完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1.设定好通讯协议,如包头+长度+数据+校验+包尾,那么中断中每收到一个字节就判断,直到收到包尾为止。这是51时代用得比较多的状态机接收流程。
但如果由于接收中断被嵌套,或干扰等原因导致一帧数据的后部分丢失,就是说接收不到包尾,那么这个状态机如何能自动复位以便接收下一帧? 2.串口空闲中断也是用得比较多的一种方法,但是波特率较高的时候,空闲中断的触发时间相应变短,使得接收中断不被打断的要求变高,如果接收中断被耽误了,从而触发空闲中断,也是收不到完整数据。 3.定时器中断代替串口空闲中断,这个可以避免串口空闲中断时间不够的问题,因为这个定时器中断可以自己设置。但是一个串口需要搭配一个定时器使用,不爽。 4.串口接收只把数据放到缓存,此外不做任何事情。然后在另一个线程不断parse这个缓存,从头开始找其中有没有符合一帧的数据,如果有就是解析,同时将这一帧从缓存中删掉,如果没有就什么也不做。这样的程序就不用管一帧是否结束,可以较好的适应各种收不全、丢数据的问题。 问题是,这个思路我在PC上位机中用过没问题,但是在STM32要是我定义的缓存是一个固定大小字节数组,当我解析到了一帧数据后,如何这帧数据从缓存中去掉,即如何做一个动态数组的结构之类的? 大家有没有什么好的办法分享? |
|
相关推荐
8个回答
|
|
|
|
|
|
楼上,肯定是固定几十MS没收到下一个数据就判定接收完成啦,不过这种方法比较多个定时器中断而且比较频繁。
|
|
|
|
动态数组结构用链表就可以了!查找,删除和插入都比较方便。
|
|
|
|
|
|
|
|
楼上正解
随便说一下,例程里的uart3.c里就用到字节间超时处理 void USART3_IRQHandler(void) { u8 res; OSIntEnter(); if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//½ÓÊÕµ½Êý¾Ý { res=USART_ReceiveData(USART3); if((USART3_RX_STA&(1<<15))==0)//½ÓÊÕÍêµÄÒ»ÅúÊý¾Ý,»¹Ã»Óб»´¦Àí,Ôò²»ÔÙ½ÓÊÕÆäËûÊý¾Ý { if(USART3_RX_STA TIM_SetCounter(TIM7,0);//¼ÆÊýÆ÷Çå¿Õ if(USART3_RX_STA==0) //ʹÄܶ¨Ê±Æ÷7µÄÖÐ¶Ï { TIM_Cmd(TIM7,ENABLE);//ʹÄܶ¨Ê±Æ÷7 } USART3_RX_BUF[USART3_RX_STA++]=res; //¼Ç¼½ÓÊÕµ½µÄÖµ }else { USART3_RX_STA|=1<<15; //Ç¿ÖƱê¼Ç½ÓÊÕÍê³É } } } OSIntExit(); } |
|
|
|
消息队列吧
|
|
|
|
你应该学习下modbus,疑虑就没了。
|
|
|
|
用链表哦
|
|
|
|
只有小组成员才能发言,加入小组>>
866 浏览 0 评论
1191 浏览 1 评论
2566 浏览 5 评论
2901 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2762 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1207浏览 3评论
214浏览 2评论
487浏览 2评论
399浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
482浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-24 13:49 , Processed in 1.167130 second(s), Total 61, Slave 52 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号