我用c51单片机进行串口通信,发送数据时如果用轮询的方式就成功,如果用发送中断的方式另一个单片机接收到得数据老是错误,望高手解答。。。
串口初始化
TMOD=0x20;//工作方式2 自动重装
TH0=0xF4; //波特率2400bps
TL0=0xF4;
TR1=1;//启动定时器1
SCON=0x50;//设置串行端口方式1 ,允许接收
PCON=0x80;//设置波特率提高1倍
IE=0x90;//开串行通信中断
void time_int(void) interrupt 4
{
if(RI)
{
RI=0;
databuf=SBUF;//读取缓冲器中的值
}
if(TI)
{
TI=0;
}
}
void main()
{...
SBUF=9;//用中断的方式接收到得都是误码,用轮询方式就不会
//sendData_serial(9);
...
}
//轮询方式
void sendData_serial(unsigned char databuf)
{
SBUF=databuf;//向缓冲器写入值
while(!TI);
TI=0; //发送完毕
}
if(TI)
{
TI=0;
}
while(!TI);
这两种方式我认为第二种要好些,即等到TI为1时才赋值TI=0; 此时程序一直在此等待发送,而第一种方式程序多次跳入再跳出中断函数,时间上可能会忙不过来,所以导致接受端乱码,当然,从原理上来讲,第一种也是正确的。不知道楼主指的乱码到了哪种程度。
首先要保证你的main里面是个无限循环.......
发送数据一般用轮询的方式(你知道何时发),接受数据才用中断(因为不知道何时来)。而且发送用中断时,一旦中断丢失会发不出去。
void main()
{...
SBUF=9;//用中断的方式接收到得都是误码,用轮询方式就不会
//sendData_serial(9);
...
}
----------------
这样处理并不能算中断方式发送,如要中断方式发送需要放到串口中断中处理...
建议发送时用轮询,接收时用中断,并且用接收缓冲区接收后放到程序中处理.
从现在给你来的程序很难判断出为啥乱码,不过建议发送用轮询的方式 。
另外我觉得,楼主你的轮询发送程序里,最好把串口中断关了,发送完再开。
我的main里是个无限循环来的,如果用中断的话,数据发送成功的话TI就会置1的,从而进入中断函数,如果发送没有成功,TI是不会置1,也不会进入中断函数的。
用中断的时候,你发送数据时,得把串口中断给关了,发送完毕后在开启串口中断
"用中断的时候,你发送数据时,得把串口中断给关了,发送完毕后在开启串口中断"
ls正解,这样可以防止再次被中断
轮询与查询,发送一个字节都是一样的。
sbuf = xxx;
while( !TI );
TI = 0;
其实在中断程序里不用关中断的,因为只有优先级比串口中断高的中断才会响应,如果是同个级别的中断时不会被响应的。
#8楼 得分:0回复于:2010-03-08 14:10:58"用中断的时候,你发送数据时,得把串口中断给关了,发送完毕后在开启串口中断"
ls正解,这样可以防止再次被中断
如果把串口中断关了,那怎么知道什么时候发送完毕呢??检查TI?那就成了查询方式了
你发送的时候进入中断,但可能也接受了数据,再次进入中断,导致出错
我觉得可能是中断嵌套了 我们并不能很准确的计算出单片机中断时执行到哪句代码
是啊,如果有其他优先级更高的中断发生呢
引用: 引用 10 楼 jeasonlsn 的回复:
其实在中断程序里不用关中断的,因为只有优先级比串口中断高的中断才会响应,如果是同个级别的中断时不会被响应的。
#8楼 得分:0回复于:2010-03-08 14:10:58"用中断的时候,你发送数据时,得把串口中断给关了,发送完毕后在开启串口中断"
ls正解,这样可以防止再次被中断
如果把串口中断关了,那怎么知道什么时候发送完毕呢??检查TI?那就成了查询方式了
if(TI)
{
TI = 0;
SBUF = 9;
}
这样可以么。。