求单片机与PC UART通信,断掉串口线单片机的状态发生改变
上代码。
解决方法,把改变状态的语句放在if()结构里,条件执行它们,这样稳定些。关于为什么变,从硬件考虑,电平突变时候引起的。
#include"main.h"
sbit relay1=P1^5;sbit relay2=P1^4;sbit relay3=P1^3;sbit relay4=P1^2;sbit relay5=P1^1;sbit relay6=P1^0;//继电器控制端口
uchar dat1;//头字节
uchar dat2,dat3,dat4;//继电器号,继电器状态(0接通,1断开),组合继电器状态
uchar datx=0xff;//将eeprom中的状态赋值给datx
uchar counter;//1秒定时
void delay1m(uint x)
{
uint i,j;
for(i=0;i<x;i++) //连数x次,约 x ms
for(j=0;j<120;j++); //数120 次,约1 ms
}
void uart_time1_time0_init()
{
/*TMOD=0x21;//定时器1工作于方式2,定时器0工作于方式1
TH1=0xfd;TL1=0xfd;//波特率9600
TH0=(65535-50000)/256;TL0=(65535-50000)%256;//定时50ms
SCON=0x50;//uart工作于方式1,8位uart
TR1=TR0=PS=ET0=EA=ES=1;//启动定时器1、0,开定时器0、总中断,开uart中断,串口中断优先 */
TMOD=0x20;//定时器1工作于方式2
TH1=0xfd;TL1=0xfd;//波特率9600
SCON=0x50;//uart工作于方式1,8位uart
TR1=PS=EA=ES=1;//启动定时器1,开总中断,开uart中断,串口中断优先
}
void main()
{
uart_time1_time0_init();
delay1m(1000);
while(1);
}
void uart_interrupt()interrupt 4
{
while(!RI);RI=0;dat1=SBUF;
if(dat1==0xbb)
{
ES=0;SBUF=0xcc;while(!TI);TI=0;ES=1;
}
else if(dat1==0x88)//控制继电器状态
{
while(!RI);RI=0;dat2=SBUF;while(!RI);RI=0;dat3=SBUF;//接收继电器号,继电器状态字节
// ES=0;SBUF=dat2;while(!TI);TI=0;SBUF=dat3;while(!TI);TI=0;ES=1;
switch(dat2)
{
case 0x01:relay1=dat3;if(dat3==0){datx=datx&0xfe;}else{datx|=dat3;}break;
case 0x02:relay2=dat3;if(dat3==0){datx=datx&0xfd;}else{datx|=dat3<<1;}break;
case 0x03:relay3=dat3;if(dat3==0){datx=datx&0xfb;}else{datx|=dat3<<2;}break;
case 0x04:relay4=dat3;if(dat3==0){datx=datx&0xf7;}else{datx|=dat3<<3;}break;
case 0x05:relay5=dat3;if(dat3==0){datx=datx&0xef;}else{datx|=dat3<<4;}break;
case 0x06:relay6=dat3;if(dat3==0){datx=datx&0xdf;}else{datx|=dat3<<5;}break;
default:break;
}
}
else if(dat1==0x77)//组合控制继电器状态
{
while(!RI);RI=0;dat4=SBUF;datx=dat4;
relay1=dat4&0x01;relay2=(dat4&0x02)>>1;relay3=(dat4&0x04)>>2;
relay4=(dat4&0x08)>>3;relay5=(dat4&0x10)>>4;relay6=(dat4&0x20)>>5;
}
}
/*
void time0_interrupt()interrupt 1
{
TH0=(65535-50000)/256;TL0=(65535-50000)%256;//定时50ms
counter++;
if(counter>=50)//1秒时间到,主动发送继电器状态给PC
{
counter=0;
ES=0;SBUF=0x99;while(!TI);TI=0;SBUF=datx;while(!TI);TI=0;ES=1;//头字节,继电器状态字节
}
} */
你的意思是防止条件不成立时也执行?先谢谢!
是这么理解的。这就是通信帧为什么要加帧起始、帧校验、帧结束的原因了,方便接收方加各种条件执行保证数据的正确率。
其实这个问题很奇怪,通讯没有问题,只要串口线连着就没事,断开就不正常!就是说,断开串口线之后单片机为啥工作不正常,其实都定义了贞头的!貌似与串口线有关啊?只断串口线的与PC连接端!