请教大侠 51 多机通信(rs232)问题 在线等待大侠的回复

2019-07-15 20:32发布

单片机: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;
        }   
    }
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。