stm32串口中断丢失数据,情况如下,请帮忙解决啊!!!
想写一个简单的串口通信程序(中断接收pc发送的数据,并随之发送给pc),大概内容如下:初始化USART1和NVIC,USART1_Config();NVIC_Config...
想写一个简单的串口通信程序(中断接收pc发送的数据,并随之发送给pc),大概内容如下:
初始化USART1和NVIC,
USART1_Config();
NVIC_Config();
中断函数如下:
void USART1_IRQHandler(void)
{
u8 i;
/*处理接收到的数据*/
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
{
i = USART_ReceiveData(USART1);
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
问题:简单的单个字节通信没有问题,但当在pc端快速发送一个字节如'1' ,那么就会出现接收到的数据量比发出去的数据量少,即有一些数据丢失了。
请问该如何解决这个问题啊????
感谢各位热心网友的积极回答,我单步调试后解决了,主要是我的USART1初始化有问题,我在初始化的时候把接收中断和发送中断都使能了,以至于在在接收中断中发送数据时出问题,接收中断和发送中断应该是同一个中断函数吧。
总之,我将初始化中的发送中断使能去了之后完全不会出现数据丢失问题,发送时间间隔在0.2ms都没有问题。 展开
初始化USART1和NVIC,
USART1_Config();
NVIC_Config();
中断函数如下:
void USART1_IRQHandler(void)
{
u8 i;
/*处理接收到的数据*/
if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
{
i = USART_ReceiveData(USART1);
USART_SendData(USART1,USART_ReceiveData(USART1));
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
{
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
问题:简单的单个字节通信没有问题,但当在pc端快速发送一个字节如'1' ,那么就会出现接收到的数据量比发出去的数据量少,即有一些数据丢失了。
请问该如何解决这个问题啊????
感谢各位热心网友的积极回答,我单步调试后解决了,主要是我的USART1初始化有问题,我在初始化的时候把接收中断和发送中断都使能了,以至于在在接收中断中发送数据时出问题,接收中断和发送中断应该是同一个中断函数吧。
总之,我将初始化中的发送中断使能去了之后完全不会出现数据丢失问题,发送时间间隔在0.2ms都没有问题。 展开
2个回答
展开全部
并不是上位机太快,而是你把程序写慢了。
两个问题:
1)接收中断函数里怎么能有发送标志位的判断?
这句去掉:while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
2)你这个串口用的方式不对,你每接收一个数据需要进一次中断,实际上应该是进一次中断把所有数据接收完毕。通过一个超时判断判断是否后续还有数据,没有数据了才退出中断函数。
两个问题:
1)接收中断函数里怎么能有发送标志位的判断?
这句去掉:while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
2)你这个串口用的方式不对,你每接收一个数据需要进一次中断,实际上应该是进一次中断把所有数据接收完毕。通过一个超时判断判断是否后续还有数据,没有数据了才退出中断函数。
追问
通过一个超时判断判断是否后续还有数据,没有数据了才退出中断函数。
这个具体该怎么设置啊?
还有(假设我还是每接收一个数据进一次中断)当把发送标志位的判断清除后,中断里调用发送函数后就不管了,因为是全双工通信的,是吗?如果是这样的话,那么当发送还没有完成时,接收中断又触发,再次调用发送函数了,那是出现什么情况?
追答
1)用一个while(timeout<=TIMEOUT)的循环做超时判断。接到数据则清零timeout,具体的TIMEOUT时间需要查看时序表,应该在1、2ms左右。
2)串口有缓冲区的,你只要发送之前判断一下发送缓冲区是否满,如果未满则将数据发送即可。(注意不是发送寄存器的状态位)。
硬件上会帮你做掉后面的事情:它会将缓冲区的值先交给发送寄存器,然后才发出去。
而你在查询的标志位如果是发送寄存器的标志位,你的时间就浪费在要等它硬件“把缓冲区的值放到发送寄存器+发送出去”这两步上面。
==============================================
你写的这段程序是不规范的。
1)0.2ms发送一个数据就是1S发送5000,如果你的波特率是9600,那你的0.2ms根本起不到任何测试作用。应该用一连串的数据通过串口工具进行发送测试。
2)数据需要加校验,“接收数据+判断数据正确性+处理数据”应该在下一次数据来之前处理完毕。
3)中断函数里一般只做接收,并不做数据处理。你把数据反着发送回去就是把处理放在了中断函数里。
展开全部
这很正常,就是中断处理时需要时间的,快发送的过程当中不一定都发送成功了,因为当串口处于中断处理状态时候是不受理新的中断的,所以无法完美解决。。。。
【对于你想解决的话,可以使用倍频时钟,加快stm32的处理速度,这样可以接受的速度就会有所提升。。。】希望采纳!
【对于你想解决的话,可以使用倍频时钟,加快stm32的处理速度,这样可以接受的速度就会有所提升。。。】希望采纳!
追问
嗯,是的,但我的已经倍频到72m了,貌似stm32最高频率是72m了。
追答
嗯!这取决于你使用的晶振,8M晶振貌似就是最高72M,但也够了。可以满足绝大多数要求的。你该进的努力应该放在其他地方,别担心你所提到的这个问题了。你可以在发送和接收信号的这方面下点功夫。。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询
广告 您可能关注的内容 |