串口通信协议程序
主机程序:
/*
主机主要处理 :
主—>从 1.给从机发送命令
2.给从机发送数据
3.命令从机向主机发送数据
从—>主由中断程序处理根据从机发送过来的请求类型
0.请求主机发送命令(包括主到从的1,2命令)
1.请求主机接收数据
2,3保留
*/
#include
#include
#define uchar unsigned char #define uint unsigned int #define
slav1_addr 0x01 #define slav2_addr 0x02 #define COMEND 0 #define
REC_DATE 1 //主机向从机发送多数据命令高四位为1111,所以其他命令高四位不能为1111
#define cmd_X 0x12 #define cmd_rec_data 0x11
sbit signal=P3^2;
uchar temp_addr,num,rec,style,re_addr;
uchar buf[20];
uchar rec_data[10];
void delay(unsigned int i) {
while(i--);
}
void init_uart(void)
{
TMOD=0x20; //定时器方式2--8位reload模式
TH1=0xfd;
TL1=0xfd;
PCON=0; //波特率不加倍
SCON=0xf0; //方式三
TB8=1; //发送地址时第九位为1
SM2=1; //接收到第九位为1时才能接收数据
TR1=1; //要在设置scon后开定时
ES=1; //开中断
EA=1;
}
//发送命令
void uart_send_cmd(uchar addr,uchar cmd)//uchar *date) {
while(signal==0); //检查总线是否被占
signal=0; //占用总线
EA=0;//关中断
do
{
do
{
SBUF=addr; //发送从机地址
while(TI!=1);
TI=0;
}
while(RI!=1); //一直等待从机响应
//while循环里可加入出错处理
temp_addr=SBUF;
RI=0;
}
while(temp_addr!=addr); //一直等到从机回应的地址相同
//while循环里可加入出错处理
TB8=0; //发送数据第9位为0 // SM2=0; // 接收到第九位为1时才置位RI //每次一个数据
SBUF=cmd;
while(TI!=1);
TI=0;
TB8=1;
// SM2=1;
RI=0;
TI=0; //不处理期间发生的中断
EA=1;
signal=1; //释放总线
}
//主机向从机发送多数据
//自动计算发送数据长度
void uart_send_data(uchar addr,uchar *date)
{
uchar n;
while(signal==0); //检查总线是否被占
signal=0; //占用总线
EA=0; //关中断
do
{
do
{
SBUF=addr; //发送从机地址
while(TI!=1);
TI=0;
}
while(RI!=1); //一直等待从机响应
//while循环里可加入出错处理
temp_addr=SBUF;
RI=0;
}
while(temp_addr!=addr); //一直等到从机回应的地址相同//while循环里可加入出错处理
TB8=0; //发送数据第9位为1
SM2=0; // 接收到第九位为1时才置位RI
num=strlen(date);
SBUF=(0xf0|num); //向从机发送接收多数据命令
//高四位为标志位低四位为数据长度
while(TI!=1);
TI=0;
delay(200) ; //等待从机能稳定(从机产生接收中断需要时间) for(n=0;n { SBUF=date[n]; while(TI!=1); TI=0; delay(2) ; //放慢发送速度使从机能稳定接收 } TB8=1; SM2=1; RI=0; TI=0; //不处理期间发生的中断 EA=1; signal=1; } //主机请求从机发送数据过来 void cmd_rec(uchar addr ) { uchar numb,n; while(signal==0); //检查总线是否被占 signal=0; //占用总线 EA=0;//关中断 do { do { SBUF=addr; //发送从机地址 while(TI!=1); TI=0; } while(RI!=1); //一直等待从机响应 //while循环里可加入出错处理 temp_addr=SBUF; RI=0; } while(temp_addr!=addr); //一直等到从机回应的地址相同//while循环里可加入出错处理 TB8=0; //发送数据第9位为1 SM2=0; // 接收到第九位为1时才置位RI //每次一个数据 SBUF=cmd_rec_data; //发送命令