19.3.2 从机程序设计
这里在KeilµVision3集成开发环境中,使用Keil C51语言进行设计。建立项目的方法可以参考双机通信一节,这里主要介绍多机通信时从机的程序。
1.主函数
在多机通信从机的主函数中,首先初始化串口,然后进行空循环,监视串口的中断。从机的通信处理部分放在中断服务例程中执行。主函数的源代码示例如下。
include<reg52.h>
define uchar unsigned char
define SLAVE 0x00
define BN 16
uchar idata SendData[16];
uchar idata ReceiveData[16];
void main(void)
{
SCON=0x70;//设置串行口:方式1,8位UART,允许接收
TMOD|=0x20;//设置定时器T1,方式2,8位自动重装
PCON=0x80;//设置SMOD=1
TL1=0xF4;//波特率4800bit/s,初值
TH1=0xF4;
TR1=1;//启动定时器T1
ES=1;
EA=1;//开串行口中断
while(1)//主循环
{
}
}
2.中断服务例程
中断服务例程用于从机处理数据的发送和接收。在程序中,首先判断接收到的是否为本机地址,如果是则继续接收指令。当接收的指令为0x01时,则继续接收主机发送的数据。当接收的指令为0x02时,则向主机发送数据。中断服务例程的流程图如图19.15所示。中断服务例程的程序代码示例如下。
图 19.15 中断服务例程的流程图
void slave(void)interrupt 4 using 1//中断服务例程
{
uchar p,i;
uchar a;
bit SendBit;//准备发送标志
bit ReceiveBit;//准备接收标志
RI=0;//关串行口中断
ES=0;
if(SBUF!=SLAVE)//非本机地址
{
ES=1;
goto Exit;
}
SM2=0;//取消监听状态
SBUF=SLAVE;//发回从机地址
while(TI!=1);
TI=0;
while(RI!=1);
RI=0;
if(RB8==1)//地址不符,从机复位
{
SM2=1;
ES=1;
goto Exit;
}
a=SBUF;//接收命令
if(a==0x01)//从机接收主机的数据
{
if(ReceiveBit==1)
SBUF=0x01;//接收准备好,发回0x01
else
SBUF=0x00;
while(TI!=1);
TI=0;
while(RI!=1);
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto Exit;
}
//开始接收数据
ReceiveBit=0;
while(1)
{
p=0;//初始化校验和为0
for(i=0;i<BN;i++)
{
while(RI!=1);RI=0;
SendData[i]=SBUF;//接收数据
p+=ReceiveData[i];
}
while(RI!=1);
RI=0;
if(SBUF==p)
{
SBUF=0x00;//校验和相同,返回00H
break;
}
else
{
SBUF=0xEE;//返回EEH,重新接收
while(TI!=1);
TI=0;
}
}
SM2=1;
ES=1;
ReceiveBit=1;//准备接收标志
}
else if(a==0x02)//从机向主机发送数据
{
if(SendBit==1)
SBUF=0x02;//发送准备好
else
SBUF=0x00;
while(TI!=1);
TI=0;
while(RI!=1);
RI=0;
if(RB8==1)
{
SM2=1;
ES=1;
goto Exit;
}
//开始发送数据
SendBit=0;
do
{
p=0;//初始校验和为0
for(i=0;i<BN;i++)
{
SBUF=SendData[i];//发送数据
p+=SendData[i];
while(TI!=1);
TI=0;
}
SBUF=p;//发送校验和
while(TI!=1);
TI=0;
while(RI!=1);
RI=0;
}while(SBUF!=0);//主机接收不正确,重新发送
SM2=1;
ES=1;
SendBit=1;//准备发送标志
}
else//非法命令
{
SBUF=0x80;
while(TI!=1);
TI=0;
SM2=1;
ES=1;//恢复监听
}
Exit:;
}