单片机多机通信之变量初始化的重要性
http://blog.sina.com.cn/s/blog_6dfb79cf0100uudd.html
博文题目之所以要加上变量初始化的重要性,是因为我在调试单片机多机通信程序时,也就是下面将给出的程序,花了一整个晚上才发出,原来是有一个变量没有初始化,从而导致,多机通信不成功。主机程序中为红色的注释的变量一定要初始化,否则将失败。
仿真图如下:
单片机多机通讯
说明:该程序为多机通讯程序,最多可以挂255个从机。
该程序主机发送端与多个从机的接收端相接,主机的接收端与多个从机的发送端相接。
该程序主要的目的为给从机发送作为命令的数据。
该程序调试成功,从机可正确接收。
*/
//=====================================================================
// 多机通讯主机程序
//host.c
//writer:40 2011年8月06日于6#实验室
//注:主机先发送地址,接收到应答后,再发送数据
//=====================================================================
#include
#define unit unsigned int
#define uchar unsigned char
#define addr1 0x31 //从机1地址
#define addr2 0x32 //从机2地址
#define addr3 0x33 //从机3地址
#define addr4 0x34 //从机4地址
sbit led=P2^0;
void delay(unit MS)
{
unit i,j;
for(i=0;i
}
void Uart_Init(void)
{
TMOD=0x20; //定时器T1使用工作方式2
TH1=253;
TL1=253;
PCON=0x0; //SMOD=1;
SCON=0xd0; //工作方式3,9位数据位,波特率19200bit/s,允许接收 11.0592的晶振 Sm2=0;
TI=0;
RI=0;
TR1=1; //开始计时
// IE |= 0x90 ;
}
void send_addr(ucharaddr) //发送地址
{
uchartem=0xff; //一定要初始化
while(tem!=addr) //如果发送的地址与从机应答的地址不一样,则一直发送地址
{
TI=0;
TB8=1; //发送地址帧 v
SBUF=addr; //发送地址
while(!TI); //等待发送完毕
TI=0; //软件复位TI
RI=0;
while(!RI); //等待接受完毕
tem=SBUF; //接收数据
RI=0;
}
}
void send_data(ucharddata) //发送数据,但此处由于与从机的协议,禁止发送0xff
{
TI=0;
TB8=0; //发送数据帧
SBUF=ddata; //发送数据
while(!TI);
TI=0; //软件复位TI
}
void main()
{
Uart_Init();
delay(100);
send_addr(addr1); //向从机1发地址
send_data(0x01); //发数据
send_addr(addr2); //向从机1发地址
send_data(0x02); //发数据
send_addr(addr1); //向从机2发地址
send_data(0x02); //发数据
send_addr(addr2); //向从机2发地址
send_data(0x01); //发数据
while(1)
{
led=!led;
delay(100);
}
}
从机1程序:
//=====================================================================
// 多机通讯从机1程序
//slave_1.c
//writer:40 2011年8月06日于6#实验室
//注:从机先接收地址,然后与自己的地址比较,正确了再接收数据,修改地址可挂多个从机
//=====================================================================
#include
#define unit unsigned int
#define uchar unsigned char
#define addr 0x31 //从机1地址
void delay(unit MS)
{
unit i,j;
for(i=0;i
}
void Uart_Init(void)
{
TMOD=0x20; //定时器T1使用工作方式2
TH1=253;
TL1=253;
PCON=0x0; //SMOD=1;
SCON=0xd0; //工作方式3,9位数据位,波特率19200bit/s,允许接收 11.0592的晶振 Sm2=0;
TI=0;
RI=0;
TR1=1; //开始计时
// IE |= 0x90 ; 开中断入口
}
uchar recv_data(void) //接收数据
{
uchar date;
RI=0;
while(!RI); //等待接受完毕
if(RB8==1) //若当前接收为地址帧则返回0xff
return 0xff;
date=SBUF;
RI=0;
return date;
}
void main()
{
uchartem=0XFF,Data;
Uart_Init();
while(1)
{ tem=0XFF;
SM2=1; //只接收地址帧
//如果接收到的地址帧不是本机地址,则继续等待
while(tem!=addr)
{
RI=0;
while(!RI);
tem=SBUF;
RI=0;
}
TI=0; //如果是本机地址,发送应答信号,并做好接受数据的准备
TB8=0; //主机不检测该位
SBUF=addr;
while(!TI);
TI=0;
SM2=0; //允许接受数据信息
//接收数据
Data=recv_data();
if(Data==0xff)
continue;
switch(Data)
{
case 0x01: //在此可以写入要完成的动作,最多可完成256个动作
P1=0x15; //为方便其间,赋值给P1口,测P1口电平来检测该程序
break;
case 0x02:
P2=0x56; //为方便其间,赋值给P2口,测P1口电平来检测该程序
break;
case 0x03:
break;
case 0x04:
break;
default:
break;
}
}
}
从机2程序:
//=====================================================================
// 多机通讯从机1程序
//slave_2.c
//writer:谷雨 2011年8月06日于6#实验室
//注:从机先接收地址,然后与自己的地址比较,正确了再接收数据,修改地址可挂多个从机
//=====================================================================
#include
#define unit unsigned int
#define uchar unsigned char
#define addr 0x32 //从机2地址
void delay(unit MS)
{
unit i,j;
for(i=0;i
}
void Uart_Init(void)
{
TMOD=0x20; //定时器T1使用工作方式2
TH1=253;
TL1=253;
PCON=0x0; //SMOD=1;
SCON=0xd0; //工作方式3,9位数据位,波特率19200bit/s,允许接收 11.0592的晶振 Sm2=0;
TI=0;
RI=0;
TR1=1; //开始计时
// IE |= 0x90 ;
}
//void send(ucharData) //发送数据程序
//{
//}
uchar recv_data(void) //接收数据
{
uchar date;
RI=0;
while(!RI); //等待接受完毕
if(RB8==1) //若当前接收为地址帧则返回0xff
return 0xff;
date=SBUF;
RI=0;
return date;
}
void main()
{
uchartem=0XFF,Data=0xff;
Uart_Init();
while(1)
{ tem=0XFF;
SM2=1; //只接收地址帧
//如果接收到的地址帧不是本机地址,则继续等待
while(tem!=addr)
{
RI=0;
while(!RI);
tem=SBUF;
RI=0;
}
TI=0; //如果是本机地址,发送应答信号,并做好接受数据的准备
TB8=0; //主机不检测该位
SBUF=addr;
while(!TI);
TI=0;
SM2=0; //允许接受数据信息
//接收数据
Data=recv_data();
if(Data==0xff)
continue;
switch(Data)
{
case 0x01: //在此可以写入要完成的动作,最多可完成256个动作
P1=0x90; //为方便其间,赋值给P1口,测P1口电平来检测该程序
break;
case 0x02:
P2=0xaa; //为方便其间,赋值给P2口,测P1口电平来检测该程序
break;
case 0x03:
break;
case 0x04:
break;
default:
break;
}
}
}