打印

串口奇校验问题

[复制链接]
3465|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lostzay|  楼主 | 2011-12-26 12:14 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lostzay 于 2011-12-26 20:47 编辑

写了个串口奇校验的程序,失败,逐步检查错误,

在检查到位运算的时候,发现有问题了~~
按照程序的思路,我发3E,应该返回01 02 03 04 05
但是实际:
发3E,没返回。
发E3,返回01 02 03
发EE,返回01 02 03
void uart_interrupt(void) interrupt 4//串口中断函数
{
        uint comm_inbuf_temp;
        uchar count;
        uint check_flag=0;                                          //校验标志
        uint m=0x80;
        
        if(RI)// RI=1表示cpu收取数据完毕
        {
                RI=0;  //复位
               
                comm_inbuf_temp=SBUF;
               
               
               

                for(count=0;count<8;count++)           //8位数据检验
                {
                        if(comm_inbuf_temp & m)                           //从最左边1位开始计算是否为1
                        {         
                                check_flag++;                           //如果是1,校验标志+1
                                comm_inbuf_temp = comm_inbuf_temp << 1 ;
                                //m=m>>1;        
                                                                   //m右移1位
                                ES=0;
                                SBUF=check_flag;
                                while(!TI);
                                TI=0;
                                ES=1;
                        }
                                
                }

                /*if((check_flag%2)^RB8)                           //校验标志是否和RB8一致,不一致则说明数据被正确接收
                {
                        comm_inbuf=comm_inbuf_temp;   //将串口数据送入comm_inbuf数组
                          send_char_comm(0);
                        //comm_judge();  //判断接收数据是否正确        
                }  */
         
           
               
                        

        }
        else
                TI=0;
               
                  
}

相关帖子

沙发
wukunshan| | 2011-12-26 14:34 | 只看该作者
串口中断函数里代码太长、太耗时,又for循环又调用函数的。造成单片机不能及时接受数据。如果非要那么长得代码,那就得延长上位机每发送一个数据(一个字节)的时间间隔。

使用特权

评论回复
板凳
ledyd| | 2011-12-26 14:44 | 只看该作者
这种情况,我之前也见到过,一直未找到解决的办法

使用特权

评论回复
地板
ayb_ice| | 2011-12-26 14:53 | 只看该作者
1: 修改协议,检验打包的数据
2: 用ASM
3: 混合编程

使用特权

评论回复
5
lostzay|  楼主 | 2011-12-26 15:27 | 只看该作者
谢谢楼上几位

我自己找到问题所在了~~

我在***论坛里也提问了,那里比我自己早找到~~错误~


在for循环里,当最高位不为1,comm_inbuf_temp 没移位

comm_inbuf_temp = comm_inbuf_temp << 1 ;
放到if外面

使用特权

评论回复
6
Wayner| | 2011-12-26 16:35 | 只看该作者
LS请问用的是什么字体啊?很漂亮的

使用特权

评论回复
7
lostzay|  楼主 | 2011-12-26 20:42 | 只看该作者
6# Wayner
居然阿~莫~也被屏蔽,擦

使用特权

评论回复
8
lostzay|  楼主 | 2011-12-26 20:43 | 只看该作者
本帖最后由 lostzay 于 2011-12-26 20:45 编辑

现在的问题是(第34行)RB8一直是0啊,我用串口调试已经设置ODD了,理论上应该k为奇数,RB8就是0,k为偶数,RB8就是1吧

导致有时候根本无法发送k的值 ,第38行,



void init_serialcomm(void)//串口中断初始化函数
{
TMOD=0x20;   //M1=1,M0=0 定时器1工作方式2(定时常数重装,8 位)
SCON=0xD0;   //SM0=1,SM1=1,SM2=0,REN=1 串口工作方式3,允许接收   
TH1=0xFD;    //晶振11.0592时,波特率9600
PCON=0x80;   //波特率倍增,9600*2=19200
TL1=TH1;     //TL1计数,溢出后,TH1值送入TL1
  
TR1=1;       //启动定时器1
TI=0;
ES=1;        //允许串口中断
EA=1;        //开总中断
}




void oddcheck(uchar tempchar)
{
uchar count;
uchar a;
uchar k=0;
a=tempchar;
TI=0;
for(count=0;count<8;count++)           //8位数据检验
{
if(0x80 & a)            //从最左边1位开始计算是否为1
{         
k++;            //如果是1,校验标志+1
}
a = a << 1 ;       
}

if((k%2)^RB8)            //校验标志是否和RB8一致,不一致则说明数据被正确接收
{
check_flag=1;   //将串口数据标志置位
         ES=0;
SBUF=k;
while(!TI);
TI=0;
ES=1;

}   

  

}


void uart_interrupt(void) interrupt 4//串口中断函数
{  

if(RI)// RI=1表示cpu收取数据完毕
{  
RI=0;  //复位

comm_inbuf_temp=SBUF;
oddcheck(comm_inbuf_temp);


}  
else
TI=0;  

   
}

使用特权

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

本版积分规则

个人签名: 欢迎单片机、射频方面的人士多多交流

4

主题

151

帖子

1

粉丝