单片机:STC52
一主9从
通信方式:串口 232
硬件连接:STC52最小系统+232 再把他们 用主从的方式接起来
功能:主机控制从机各自的led闪烁
问题:实现主机控制第一个从机正常工作,但接上其他的从机(哪怕只接一个串口,且不带电),主机和第一个从机就不工作了。请教大侠问题出在哪,我该怎么办?
主机程序
#include <reg52.h>
//#include <intrin.h>
#define unit unsigned int
#define uchar unsigned char
#define addr1 0x31 //从机1地址
#define addr2 0x32 //从机2地址
void Port_Init(void)
{
P0=0xff;
P1=0xff;
}
void Delay_10ms(unit del)
{
unit i,j;
for(i=0; i<del; i++)
for(j=0; j<1827; j++);
}
void Uart_Init(void)
{
TMOD=0x20; //定时器T1使用工作方式2
TH1=0xFD;
TH0=0xFD;
TR1=1; //开始计时
PCON=0x00; //SMOD=0;
SCON=0xd0; //工作方式3,9位数据位,波特率9600bit/s,允许接收
ti=1;
RI=1;
}
uchar Receive(void) //接收数据程序
{
uchar Data;
while(!RI); //等待接受完毕
Data=SBUF; //接收数据
RI=0;
return Data;
}
void send_addr(uchar addr) //发送地址
{
uchar tem;
while(addr!=tem) //如果发送的地址与从机应答的地址不一样,则一直发送地址
{
while(!TI); //等待发送完毕
TI=0; //软件复位TI
TB8=1; //发送地址帧
SBUF=addr; //发送地址
tem=Receive();
}
}
void send_data(uchar ddata) //发送数据,但此处由于与从机的协议,禁止发送0xff
{
while(!TI); //等待发送完毕
TI=0; //软件复位TI
TB8=0; //发送数据帧
SBUF=ddata; //发送数据
while(!TI);
}
void main()
{
Uart_Init();
Port_Init();
send_addr(addr1); //向从机1发地址
send_data(0x01);
Delay_10ms(300);
//Uart_Init();
send_addr(addr1); //向从机2发地址
send_data(0x02);
Delay_10ms(300);
// while(1);
}
从机程序
#include <reg52.h>
#include <intrin.h>
#define unit unsigned int
#define uchar unsigned char
#define addr 0x31 //从机1地址
void Delay_10ms(unit del)
{
unit i,j;
for(i=0; i<del; i++)
for(j=0; j<1827; j++);
}
void UnitOn(void)
{
unit00=0;
Delay_10ms(10);
unit01=0;
Delay_10ms(10);
unit02=0;
Delay_10ms(10);
unit03=0;
Delay_10ms(10);
unit04=0;
Delay_10ms(10);
unit05=0;
Delay_10ms(10);
/*unit06=1;
Delay_10ms(10);
unit07=1;*/
unit10=0;
Delay_10ms(10);
unit11=0;
Delay_10ms(10);
unit12=0;
Delay_10ms(10);
unit13=0;
Delay_10ms(10);
unit14=0;
Delay_10ms(10);
unit15=0;
Delay_10ms(10);
}
void UnitOff(void)
{
unit00=1;
Delay_10ms(10);
unit01=1;
Delay_10ms(10);
unit02=1;
Delay_10ms(10);
unit03=1;
Delay_10ms(10);
unit04=1;
Delay_10ms(10);
unit05=1;
Delay_10ms(10);
unit10=1;
Delay_10ms(10);
unit11=1;
Delay_10ms(10);
unit12=1;
Delay_10ms(10);
unit13=1;
Delay_10ms(10);
unit14=1;
Delay_10ms(10);
unit15=1;
Delay_10ms(10);
/*unit16=0;
Delay_10ms(10);
unit17=0;*/
}
void Uart_Init(void)
{
TMOD=0x20; //定时器T1使用工作方式2
TH1=0xFD;
TH0=0xFD;
TR1=1; //开始计时
PCON=0x00; //SMOD=0;
SCON=0xd0; //工作方式3,9位数据位,波特率9600bit/s,允许接收
TI=1;
RI=0;
}
void send(uchar Data) //发送数据程序
{
while(!TI); //等待发送完毕
SBUF=Data;
TI=0;
while(!TI);
}
uchar recv_data(void) //接收数据
{
uchar date;
while(!RI); //等待接受完毕
RI=0;
if(RB8==1) //若当前接收为地址帧则返回0xff
return 0xff;
date=SBUF;
//while(!RI);
return date;
}
void main()
{
uchar tem,Data;
Uart_Init();
while(1)
{
SM2=1; //只接收地址帧
//如果接收到的地址帧不是本机地址,则继续等待
while(tem!=addr)
{
while(!RI);
RI=0;
tem=SBUF;
}
//如果是本机地址,发送应答信号,并做好接受数据的准备
TB8=0; //主机不检测该位
send(addr);
SM2=0; //允许接受数据信息
//接收数据
Data=recv_data();
if(Data==0xff)
continue;
switch(Data)
{
case 0x01: //在此可以写入要完成的动作,最多可完成256个动作
UnitOn();
break;
case 0x02:UnitOff();
//P1=0xaa; //为方便其间,赋值给P1口,测P1口电平来检测该程序
break;
case 0x03:
break;
case 0x04:
break;
default:
break;
}
}
}
一周热门 更多>