完整注释,有问题可以私聊。也可用作两个串口通信。
1.定义标志位
u16 temp1 = 0;
u16 temp2 = 0; //定义中断标志位和数据缓存位
u8 rbuff_1[30]; //数据储存数组
u8 r_count_1 =0; //计数收了多少数
u8 r_flag_1 =0; //数据完成标志位
u8 state_1 =0; //状态标志位
u16 r_num = 0; //数据帧长度
u16 check = 0; //校验位
u16 check_1 = 0;
u16 check_2 = 0;
u8 flag2 = 0; //串口2中断标志位
u8 count = 0; // TIM 1
u8 i = 0;
u8 j = 0;
#define FOSC 11059200L //系统频率
#define BAUD 9600
2.串口初始化
void InitUART(void)
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
BRT = 0xDC; //设定独立波特率发生器重装值
AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器
AUXR |= 0x10; //启动独立波特率发生器
AUXR &= 0xF7; //波特率不倍速
S2CON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //
BRT = 0xDC; //设定独立波特率发生器重装值
AUXR |= 0x10; //启动独立波特率发生器
IE2 =0x01; //开串口2中断 ES2=1
EA = 1; //开启总中断
ES = 1; //开启串口1中断
}
3.收发函数
/****************串口1发送********************/
void UART_1SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI); //若TI=0,在此等待
TI = 0;
}
/****************串行口2发送****************/
void UART_2SendOneByte(unsigned char c)
{
S2BUF = c;
while(!(S2CON&S2TI)); //若S2TI=0,在此等待
S2CON&=~S2TI; //S2TI=0
4.中断处理函数
void UART_1Interrupt(void) interrupt 4
{
if(RI==1)
{
/******************带协议收发状态机程序***********************/
temp1=SBUF; //寄存器值赋给数据位
switch (state_1) //状态判断
{
case 0: //状态0
if(temp1 == 0xA5) //判断数据头
{
rbuff_1[r_count_1++] = temp1; //把第一个数据存到数组里
state_1 = 1; //收到数据头正确状态变为1
}
else
{
state_1 = 0; // 数据头不对 重新获取数据
r_count_1 = 0; // 标志位不变
}
break;
case 1:
if(temp1 == 0xB6) //数据头多加一位,防止出错
{
rbuff_1[r_count_1++] = temp1; //把第第二个数据存到数组
state_1 = 2; //收到数据头正确,状态变为2
}
else //数据头不对重新获取数,从头开始获取
{
state_1 = 0;
r_count_1 = 0;
}
break;
case 2:
rbuff_1[r_count_1++] = temp1; //保存数据长度位到数组第三位
state_1 = 3; //状态进行到3
r_num=rbuff_1[2]; //数据长度存入
break;
case 3:
if(r_count_1<(r_num+2)) // 判断是否符合数据长度
{
rbuff_1[r_count_1++] = temp1; //不符合继续存入
state_1 = 3; //继续跳转的状态4 继续接收完数据
}
else //数据接收完成
{
rbuff_1[r_count_1++] = temp1; //数组最后一位保存完成其余状态位清0
state_1 = 4; //状态位变为0
}
break;
case 4:
rbuff_1[r_count_1] = temp1;
check_2 = temp1;
r_flag_1 = 1;
r_num = 0;
state_1 = 0;
default:
state_1 = 0;
break;
}
RI = 0; //中断标志位清0
}
}
/************串行口2中断处理函数*************/
void UART_2Interrupt(void) interrupt 8
{
if(S2CON&S2RI)
{
S2CON&=~S2RI;
flag2=1;
temp2=S2BUF;
}
}
5.主程序
void main(void)
{
InitUART(); //串行口初始化
while(1)
{
if(r_flag_1==1)
{
r_flag_1=0;
for(j=3;j<(r_count_1);j++)
{
check += rbuff_1[j];
}
check_1 = check % 6;
if(check_1 == check_2)
{
check = 0;
for(i=0;i<(r_count_1+1);i++)
{
UART_1SendOneByte(rbuff_1[i]);
}
}
else
{
UART_1SendOneByte(0xbb);
}
r_count_1=0;
}
//如果串口2接收到数据,将此数据由串口1发送
if(flag2==1)
{
flag2=0;
UART_1SendOneByte(temp2);
}
// }
}
}