STM32CubeMX开发,解决串口DMA接受第一次接收不到数据

本次生成的串口:

使用芯片:STM32F215ZE

    端口:USART3

波特率:115200

数据位:8位

校验    :无校验

 

第一次使用STM32CubeMX开发,本人觉得HAL库还是有些问题,本次开发搞那个串口就使用了我好多时间

本次遇到的问题:

 1.串口使用CubeMX生成的工程有点问题,串口接受与发送有个互锁的问题,具体请看链接

使用链接的解决方法还是无法解决,15个数据1MS周期发送还是出现死机现象

2.上面的方法不能解决,然后我想到了串口使用DMA接受与发送空闲中断,加快接受发送速度,全都是硬件自动完成具体生成过程请看链接STM32—cubeMX+DMA+USART 接收任意长度的数据

使用cubeMX+DMA+USART后,再也没有出现死机卡死的问题,但是第一次发送数据后无法产生空闲中断(这是我调试跟踪验证的),那这就意味这第一次数据是无法收到,我尝试过初始化是清除所有的标志,和发送数据清除标志位,但还是无法解决第一次无法收到数据问题

解决方法

上面的问题困扰我蛮久的,最后我想到了了一个跳过开机第一次接收数据的空闲中断,方法也不难,就是开机时不使用空闲中断,接收的第一个数据是普通的中断,到第一个数据接收完成后,在回调函数里开启DMA空闲中断,这样就跳过开机第一次数据无空闲中断问题,下面我会贴一下我改的一些代码

 

放在main(void)初始化里

  /* USER CODE BEGIN 2 */
	
//   __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);/*开启串口空闲中断*/
//  HAL_UART_Receive_DMA(&huart3, Rx_tempBuff,BufferMax);//打开DMA接收,数据存入Rx_tempBuff数组中。

	HAL_UART_Receive_IT(&huart3,&FirstRBuffer,1);  //不开空闲中断,第一次接收数据	
  Usart3_Dat.Penetrate = 1; //透传模式 1 ; 命令提取模式 0

  /* USER CODE END 2 */

stm32f2xx_it.c的中断函数

void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */
  /* USER CODE END USART3_IRQn 0 */
  HAL_UART_IRQHandler(&huart3);
  /* USER CODE BEGIN USART3_IRQn 1 */
    uint32_t temp;
	  u16 Ai = 0;

    if((__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)) != RESET)//获取IDLE标志位,检查idle标志是否被置位
    { 
        __HAL_UART_CLEAR_IDLEFLAG(&huart3);//清除标志位
        temp = huart3.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
        temp = huart3.Instance->DR; //读取数据寄存器中的数据
        HAL_UART_DMAStop(&huart3); //
        temp  = hdma_usart3_rx.Instance->NDTR;// 获取DMA中未传输的数据个数,NDTR寄存器分析见下面
        temp =  BufferMax - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
			  for(Ai = 0; Ai <temp ;Ai++)
		   	{
			    RingBuffWrite ( &Usart3_Dat,  (u16)Rx_tempBuff[Ai]);				
				}
         HAL_UART_Receive_DMA(&huart3,  Rx_tempBuff,BufferMax);//打开DMA接收,数据存入rx_buffer数组中。(数组重新复位)
        
			}
  /* USER CODE END USART3_IRQn 1 */
}

修改一下串口的回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    UNUSED(huart);
    //	HAL_UART_Transmit(&huart3,(uint8_t*)RBuffer,1,0xFF);//(uint8_t*)aRxBuffer为字符串地址,10为字符串长度,0xFFFF为超时时间
    //=====================
    if(huart->Instance == USART3)
    {
        if(FirstDMA == 0)   //第一次回调,转为DMA接收
        {
            FirstDMA ++;
            RingBuffWrite ( &Usart3_Dat,  (u16)FirstRBuffer);	  //接收数据,缓存到数组里
            __HAL_UART_CLEAR_IDLEFLAG(&huart3);         //清除标志位
            __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);//使能idle中断
            HAL_UART_Receive_DMA(&huart3, Rx_tempBuff, BufferMax); //打开DMA接收,数据存入rx_buffer数组中。
        }
    }

}

 

就写到这了,如有不足请指出

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值