zjipc 发表于 2016-3-13 22:44:42

使用K60串口接收字符串问题

用单片机K60的串口和上位机完成通信,需要接收上位机的数据,是字符串,长度未知,数据开始为0xaa,结尾是中间数据的和,作为校验值,查了一些文档,串口接收数据的中断只能一个字节一个字节接收,有没办法一次串口中断吧数据都接收进来,这样就可以避免频繁的进入串口接收中断,初学K60,请各位赐教一下!

zjipc 发表于 2016-3-14 10:32:41

可以一次性接收多个字节的数据吗,而不是一个字节进一次中断

ccq101 发表于 2016-3-14 11:47:16

没用过K60,不过单片机都是一个字节一个字节的接收,如果你不想频繁中断 可以试试DMA模式
或者使用接收超时,接收一个字节后,如果超过2~3个波特率间隔没有收到新的字节 就可以决定 这个数据包已经传输完毕了。
或者使用环形队列,串口中断只负责放数据进去缓冲区。然后在主函数或者定时器判断缓冲区是否有数据,且处理。

zjipc 发表于 2016-3-14 12:18:48

号的,谢谢,我试一下DMA

snail_dongbin 发表于 2016-3-14 12:27:21

首先你要弄明白一个问题,串口是一个一个接,无论什么单片机 什么pc 都是一样的,只不过人家封装的好,协议上不占用太多时间而且
就算接收过程中被其他高优先打断,接收数据被临时放入fifo,一般单片机也只有4级左右,再多就要串口溢出报警了。

你所做的工作就是串口来一个缓存进一个buffer 直到接收结束,然后处理。
开始有“0xaa”,这是一个很好的标志,可以用来清空buffer和重置计数。没有结束位也没关系,只要开一个定时器判断多长时间后没有数据过来
比如波特率9600 。一个字符大约2ms 那么你等5ms还是没有数据过来就认为接收完成了,然后出来处理字符串,否则的话清空定时器值。

一切都在中断当中完成,用不了多长时间。
主程序该干嘛干嘛

zjipc 发表于 2016-3-14 21:46:04

snail_dongbin 发表于 2016-3-14 12:27
首先你要弄明白一个问题,串口是一个一个接,无论什么单片机 什么pc 都是一样的,只不过人家封装的好,协议 ...

我处理程序也是放在其他中断里,对时间的要求比较高,我是怕频繁串口中断影响了其他中断服务程序,上一次,我串口发送数据放在中断里,波特率设成9600,其他程序就不能正常的执行了,后来改成115200,其他程序就能正常执行

snail_dongbin 发表于 2016-3-16 19:06:17

zjipc 发表于 2016-3-14 21:46
我处理程序也是放在其他中断里,对时间的要求比较高,我是怕频繁串口中断影响了其他中断服务程序,上一次 ...

发送放中断里还9600 ,不等才怪

串口发送一般可以用发送中断,高级点的可以用dma
波特率我一般都是115200 结尾用校验码。从没出过问题

1328616904 发表于 2016-3-20 19:32:17

FIFO或DMA

zjipc 发表于 2016-4-6 21:44:48

snail_dongbin 发表于 2016-3-16 19:06
发送放中断里还9600 ,不等才怪

串口发送一般可以用发送中断,高级点的可以用dma


这几天一直在研究这个问题,用DMA接收数据,由于数据长度是变化的,不知道怎么解决,如果用用UART中断接收数据,又出来问题是数据每次接收不完全,因为中断不能嵌套,1、如果中断设置嵌套该怎么设置,数据手册里面没有讲到;2、如果用DMA数据不定长怎么办,因为是K60的芯片,网上都找不到例子

落叶知秋 发表于 2016-4-8 15:23:19

zjipc 发表于 2016-4-6 21:44
这几天一直在研究这个问题,用DMA接收数据,由于数据长度是变化的,不知道怎么解决,如果用用UART中断接 ...

最近工作在用K6X系列的芯片,也用到了UART和DMA,看到楼主的目的有点描述不清楚,
所以进行以下猜测:
1. 上位机和K60通过UART进行通信,因为其中有涉及到通信协议,数据长度不定,又不想在UART中断里接收;
2. 楼主尝试了DMA接收,但是又在数据长度不定这里卡住了,不知道怎么办?

