在中断中从串口调试器里发送出来的数据,接收下来再发送出来在串口调试器上接收的和先前发送的数据不同,不明白到底是什么原因影响了,我是新手,一直找不到原因之只好请各位高手帮忙看看
我从串口调试器发送AB2D02000084 这串数据
void com_UART(void) interrupt 4 using 1
{
unsigned char idata chek,c;
TOGGLE_WD();
if(RI)
{
c=SBUF;
RI=0;
oldstate=nowstate;
nowstate=0;
switch(oldstate)
{
case 0:
if(c==0xAB)
{
TIME_OUT=50;
chek=c;
nowstate=1;
break;
}
else
{
nowstate=0;
break;
}
case 1:
if(c<=0x2f&&c>=0x20)
{
TIME_OUT=50;
REBuffer[0]=c;
chek^=c;
nowstate=2;
}
else
{
nowstate=0;}
break;
case 2:
TIME_OUT=50;
REBuffer[1]=c;
chek^=c;
nowstate=3;
index=0;
break;
case 3:
TIME_OUT=50;
if(index {
REBuffer[2+index]=c;
chek^=c;
index++;
nowstate=3;
break;
}
if(c==chek)
{
CmdValid=1;
SBUF=REBuffer[0]; 这里在串口调试器上可以看到正确返回了2D
while(!TI);
TI=0;
}
else
{
SBUF=0xFF;
CmdValid=0;
while(!TI);
TI=0;
}
break;
default: break;
}
}
if(TI&&!RI)
{
TI=0;
chek=0;
index=0;
}
}
}
void main(void)
{
char idata status;
init();
init_serialcomm();
status = M500PcdConfig();
Idle_init(); //Initialize and prepare for Idle
while(1)
{ TOGGLE_WD();
if(CmdValid)
{
SBUF=REBuffer[0]; 这里返回的就不是2D,而是B3了,不知道这个B3是哪里来的,为什么会无故跑出个其他数来?
CmdValid = FALSE;
cmdexecution();
Idle=FALSE;
else {
Tdelay_10ms(10);
}
}
请高手帮我看看吧!
只能说你程序写的太混乱了, 自己先好好检查一下吧. 呵呵
串口还是建议使用中断方式,查询标志位太浪费资源了,中断会更加简单
程序最好能缩进,要不然读起来太费力气,还没有注释
不好意思,先前的程序没有缩进和注释看起来的确很费劲。现在加上缩进和注释,请高手帮帮忙看看吧!
串口中断服务函数,从串口调试器发送一串规定格式的数据,格式为开始位0XAB,命令字0X20-0X2F中的一个,数据的长度位,数据……,奇偶校验位,这里我从串口发送AB2D02000084,即命令字为2D,数据长为2,2个数据是分别是00,00,校验位为84,
void com_UART(void) interrupt 4 using 1
{
unsigned char idata chek,c;
TOGGLE_WD(); 喂狗信号
if(RI)
{
c=SBUF; 如果从串口调试器上有数发出则把接收到的数存在C中
RI=0;
oldstate=nowstate;
nowstate=0; 设定状态,初始状态为0,即从开始位开始接收
switch(oldstate)
{
case 0:
if(c==0xAB) 如果接收到的数为AB
{
TIME_OUT=50; 时间溢出,若很长时间还没有接收到数则返回到初始态
chek=c; 存在校验位里以便运算
nowstate=1; 进入下个状态,即接收命令字
break;
}
else
{
nowstate=0; 不然就返回到初始状态继续等待接收AB
break;
}
case 1:
if(c <=0x2f&&c>=0x20) 如果命令字在这个范围内
{
TIME_OUT=50; 将命令字存在REBuffer里,定义如下:
REBuffer[0]=c; static unsigned char xdata Buffer[24] ;
chek^=c; 开始位与命令字进行异或运算,算出其校验位
nowstate=2; 进入第2状态,即接收数据长度
}
else
{
nowstate=0; 不在范围内则返回初始态
}
break;
case 2:
TIME_OUT=50;
REBuffer[1]=c; 接收长度到REBuffer[1]
chek^=c; 计算其校验位
nowstate=3; 进入第3状态,即接收数据
index=0;
break;
case 3:
TIME_OUT=50;
if (index < Buffer[1]) 一个个接收REBuffer[1]个数据
{
REBuffer[2+index]=c; 接收的数存入REBuffer中
chek^=c;
index++; 计算其校验位
nowstate=3; 继续返回接收数据状态直到数据接收完
break;
}
if(c==chek) 接收完后,如果再接收到的数等于计算出来的校验位则置 CmdValid=1;
{
CmdValid=1;
SBUF=REBuffer[0]; 这里在串口调试器上可以看到发送的命令字,正确返回了2D
while(!TI);
TI=0;
}
else
{
SBUF=0xFF; 校验不对则返回FF
CmdValid=0;
while(!TI);
TI=0;
}
break;
default: break;
}
}
if(TI&&!RI)
{
TI=0;
chek=0;
index=0;
}
}
}
主程序
void main(void)
{
char idata status;
init(); 初始化一些变量
init_serialcomm(); 初始化串口
status = M500PcdConfig();
Idle_init(); //Initialize and prepare for Idle 初始化无卡的状态
while(1)
{
TOGGLE_WD(); 喂狗信号
if(CmdValid) 当串口调试器发送一串正确的数据后程序将进入这里
{
SBUF=REBuffer[0]; 在这里返回命令字看是多少,这里返回的就不是2D,而是B3了,不知道这个B3是哪里来的,为什么会无故跑出个其他数来?
CmdValid = FALSE;
cmdexecution(); 根据返回的命令字来执行函数
Idle=FALSE;
else
{
Tdelay_10ms(10);
}
}
先从简单的来!!!
我是做c8051f单片机
我打算做三合一的下载线
c8051f,s5x,(以上两种已做好,效果还真不错!!!)
现在准备做mega8/48/88/168
欢迎大家到我的博客看看
http://c8051fmcu.blog.sohu.com