打印

串口中断接收数据处理

[复制链接]
4692|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xvezhe|  楼主 | 2014-2-26 08:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xvezhe 于 2014-2-26 09:29 编辑

//串口中断
void timer1(void) interrupt 4
{        
         uchar ch;
         if(RI)
         {                 
                         ch = SBUF;                                            //接收串口数据
                        ES = 0;
                        if(State_machine==0)
                        {                                                
                                        if(ch==0x55)           State_machine=1;          //数据帧头
                                        else                 State_machine=0;
                        }
                        else if(State_machine==1)
                        {               
                                        if(ch==0xaa)           State_machine=2;  //数据帧头
                                        else                 State_machine=0;
                        }                                                               
                        else if(State_machine==2)
                        {                        
                                dat_bug [ i ] = ch;                                   //存储串口数据
                                num=dat_bug[0];         
                                i++;                                
                                if(i>=2*num+2)                 
                                {
                                        i=0;State_machine=0;
                                        read_flag=1;      //取数标志位
                                }                                       
                                                                                                                        
                    }
                    RI = 0;
                    ES = 1;
         }
}


以上的代码。若一次接收失败,则后面的接收时, read_flag就不会置1;
也就是说,接收的数据 i  不满足i>=2*num+2,  i 就不会 清0.。。。
串口接收不定长数据,怎样在其收到的数据错误的情况下,恢复接收缓冲区
相对以上代码,若接收失败,不会影响到下一次接收。。。。应如何更改,请各位指点



















相关帖子

沙发
原野之狼| | 2014-2-26 09:00 | 只看该作者
中断中收数据放入缓冲,在中断外再判断处理。

使用特权

评论回复
板凳
ayb_ice| | 2014-2-26 09:08 | 只看该作者
LS的方法是正道

使用特权

评论回复
地板
xvezhe|  楼主 | 2014-2-26 09:14 | 只看该作者
本帖最后由 xvezhe 于 2014-2-26 09:18 编辑
ayb_ice 发表于 2014-2-26 09:08
LS的方法是正道

因程序中,有几种运行模式,比如说:A中运行中断数据处理,B运行其他的模式处理;程序现在正在B模式,只有当串口接收数据成功,才切回A模式运行
所以,在串口中断中判断,若本次接收不成功,应不影响下次接收

使用特权

评论回复
5
ayb_ice| | 2014-2-26 09:31 | 只看该作者
xvezhe 发表于 2014-2-26 09:14
因程序中,有几种运行模式,比如说:A中运行中断数据处理,B运行其他的模式处理;程序现在正在B模式,只有 ...

啥这模式,那模式的,主循环应该就是不停的循环,A-B-C...>A...

使用特权

评论回复
6
xvezhe|  楼主 | 2014-2-26 09:36 | 只看该作者
ayb_ice 发表于 2014-2-26 09:31
啥这模式,那模式的,主循环应该就是不停的循环,A-B-C...>A...

有标志位才能进的、、、

使用特权

评论回复
7
ayb_ice| | 2014-2-26 09:52 | 只看该作者
xvezhe 发表于 2014-2-26 09:36
有标志位才能进的、、、

不都说了吗,改变算法吗

只要接收的数据不丢失,其它的都好办

使用特权

评论回复
8
原野之狼| | 2014-2-26 10:29 | 只看该作者
单核下,虽说只能同时做一件事,但是做完一件事还可以做另外一件事嘛,表现在:
A、简单点的,协作式任务调度。
B、复杂点的,抢占式OS机制。

使用特权

评论回复
9
52414133| | 2014-2-26 10:55 | 只看该作者
设置个标志位判断

使用特权

评论回复
10
很忙| | 2014-2-26 12:02 | 只看该作者
本帖最后由 很忙 于 2014-2-26 13:29 编辑

这样做没有什么大的问题,一般处理简单的协议是可以这样做的,我就经常这样玩。但是你写的这个判断头出问题了。
真的会出现你遇到的情况。建议这样写。
//串口中断
uchar buff=0,buff1=0;
void timer1(void) interrupt 4
{        
         uchar ch;
         if(RI)
         {               
                        RI = 0;
                        ch = SBUF;                                            //接收串口数据
                        ES = 0;
                        buff1=buff;
                        buff=ch;
                        if((buff1==0x55)&&(buff==0xaa))
                        {
                         State_machine=1;
                        }
                        if(State_machine==1)
                       {
                       dat_bug [0] =ch;
                       num=dat_bug[0];   
                       i=1;
                      State_machine=2;
                       }
                        else if(State_machine==2)
                           {                        
                           dat_bug [ i ] = ch;                                   //存储串口数据                 
                           i++;                                
                           if(i>=2*num+2)                 
                           {
                            i=0;
                            State_machine=0;
                            read_flag=1;      //取数标志位
                           }                                                                                                                                                               
                       }
                                
         }
}
这样比你的要稳健很多。
当然在你的主函数中,要判断数据的合理性。

使用特权

评论回复
11
科技猎人| | 2014-2-26 12:49 | 只看该作者
可以采用“超时断句”接收数据包,其天生就有出错后能自动恢复的功能,不会影响后面数据包得接收。具体方法看我的另一篇帖子吧(包括各楼的回复中有许多高手们的深入见解)
https://bbs.21ic.com/icview-674102-1-1.html

使用特权

评论回复
12
飞辉会i| | 2014-2-26 15:59 | 只看该作者
对,在中断外判断 处理

使用特权

评论回复
13
aouwen| | 2017-4-22 11:12 | 只看该作者
很忙 发表于 2014-2-26 12:02
这样做没有什么大的问题,一般处理简单的协议是可以这样做的,我就经常这样玩。但是你写的这个判断头出问题 ...

你好,我的usart数据接收,有时候会出问题,就是当主控发送数据过来的时候,一次发送两条,我是接收不了的,因为接收缓冲区是全局变量,第一条接收就没处理完第二条中断又来了

使用特权

评论回复
14
ningling_21| | 2017-4-22 12:37 | 只看该作者
aouwen 发表于 2017-4-22 11:12
你好,我的usart数据接收,有时候会出问题,就是当主控发送数据过来的时候,一次发送两条,我是接收不了 ...

缓冲区怎么能用全局变量,太乱来了

使用特权

评论回复
15
aouwen| | 2017-4-26 17:29 | 只看该作者
ningling_21 发表于 2017-4-22 12:37
缓冲区怎么能用全局变量,太乱来了

那用临时变量如何传到main函数中处理?

使用特权

评论回复
16
lnulibin| | 2017-4-26 21:58 | 只看该作者
原野之狼 发表于 2014-2-26 09:00
中断中收数据放入缓冲,在中断外再判断处理。

原野之狼说的是j正道.

使用特权

评论回复
17
lnulibin| | 2017-4-26 22:05 | 只看该作者
原野之狼 发表于 2014-2-26 10:29
单核下,虽说只能同时做一件事,但是做完一件事还可以做另外一件事嘛,表现在:
A、简单点的,协作式任务调 ...

嗯.就是.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

225

帖子

2

粉丝