如果猜测没错的话,给楼主建议:
1. 使用DMA是对的;
2. DMA搬运是支持地址偏移的;
3. 开辟RAM缓冲区接收UART数据;
4. 通信协议规定单包数据最大长度;
5. 为了防止上位机玩命往K60发数据,应该在协议中规定单个命令包的应答机制;
6. K60以查询方式处理RAM接收缓冲区里的数据,合法数据包则返回应答;
7. 如果要求上位机玩命往K60发数据,则可以考虑建立乒乓缓冲区,DMA收满一个缓冲区,就往另外一个搬,K60处理速度肯定比通信速率快。

zjipc 发表于 2016-4-12 15:35:51

落叶知秋 发表于 2016-4-8 15:23
最近工作在用K6X系列的芯片,也用到了UART和DMA,看到楼主的目的有点描述不清楚,
所以进行以下猜测:
1. ...

非常感谢您,这么认真的分析以及给与合理的建议,上位机我用的是网上的,上位机发送的数据包长度我不能修改,比如数据包发送来AAAF02(n字节),我可以通过AAAF02这6个字节指令语句来判断这个数据包的长度,我如果用DMA先接收6个字节,然后根据这6个字节判断后面n是多大,然后从新初始化DMA接收N字节,不知道会不会导致串口数据丢失的。

落叶知秋 发表于 2016-4-12 17:56:50

zjipc 发表于 2016-4-12 15:35
非常感谢您,这么认真的分析以及给与合理的建议,上位机我用的是网上的,上位机发送的数据包长度我不能修 ...

楼主考虑的这种做法也不是不可以,只要你查询和处理DMA状态的速度比UART的发送速率块,不导致数据到了没人管就行了。
另外,也可以考虑我上面提及的【乒乓缓冲】的方法。即:
1. 开辟2块内存缓冲区A和B;
2. 让DMA将收到的UART数据先存到A;
3. 主程序可以查询DMA已经搬运了多少,如果够6个字节,就开始解析;
4. 等到DMA收完解析出来的长度后,就进行n个字节的读取解析;
5. DMA把A区填满了,就指定DMA开始把B区开始“填埋”;
6. 主程序处理完A区,跟着处理B区;
7. 然后就是A->B->A->B……这样了。

落叶知秋 发表于 2016-4-12 17:59:57

zjipc 发表于 2016-4-12 15:35
非常感谢您,这么认真的分析以及给与合理的建议,上位机我用的是网上的,上位机发送的数据包长度我不能修 ...

其实只要遵循一个原则就行了:数据到了就尽快取走存起来,免得丢了,然后再根据协议做出处理,处理完的数据就丢掉。

FSL_FAE_JiCheng 发表于 2016-4-12 21:41:34

推荐你一个好的解决办法,确定好最大可能发送的串口字节数并将其赋给DMA buffer长度,然后利用UART的IDLE Line功能可以实现一帧数据发送完成之后自动插入一个空闲中断,在该中断里把buffer里的一帧数据读出来处理即可,具体操作可以参考我的一篇文章http://blog.chinaaet.com/jihceng0622/p/40378

zjipc 发表于 2016-4-19 10:30:14

落叶知秋 发表于 2016-4-12 17:56
楼主考虑的这种做法也不是不可以,只要你查询和处理DMA状态的速度比UART的发送速率块,不导致数据到了没 ...

我明白这个意思了,DMA初始化接收长度,我可以确定的大一点,然后一边接收我一遍处理,谢谢您无私的讲解,我想能搞定了

zjipc 发表于 2016-4-19 10:33:02

FSL_FAE_JiCheng 发表于 2016-4-12 21:41
推荐你一个好的解决办法,确定好最大可能发送的串口字节数并将其赋给DMA buffer长度,然后利用UART的IDLE L ...

谢谢您的分享,我去研究一下,{:loveliness:}

tim4146 发表于 2016-6-25 17:17:09

不知道楼主最后这么解决的,也没个说法啊{:lol:}
我觉得14楼的办法是非常不错的,我们公司也是用的类似办法,UART+DMA+空闲中断的办法,因为数据传送完一帧之后总会空闲一段时间再来第二帧的,设置一下空闲时间多长产生中断就行了。

ccitlad 发表于 2016-8-8 15:25:28

k60 绝大多是uart的fifo只有一个字节,好像有2个串口具有fifo功能
页: [1]
查看完整版本: 使用K60串口接收字符串问题