xzyswr 发表于 2023-10-31 13:53:29

STM32不定长串口DMA接收+简单AT命令实现

之前在论坛搜索过相关,感觉实现太麻烦了
分享自己写的代码,程序设计思路是一切以简化为主
只需要在CubeMX里面打开串口,然后打开串口DMA,和使能中断不要忘记了


实验效果:



代码结构:





说明:
void USART_Init(UART_HandleTypeDef *huart); //用于初始化DMA接收,例如在main.c里面USART_Init(&huart2);


void Printf(const char *fmt, ...);
void Printf_DMA(const char *fmt, ...); //区别在于一个不用DMA发送一个使用,用法和printf是一样的
static void Process_AT_command(char *command); //处理命令相关,在串口接收回调 函数里使用Process_AT_command(RxBuffer);


使用方法:
1.只需要在CubeMX里面配置好串口和DMA就行,



注意勾选生成外设.c/.文件


在你的main函数里初始化USART_Init(&huart2); //使用那个串口就填那个,前提是在cubemx里面配置好了
打开sys.c文件

这里面可以找到串口接收的回调函数,在这里做你需要的处理就好了







xzyswr 发表于 2023-10-31 13:56:24

图片测试,,,,,,

eric2013 发表于 2023-10-31 16:46:32

非常感谢楼主分享。

ps:我们论坛的bug,得单独上传才行,已经帮楼主上传好。

云琴箫龙 发表于 2023-11-2 16:19:48

单纯依靠DMA+空闲中断的方式,如果对方发送的数据断断续续的时候(不是用的DMA发送),就会概率性出现丢数据的情况。
原因是你在打印或者处理数据期间,又收到了新的数据,但这里处理完数据就清空了缓存,所以后来收到的这些数据就丢失了。
弥补的方式是,进入空闲中断后,把一个计数器置位(比如10),然后每ms把这个数自减,直至减到0的时候,说明连续10ms已经没有新的数据了,就可以认为当前帧已经接收完毕。
这时候再处理数据,可以很大程度上弥补以上的问题,当然极端概率事件,比如就在10ms那个瞬间收到数据,这就是后话了。

fyyxxm 发表于 2023-11-3 14:59:17

有问题,直接DMA 循环接收就行了,不然每次还要重新打开接收。

不用DMA刻意这样搞

tdh03z 发表于 2023-11-12 11:01:10

串口接收用DMA循环方式,有新的数据丢FIFO中,都不用中断,也保证不丢数
页: [1]
查看完整版本: STM32不定长串口DMA接收+简单AT命令实现