#include
#include
#include
#define max_rev_time 5
#define rev_cnt 10
#define max_rev_num 20
unsigned char recv_buf[max_rev_num];
unsigned char start_timer=0;
unsigned char recv_timer_cnt;
unsigned char recv_cnt;
unsigned char recv_flag=0;
void Delay100ms();
void sendbyte(unsigned char dat);
void sendstring(unsigned char *dat1);
char putchar(char c);
void Timer0Init(void);
void UartInit(void);//9600bps@11.0592MHz
void clr_recvbuffer(unsigned char *buf);
void main()
{
Timer0Init();
UartInit();
EA=1;
printf("wait for serial communication test start.\r\n");
printf("please send a string of data: \r\n");
while(1)
{
if(recv_flag)
{
recv_flag=0;
start_timer=0;//关闭定时器
sendstring(recv_buf);//处理数据
clr_recvbuffer(recv_buf);//清除缓冲BUFFER
}
}
}
void Delay100ms() //@11.0592MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 5;
j = 52;
k = 195;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void UartInit(void) //9600bps@11.0592MHz
{
PCON |= 0x80; //使能波特率倍速位SMOD
SCON = 0x50; //8位数据,可变波特率
//AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
//AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xFA; //设定定时初值
TH1 = 0xFA; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
ES=1;
TR1 = 1; //启动定时器1
}
void Timer0Init(void) //1毫秒@11.0592MHz
{
//AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
ET0 =1;
TR0 = 1; //定时器0开始计时
}
void timer0_isr() interrupt 1
{
TR0=0;
if(start_timer==1)
{
recv_timer_cnt++;//累加定时器时间计数器
if(recv_timer_cnt>max_rev_time)//判断定时时间表是否超过了设定的最大的阀值,超过则说明等待一段时间后没有新的数据到,我们判断一包数据接收完毕。
{
recv_timer_cnt=0;//清除定时计数器 处理数据 清除BUFFER (放到数据处理之后。
recv_cnt=0;
recv_flag=1;
}
}
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TR0=1;
}
void sendbyte(unsigned char dat)
{
SBUF=dat; //10位 异步串口通信 0 88H 1
while(!TI);
TI=0;
}
void sendstring(unsigned char *dat)
{
while(*dat!='\0')
{
sendbyte(*dat++);
}
}
char putchar(char c)
{
sendbyte(c);
return c;
}
void uart_isr() interrupt 4
{
if(RI)
{
RI=0;
start_timer=1;//每接收一帧数据的时候,打开软件定时器,去计数。
if(recv_cnt < max_rev_num)
{
recv_buf[recv_cnt]=SBUF;//接收数据到数据缓冲区,注意缓冲区的大小范围问题
recv_cnt++;
}
else
{
recv_cnt=max_rev_num;
}
recv_timer_cnt=0;//每接收一帧数据,记得把定时计数清零,相当于是看门狗,但是在定时中断里面会不断累加。
if(TI)
{
TI=0;
}
}
}
void clr_recvbuffer(unsigned char *buf)
{
unsigned char i;
for(i=0;i
{
buf[i]=0;
}
}