现在手上有一个串口模块要开发,比较复杂, 功能:接收各种类型不定长度的 字符串,然后解析做出反馈 字符串基本规格: 单条命令 : CMD(X,Y,'ABC或者中文字符不定长',W); 结束符号: \r\n 最终串口接收字符串是: 命令+结束符 ======》 CMD(X,Y,'ABC或者中文字符不定长',W); \r\n 特殊情况1: 有时是几条命令一起过来, 如: CMD(X,Y,'aaaa',W);CMD(X,Y,'bbb',W);CMD(X,Y,'啊啊啊啊',W); \r\n 特殊情况2: 发送端是不定时发送,可能突然发送连续两条 CMD(X,Y,'1111',W); \r\n CMD(X,Y,'22222',W);\r\n 问题: 对于以上两种特殊情况, 1. 请问串口设置为中断模式 接收数据 可行么? 2. 串口中断的条件是什么? 比如一条 CMD(X,Y,'ggg',W); \r\n ,串口是收到 “C” 第一字符之后 就中断吗? 还是整句接收完才中断? 3. 中断后,串口还接收数据吗? 比如CMD(X,Y,'ggg',W); \r\n 发送过来,正在中断里面接收数据,此时又来一条,那么串口会不会继续接数据进来? 4. 接收数据时 是在串口中断中边接收 边解析好呢? 还是直接读空串口, 存在buffer, 到主程序 外面进行解析 好呢? 5. 是否需要 用DMA 方式进行接收? 6. 接收到数据之后,主程序 需要进行反馈(可能包括一些IO 操作,读取flash 等等),如果在此期间,串口又来数据了,但是不想被接收动作打断同时又能把数据 接过来,等这些反馈动作完成后, 再去分析这些数据(不错过它) 可能吗?如何实现? |
1,不考虑头尾只要来数据都接收存储,然后在慢慢分析接收到的数据。这种接收方式的话不用判断数据,用时间卡,比较只要串口中断进来就接收数据,并且开始计时,如果在指定时间内比如10ms内有数据进来,就计数器清零。如果计时器的值超过10ms,则认为本次串口接收数据结束。然后统一区分析处理接收到的数据。
2,根据协议通过头尾接收数据,如果接收到C则标记准备接收数据,并且开始计数接收到1个字节,然后依次判断第2个字节是M,第3个字节是D,如果前三个字符是CMD则开始正式接收数据,将接收到的数据存储起来,如果接收到了\r 则标记准备结束,如果接收到\n则标记结束完成。本次数据存储结束,清空所有标志位。然后置接收结束标志位,主程序判断接收结束后就去处理本次接收到的数据,然后中断中继续接收下一组数据。
2.串口中断是每接收到一个字节进入中断处理。
3.中断处理的过程,串口还继续工作,但最好在中断中只接收保存数据,处理数据放在主函数执行。
4.同上。
5.DMA也是可以的,注意别溢出了。及时处理。
6.肯定可以的。如果只是IO操作,完全可以串口中断接收数据啊,反正影响不大。如果这个期间不能被打断,那就只能用DMA收数据了。把收到的但未来得及处理的命令保存下来,有空了就慢慢执行回复吧。
评分
查看全部评分
比如:
https://www.stmcu.org.cn/module/ ... D%E5%AE%9A%E9%95%BF
谢谢你的回复。
你说的第1种方法,定时有点像 使用DMA , 定义一个buffer ,然后轮询去检测buffer 里面有没有数据。取出来进行解析,这个能否避免命令 “断节” 的问题呢? 比如再取buffer的时候,突然进来了下一个命令的 前半部分数据, 尤其是发送端是突然不定时的发送数据。
至于第2种方法 是否就是 写一个状态机 之类的东西,然后再串口中断函数中去判断 接收的数据,但是这样如果数据中间一个byte 不对了, 整个命令就不对了, 丢包现象不知道会不会 很严重?
关于5,
你说 注意别溢出, 但是发送端 是不定时突发性发送的, 这边不能控制其发送的速度 和数据量,
如果溢出了,如何处理? DMA 可以设一个上限 过了 就停止串口接收 , 设一个下限低了继续接收 这样可行吗?
关于6, 除了IO 操作 ,还有一些SPI flash 的读写, LCD 屏控制, 时间上可能需要一些时间。
所以只能用 DMA 读数据,DMA 读的话是不是也是放在一个buffer, 这个buffer 空不空, 存量什么 硬件有标志位吗? 还是应用层的一个数组 而已?
谢谢你, 这个帖子我看过, 但是 定时轮询的方法 对于发送端不定时突发性的 特点 , 是否适合呢?
ST 的 DMA 硬件标志位上有没有 关于缓存区 是否有数据,能否设上下限的 功能?
每次断帧中断,一定能接收到整帧数据,应该不难进行数据处理的。
可以利用DMA传数据到一个环形数组作缓冲,循环填充数据,有数据及时处理,数据处理延迟的最长时间内串口可能会收到多少数据,然后定义稍微大一点的数组即可。
举例:比如你最长10ms才处理收到的数据,如果你的波特率是115200,那么10ms内最多会收到100+个数据,你把DMA数组设置为200就不怕溢出了。