网站首页 > 技术文章 正文
在嵌入式开发中,串口通信是产品各功能模块间信息交互的最常用手段,包括单片机与上位机的通信。STM32的串口+DMA的配合使用在做协议解析时简直不要太完美,再加上C语言结构体与指针的使用,串口通信将变得格外简单。
DMA,中文翻译即内存直接存取,而无需CPU参与。初学者习惯使用串口接收完成中断的方式来接收串口数据,对于大数据量时就显得力不从心了,而且做协议解析时将变得相当复杂。而我在项目开发中,已经将串口驱动做成了固定模块,对应于不同的外部串口设备,直接重新封装调用即可。下面来分析一下串口DMA的具体实践。
我这里就以STM32F103ZET6这款芯片的USART2为例来进行说明,编译器使用keil5。这款芯片有两个DMA控制器,查阅芯片开发手册可知,USART2_TX和USART2_RX均是挂在DMA1控制器上,分别使用其通道7和通道6。由下图可以看出:
在初始化USART2外设之前,我们先整理一下思路。首先,需要明确我们需要实现的功能:1.串口+DMA 发送数据包 2.串口+DMA接收数据包 3.发送完成和接收完成状态判断。然后需要注意的就是选择合适的中断方式来接收数据。我这里使用的是串口空闲中断的方式来接收数据,可能对于某些要求比较苛刻的场合不太适用,比如数据量特别大并且需要容忍数据包断帧的异常的情况,但对于一般场合完全可以满足要求,而且在不是特别苛刻的情况下也可以通过补充协议规范,解码错误要求重传等方法来尽量避免上述问题。
这样,我们先定义一个结构体,其成员变量包含接收和发送缓存,接收和发送数据量大小,接收和发送完成标志。如下图所示:
然后进行相关的初始化,注意,下面代码中我对USART2端口做了重映射:
可以清晰的看出,我们只需将对应的缓存地址赋值给DMA_InitStructure.DMA_MemoryBaseAddr变量,设置好DMA_InitStructure.DMA_BufferSize为我们开的缓存大小即可。
DMA_InitStructure结构体中其他的成员变量应该很容易理解,这里不再讲解。然后我们就可以实现串口发送数据包函数,如下图:
备注很详细,应当不难理解,这里带有两个参数,一个是发送缓冲区地址,一个是发送的字节数。如果我们想实现类似与printf()这样的函数来发送字符串,可以将上面的代码稍作修改,如下图:
发送函数比较简单,接下来我们就要去处理串口中断来接收数据了,在串口中断中只需判断是否是串口空闲中断标志置位,是则先清除中断标志,其实就是要接收一次串口数据便会自动清除标志。然后关闭DMA对应通道,计算并获得DMA接收到的数据包大小(也就是用我们设置的缓冲区大小减去剩余的数据量),再重新设置DMA接收缓冲大小,再使能DMA相应通道,最后置位接收完成标志即可。具体实现如下图所示:
好了,到这里,基本上就大功告成了。我们只需要在主函数中不断的去判断接收完成标志是否置位,如果被置位就可以去解析UsartDataHandle2.RxBuf中的数据了,然后实现相应功能,但是不要忘记将接收完成标志重新复位,以为下一次的通信做准备。
以上代码完全可以封装成一个固定模块,当我们实际项目中应用时可以进行再次封装调用,这里暂且不提,下一期再以实际应用来详述!
猜你喜欢
- 2024-10-12 STM32单片机-多串口printf()问题与ASCII码解析
- 2024-10-12 stm32F0 串口的几个特殊功能 stm32f1串口引脚
- 2024-10-12 STM32串口发送用哪个中断? stm32f4串口发送数据
- 2024-10-12 STM32F103编程学习——USB虚拟串口篇
- 2024-10-12 STM32F4入坑日记——串口发送数据(非中断)
- 2024-10-12 STM32 HAL库串口中断发送过程 stm32f4串口中断
- 2024-10-12 在货物监控设备研发时,STM32串口第一个字节丢失解怎么解决?
- 2024-10-12 STM32单片机采用环形缓冲区实现串口中断数据接收管理
- 2024-10-12 STM32下载程序新思路--使用串口下载STM32程序
- 2024-10-12 STM32F103编程学习——串口接收不定长数据
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)