STM32 hal库解决串口+DMA接收数据

   日期:2021-02-28     浏览:245    评论:0    
核心提示:STM32F407串口空闲中断+DMA 接收,应用于大疆DT7无线遥控#stm32CubeIDE STM32F4 HAL库 大疆DT7 串口+DMA ()1.硬件设计首先了解大疆接收器发送串口数据的信号类型如图可知,需要做一个取反电路…如下图:图片取自网上.这些在网上都可以搜到. 记住要有上拉电阻,如果外部没有,可使用单片机USART的RX的GPIO配置为上拉遥控接收后会发送,相当于外部串口的TX,与单片机的RX连接.接下来就是软件部分,我使用的是STM32CubeIDE,先配

STM32F407串口空闲中断+DMA 接收,应用于大疆DT7无线遥控

#stm32CubeIDE STM32F4 HAL库 大疆DT7 串口+DMA ()

1.硬件设计
首先了解大疆接收器发送串口数据的信号类型
如图可知,需要做一个取反电路…如下图:

图片取自网上.这些在网上都可以搜到. 记住要有上拉电阻,如果外部没有,可使用单片机USART的RX的GPIO配置为上拉
遥控接收后会发送,相当于外部串口的TX,与单片机的RX连接.

接下来就是软件部分,我使用的是STM32CubeIDE,先配置环境
1.配置RCC时钟,这个就不多说了,不会的话评论区和我说
2.
配置串口数据
配置串口DMA接收

GPIO模式配置
最后,使能串口接收中断

我使用了10ms定时器中断 在定时器中来处理数据,不在中断中处理.中断仅用来接收数据.定时器配置我也不多说了


补充一张图,.
下面上代码

int main(void)
{
  

  

  

  
  HAL_Init();

  

  

  
  SystemClock_Config();

  

  

  
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); //使能串口空闲中断
  HAL_UART_Receive_DMA(&huart1, receive_buff,18);//开启串口DMA接收
  HAL_TIM_Base_Start_IT(&htim2);//开启1定时器中断
  

uint8_t receive_buff[18];这是定义的接收数组
receive_buff为接收数组,接收到的数据放在这里,18代表一次接收18字节.
接下来找到stm32f4xx_it.c文件

 * @brief This function handles USART1 global interrupt.
  */
void USART1_IRQHandler(void)
{
  

  
  HAL_UART_IRQHandler(&huart1);  //这个可有可无
  
  if(USART1==huart1.Instance)  //判断是否为串口1的中断
  {
  if( __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)!=RESET )                /判断是否为空闲中断
  			   {
  				__HAL_UART_CLEAR_IDLEFLAG(&huart1);        //  如果是空闲中断清除空闲中断标志
  				HAL_UART_DMAStop(&huart1);                 // 关闭串口的DMA接收
  				DMA2_Stream2->NDTR=(uint16_t)(RC_FRAME_LENGTH);  //  这个参考的大疆DT7历程,重置DMA存储指针到起始位置
  				HAL_UART_Receive_DMA(&huart1, (uint8_t*) receive_buff, 18); //再开启接收
  				HAL_Delay(25);    //为什么加延时呢,见后面
              if(__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)==0&&receive_buff[17]==4)  // 见后面
                {
                memcpy(data_Handle, receive_buff, 18);      //复制到其他数组方便处理
      
                }
  			   }
  }
  
}
/**

讲解一下, __HAL_DMA_GET_COUNTER(&hdma_usart1_rx)这句话的意思是当前DMA流传输中剩余数据单元的数量,也就是说开启接收后,需要等接收完成才可以去处理数据,即__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)这个等于零,代表18个字节都接收完成.
可以看一下HAL库中这个宏定义 #define __HAL_DMA_GET_COUNTER(HANDLE) ((HANDLE)->Instance->NDTR)
再看一下ST文档NDTR寄存器含义

所以我在HAL_UART_Receive_DMA(&huart1, (uint8_t*) receive_buff, 18); 开启接收后需要等待20m’接收完成才可以进行这个判断,否则在调试时设置断点会不进入这个if.因为还有剩余,就不会等于0.
关于&&receive_buff[17]==4,是应为我根接收数据的特点,自己增加的一个判断条件,提高数据正确性.
说白了这句话就是一个接收数据的长度校验 又加上了一个我自己找的数据的一个特点,才能保证数据的正确性,当发生数据乱的状况会过滤掉
if(__HAL_DMA_GET_COUNTER(&hdma_usart1_rx)==0&&receive_buff[17]==4)
好的,就这么多了,第一次写文章,欢迎广大网友批评指责,看看这个还有什么可提升的地方,互相学习,加油!

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服