OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1835|回复: 4

求助STM32F07ZGT6SPI3使用DMA发送时 一直卡在 while (!DMA_GetFlagStatus(DMA1_S...

[复制链接]

7

主题

13

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2023-10-24
在线时间
6 小时
发表于 2023-10-24 16:13:05 | 显示全部楼层 |阅读模式
void RGB_Init(void)
{
    RGB_GPIO_Init();
    RGB_Driver_Init();
}
static void RGB_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_AHB1PeriphClockCmd(Colorful_RCC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = Colorful_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
                GPIO_InitStructure.GPIO_OType =GPIO_OType_PP;
                GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(Colorful_PORT, &GPIO_InitStructure);
                GPIO_PinAFConfig(Colorful_PORT,  GPIO_PinSource5, GPIO_AF_SPI3 );
    GPIO_ResetBits(Colorful_PORT, Colorful_PIN);
}
static void RGB_Driver_Init(void)
{
#if RGB_DRV_SPI
    RGB_Spi_Init();
#else
    RGB_Timer_Pwm_Init();
#endif
    RGB_DMA_Init();
}

static void RGB_Spi_Init(void)
{
    SPI_InitTypeDef SPIInitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
    SPIInitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
    SPIInitStructure.SPI_Mode = SPI_Mode_Master;
    SPIInitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPIInitStructure.SPI_CPOL = SPI_CPOL_Low;
    SPIInitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPIInitStructure.SPI_NSS = SPI_NSS_Soft;
    SPIInitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
    SPIInitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPIInitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(SPI3, &SPIInitStructure);
    SPI_Cmd(SPI3, ENABLE);
    SPI_CalculateCRC(SPI3, DISABLE);
    SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE);
}

static void RGB_DMA_Init(void)
{
    DMA_InitTypeDef DMA_InitStructure;
                RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1,ENABLE);

    DMA_DeInit(DMA1_Stream5);
                DMA_InitStructure.DMA_Channel=DMA_Channel_0;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&SPI3->DR);           // 外设地址: SPIx  DR
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RGB_Byte_Buffer;           // 待发送数据的地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;                          // 传送方向,从内存到寄存器
    DMA_InitStructure.DMA_BufferSize = 0;                                       // 发送的数据长度,初始化可设置为0,发送时修改
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;            // 外设地址不增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     // 内存地址自动增加1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;     // 外设数据宽度
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;             // 内存数据宽度
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                               // 发送模式,只发一次
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;                         // DMA传送优先级为高
    DMA_Init(DMA1_Stream5, &DMA_InitStructure);
                DMA_Cmd(DMA1_Stream5, DISABLE);
}
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

12

主题

3370

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8581
金钱
8581
注册时间
2020-5-11
在线时间
3998 小时
发表于 2023-10-25 09:32:24 | 显示全部楼层
你发的代码里就没有while
专治疑难杂症
回复 支持 反对

使用道具 举报

7

主题

13

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2023-10-24
在线时间
6 小时
 楼主| 发表于 2023-10-25 11:40:34 | 显示全部楼层
LcwSwust 发表于 2023-10-25 09:32
你发的代码里就没有while

不好意思只放了初始话代码
下面是是是函数掉用代码
void RGB_Update(void)
{
    uint8_t i, j;
    for (j = 0; j < MAX_RGB; j++)
    {
        for (i = 0; i < BIT_LEN; i++)
        {
            RGB_Byte_Buffer[i + j * 24 + 1] = ((led_buf[j] >> (23 - i)) & 0x01) ? TIMING_ONE : TIMING_ZERO;
        }
    }
#if RGB_DRV_SPI

                DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5);
                DMA_Cmd(DMA1_Stream5, DISABLE);
    DMA_SetCurrDataCounter(DMA1_Stream5, BUFF_SIZE); // 更新传输的数据量
    DMA_Cmd(DMA1_Stream5, ENABLE);                   // 使能DMA通道,开始传输数据

  while (!DMA_GetFlagStatus(DMA1_Stream5,DMA_FLAG_TCIF5))         // 等待传输完成
        ;
    DMA_Cmd(DMA1_Stream5, DISABLE); // 关闭DMA通道
    DMA_ClearFlag(DMA1_Stream5,DMA_FLAG_TCIF5);    // 清除DMA通道状态
#else
    DMA_SetCurrDataCounter(DMA1_Channel5, BUFF_SIZE); // 更新传输的数据量
    DMA_Cmd(DMA1_Channel5, ENABLE);                   // 使能DMA通道5,开始传输数据
    TIM_Cmd(TIM1, ENABLE);                            // 使能定时器1
    while (!DMA_GetFlagStatus(DMA1_FLAG_TC5))         // 等待传输完成
        ;
    TIM_Cmd(TIM1, DISABLE); // 关闭定时器1,并清除定时器参数
    TIM1->CCR1 = 0;
    TIM1->CNT = 0;
    TIM1->SR = 0;
    DMA_Cmd(DMA1_Channel5, DISABLE); // 关闭DMA通道5
    DMA_ClearFlag(DMA1_FLAG_TC5);    // 清除DMA通道状态
#endif
}
回复 支持 反对

使用道具 举报

12

主题

3370

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8581
金钱
8581
注册时间
2020-5-11
在线时间
3998 小时
发表于 2023-10-25 12:12:11 | 显示全部楼层
Pretenderlk 发表于 2023-10-25 11:40
不好意思只放了初始话代码
下面是是是函数掉用代码
void RGB_Update(void)

没发现问题。想问下你是否在调用RGB_Update()之前未初始化DMA、SPI?
SPI在不用DMA的情况下是否能正常发送?
专治疑难杂症
回复 支持 反对

使用道具 举报

7

主题

13

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2023-10-24
在线时间
6 小时
 楼主| 发表于 2023-10-25 14:50:49 | 显示全部楼层
LcwSwust 发表于 2023-10-25 12:12
没发现问题。想问下你是否在调用RGB_Update()之前未初始化DMA、SPI?
SPI在不用DMA的情况下是否能正常发 ...

SPI和DMA初始化应该是正常的,没有尝试不用DMA SPI发送数据
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-4-7 12:20

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表