钻石会员
  
主题
帖子
积分11931
阅读权限50
注册时间2009-7-18
最后登录1970-1-1
在线时间 小时
|
求助各位大师能否帮我写一个数据长度不相等的串口中断程序
要求晶振为11.0592m 或22.1184m 波特率为:57600
首先从串口发送一个 02 03 04 05 07 02 17 的十六进制码
如果接收到是: 02 03 04 05 09 02 4F 4B B3 的十六进制码,则P1.0为低,反之P1.0为高
再发从串口发送一个 02 03 04 05 07 03 18 的十六进制码
如果接收到是: 02 03 04 05 08 03 00 19 的十六进制码,则P1.1为低,反之P1.1为高
蓝色字体为头 红色字体为数据长度 绿色为检验码
谢谢!
我自已写的其本上能实现上述功能,但是如果接收到十六进制码长度如果大于9则程序飞跑了.刚学C语言写得很乱
//晶体振荡器为22.1184MHZ
#include<AT89X52.h>
#define uchar unsigned char
#define uint unsigned int
void scan1();//发送指令02030405070217
void scan2();//发送指令02030405070318
void beep();//读return值是否为0203040509024F4BB3
void adc1(); //读return值是否为0203040508030019*/
void display(uchar , uchar , uchar , uchar ); //显示函数
void delay_1ms(uint x);//1MS延时
#define length 9 //数据长度
uchar SBUFF[length];
uchar bai , shi , ge ,i , a = 0 , k=0;
bit l, M ;
uint shu ;
uchar code FCT1[7]={0x02,0x03,0x04,0x05,0x07,0x02,0x17};//指令1
uchar code FCT2[7]={0x02,0x03,0x04,0x05,0x07,0x03,0x18};//指令2
void main()
{
TMOD=0x21; //设置定时器1为模式2;定时器0为模式1
TH0=(65536-46000)/256; //约50MS定时器初值
TL0=(65536-46000)%256; //约50MS定时器初值
ET0 = 1;
TH1=0xff; //装初值设定波特率//22.1184MHZ=57600
TL1=0xff; //19200=0xfd
TR1=1; //启动定时器 SM0 SM1
SM0=0; //串口通信模式设置 0 0 = 0
SM1=1; // 0 1 = 1
REN=1; //串口允许接收数据 1 0 = 2
EA=1; //开总中断 1 1 = 3
PS=1; //串行口定义为高优先级中断源
ES=1; //开串中断
PCON=0x80; // 波特率不加倍
//若为PCON=0x80波特率加倍(11.0592MHZ=57600)
while(1)
{
if(start_key==0 && M==0) //开始定时器0
{
delay_1ms(5);
if(start_key==0 )
{
M = 1;
TR0 = 1;//开始定时器0
}
// while(!start_key) ;
}
beep();
//////////////////////////////////////////////////////////
if(l!=1)
display(15,bai,shi,ge); //显示时间
else
{
if( P1_0==0 && P1_1==0)
{
display(14,10,11,11); //显示pass
}
else
{
display(15,16,17,17); //显示Err
}
}
adc1();
}
}
//========读return值是否为0203040509024F4BB3==============
void beep()
{
if(SBUFF[0]+SBUFF[1]+SBUFF[2]+SBUFF[3]+SBUFF[4]+SBUFF[5]+SBUFF[6]+SBUFF[7] ==SBUFF[8] && SBUFF[8] == 0xb3)
{
P1_0=0;
}
}
//========读return值是否为0203040508030019============
void adc1()
{
if(SBUFF[0]+SBUFF[1]+SBUFF[2]+SBUFF[3]+SBUFF[4]+SBUFF[5]+SBUFF[6] == SBUFF[7] && SBUFF[7] == 0x19)
{
P1_1=0;
}
}
//=================scan:02030405070217===================== */
void scan1()
{
for(i=0;i<7;i++)
{
ES=0;//进入发送数据时先关闭串行中断
SBUF=FCT1;//将数据原样发回?
while(!TI);//等待数据发完
TI=0;
ES=1;//退出再开串行中断
}
}
//==================scan:02030405070318====================
void scan2()
{
for(i=0;i<7;i++)
{
ES=0;//进入发送数据时先关闭串行中断
SBUF=FCT2;//将数据原样发回?
while(!TI);//等待数据发完
TI=0;
ES=1;//退出再开串行中断
}
}
//=============中断服务程式================================ */
void UART_Interrupt_Receive(void) interrupt 4
{
if(RI==1)
{
RI=0;
SBUFF[k]=SBUF;
++k;
if(k==SBUFF[4])
k=0;
}
else
{
TI=0;
}
}
//=========================================================
/*22.1184MHZ时=1.0026MS为单位的延时程序*/
void delay_1ms(uint x)
{
uchar j;
while(x--)
{
for(j=0;j<227;j++)
{;}
}
}
//==========================================================
void InitTimer0(void) interrupt 1 //约50ms中断一次
{
TH0=(65536-46000)/256; //约50MS定时器初值 11.0592 = 4600
TL0=(65536-46000)%256; //约50MS定时器初值
a++; //约每50ms A自加一
if(a==40) //如果到了约1s
{
a=0;
shu++;
bai=shu/100;
shi=shu%100/10;
ge=shu%10;
switch(shu)
{
case 120: //120S 等待2分钟
{
scan1(); break;
}
case 365: //48S
{
scan2(); break; //375 等待4分钟
}
case 380: //48S
{
l=1;
shu = 0;
TR0 = 0;
break; //20s
}
}
}
}
//default:
//////////////////////////////////////////////////////////////
void display(uchar k,uchar b,uchar s,uchar g) //显示函数
{
P0=table[k];
dula=1;
dula=0;
P0=0x7b;// 0x04; //
wela=1;
wela=0;
delay_1ms(2);
dula=0;
P0=table;
dula=1;
dula=0;
P0=0x77;// 0x08;//
wela=1;
wela=0;
delay_1ms(2);
dula=0;
P0=table;
dula=1;
dula=0;
wela=0;
P0=0x6f;//0x10;//
wela=1;
wela=0;
delay_1ms(2);
P0=table[g];
dula=1;
dula=0;
P0=0x5f;// 0x20; //
wela=1;
wela=0;
delay_1ms(2);
} |
|