📄 master.c
字号:
/*c8051f内置UART地址识别硬件,UART0的地址是通过串口地址寄存器
SADDR0和串口地址允许寄存器SADEN0两个SFR进行编程的。
设主机发送的地址联络信号00H,01H,02H为从机地址,地址FFH是命令
各从机复位SM2=1的复位命令。
主机的命令如下:
01H 请求从机接收主机数据的命令
02H 请求从机向主机发送数据的命令
其他都按照从机向主机发送数据命令02H来执行
从机的状态字格式如下:
ERR 0 0 0 0 0 TRDY RRDY
ERR=1 表示从机接收到的命令是非法的
TRDY=1 表示从机已经准备好向主机发送数据
RRDY=1 表示从机已经准备好接收主机发送的数据
通常从机以中断方式控制与主机的通信,程序分为主机程序和从机程序,
约定一次传输的数据为16字节,下面以02H地址的从机为例。*/
#include<c8051f020.h>
#define uchar unsigned char
#define SLAVE 0x02 //从机地址
#define BN 16
uchar rbuf[16];
uchar idata tbuf[16]={"master transmit"};
void err(void) //发复位FFH命令
{ SBUF0=0xff;
while(!TI0);
TI0=0;
}
uchar master(uchar addr,uchar command) //主机函数
{
uchar aa,i,p;
while(1)
{
SBUF0=SLAVE; //发呼叫地址
while(!TI0);TI0=0;
while(!RI0);RI0=0; //等待从机地址答复
if(SBUF0!=addr) err(); //地址错,发复位命令
else
{
TB80=0; //清地址标志
SBUF0=command; //发命令
while(!TI0);TI0=0;
while(!RI0);RI0=0; //等待从机命令答复
aa=SBUF0;
if((aa&0x80)==0x80) {TB80=1;err();} //命令出错,发复位命令
else
{
if(command==0x01) //是发送命令
{
if((aa&0x01)==0x01)
{
do{
p=0; //清校验和
for(i=0;i<BN;i++)
{
SBUF0=tbuf[i]; //发送一字节
p+=tbuf[i];
while(!TI0);TI0=0;
}
SBUF0=p; //发校验和
while(!TI0);TI0=0;
while(!RI0);RI0=0; //等待校验和的应答
}while(SBUF0!=0); //接收出错,重发。00h为正确,ffh为错误
TB80=1; //接收正确,置地址标志
return(0);
}
}
else ////是接收命令
{
if((aa&0x01)==0x01) //从机准备好发送
{
while(1)
{
p=0;
for(i=0;i<BN;i++)
{
while(!RI0);RI0=0;
rbuf[i]=SBUF0;
p+=rbuf[i];
}
while(!RI0);RI0=0;
if(SBUF0==p)
{
SBUF0=0x00; //校验和相同,发00h
while(!TI0);TI0=0;
break; //推出
}
else
{
SBUF0=0xff;
while(!TI0);TI0=0;
}
}
TB80=1; //置地址标志
return(0);
}
}
}
}
}
}
void main()
{
TMOD=0x20; //T1方式2
TH1=0xfd;
TL1=0xfd; /*传输波特率9600,设SYSDCLK=12Mhz
T1M=0(按振荡器的12分频计数),SMOD0=0*/
PCON=0x00;
TR1=1;
SCON0=0xf8; //UART0方式3,SM20=1,REN0=1,TB80=1
master(SLAVE,0x01);
master(SLAVE,0x02);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -