STM32使用DMA+IDLE+环形缓冲区+双缓存池进行MODBUS串口通信
前面学到了使用串口通信,串口通信有好几种,比如普通的阻塞(测试阶段可用),然后就是中断串口(频繁打扰CPU),再然后就是DMA这个万能的搬运工,也可以使用它来进行串口通信。DMA的工作很简单,CPU发指令,发完之后只管把数据搬到外设(比如使用DMA串口给上位机发信息),或者将数据从外设搬到指定地址(使用DMA接收串口信息),DMA只管搬,搬完就发送中断请求。
然后大致讲讲这一套通信,我是感觉用在普通的MODBUS上有点大材小用了,因为没有那么多的数据量,直接使用DMA环形结构然后通过指针在DMA内存区读取数据也是可以的。总体流程就是现在CUBEMX上配置DMA,将DMA串口接收数据模式设置为Circular循环,然后打开串口的中断NVIC(因为IDLE属于串口中断,这个中断的意思就是当串口一段时间没有新的数据发送过来的时候,触发一次中断,但是这个中断没有回调函数,作为一个小众的中断,只有一个标志位),串口的好几个中断都是共享一个中断通道的(比如接收中断,发送中断,溢出中断,空闲中断),所以需要在USART1_IRQHandler里处理IDLE中断,在这里面我们需要添加一个指针,用以指示CPU取值的最新位置,这样就能够在中断触发时,将数据从环形缓冲区拷贝到双缓冲区的解析帧区域,然后设置新的指针位置,就可以退出中断了。在主函数中对数据进行解析,CRC校验,要是数据正确,就可以放入双缓冲区的执行区域,等待进行逻辑处理。
然后说说MODBUS通信,一般都是配合上485芯片进行处理的。所谓MODBUS通信,实质上就是一种通用的通信协议+标准化的使用流程,其物理层就是串口。
所谓的是通讯协议,那就是:MODBUS的数据帧是从机地址+功能码+数据+CRC16校验这种通用数据格式,其从机地址功能码之类的都有标准的数字,我们需要按照其标准进行填写。所谓的标准化使用流程就是:1.只能有MODBUS主机发启通信(启动必须是主机)2.主机发送完之后切回接收模式,允许从机发送,并且启动超时计时器(当等待响应的时间超过了,那就算无法连接到设备,发送错误码,这个超时一般设置为500ms~1000ms)3.从机接收到指令校验通过并执行之后,必须给主机回应。4.这种通信没有帧头,是通过T3.5字节判断一帧是否结束(也是一种计时,这个一般设置为3ms,与波特率相关)5.主机收到从机的回应之后,就算完成了一次完整的MODBUS通信。
对了,从机虽然要回应,但也是接收完一帧之后才判断是否回应的,不是收一个字节就回应。
说了这么多,上面的都是刚学的,没经过真正的实践。
另外附上一些查阅到的资料
为什么串口不能一对多通信?

MODBUS通信流程

从机构造回应帧

T3.5

为什么IDLE需要开串口的中断

关于485


浙公网安备 33010602011771号