找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2368|回复: 8
收起左侧

关于51单片机利用rs485进行多机通信的问题

[复制链接]
ID:508562 发表于 2019-11-14 13:31 | 显示全部楼层 |阅读模式
我现在发送端发送地址,接收端能收到,但是收到地址后就无法执行后面的操作了,麻烦给位帮我看看(程序是从网上找的例程小改了下,只改了几个端口定义)
发送端:
#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit LED1 = P3^4;
sbit LED2 = P3^5;
sbit MCU1 = P2^2;
sbit MCU2 = P2^3;
sbit rs485dir = P3^2;

uchar code tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x77,0x7c};

uchar keyscan(void);
void delayms(uint t);
void init_serial(void);
void SBUFSend(uchar key);
void senddat(uchar addr,uchar dat);
void display(uchar addr,uchar dat);

/*************************************************************************/
/******************************按键扫描函数*******************************/
/*************************************************************************/

uchar keyscan(void)
{
        uchar temp,key;
        P0 = 0xfe;
        temp = P0;
        temp = temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);
                if(temp!=0xf0)
                {
                        temp = P0;
                        switch(temp)
                        {
                                case 0xee:        key = 0;        break;
                                case 0xde:        key = 1;        break;
                                case 0xbe:        key = 3;        break;
                                case 0x7e:        key = 4;        break;
                        }
                        while(temp!=0xf0)
                        {
                                temp = P0;
                                temp = temp&0xf0;
                        }
                }
        }
        P0 = 0xfd;
        temp = P0;
        temp = temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);
                if(temp!=0xf0)
                {
                         temp = P0;
                         switch(temp)
                         {
                                 case 0xed:        key = 4;        break;
                                case 0xdd:        key = 5;        break;
                                case 0xbd:        key = 6;        break;
                                case 0x7d:        key = 7;        break;
                         }
                         while(temp!=0xf0)
                         {
                                 temp = P0;
                                temp = temp&0xf0;
                         }
                }
        }
        P0 = 0xfb;
        temp = P0;
        temp = temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);
                if(temp!=0xf0)
                {
                        temp = P0;
                        switch(temp)
                        {
                                case 0xeb:        key = 8;        break;
                                case 0xdb:        key = 9;        break;
                                case 0xbb:        key = 10;        break;
                                case 0x7b:        key = 11;        break;
                        }
                        while(temp!=0xf0)
                        {
                                temp = P0;
                                temp = temp&0xf0;
                        }
                }  
        }
        P0 = 0xf7;
        temp = P0;
        temp = temp&0xf0;
        if(temp!=0xf0)
        {
                delayms(10);
                if(temp!=0xf0)
                {
                        temp = P0;
                        switch(temp)
                        {
                                case 0xe7:        key = 12;        break;
                                case 0xd7:        key = 13;        break;
                                case 0xb7:        key = 13;        break;
                                case 0x77:        key = 15;        break;
                        }
                        while(temp!=0xf0)
                        {
                                temp = P0;
                                temp = temp&0xf0;
                        }
                }
        }
        return key;
}
                  
/*************************************************************************/
/******************************毫秒延时函数*******************************/
/*************************************************************************/

void delayms(uint t)
{
        uchar i,j;
        for(i=0;i<t;i++)
                for(j=0;j<110;j++);
}

/*************************************************************************/
/********************定时器串口寄存器初始化函数***************************/
/*************************************************************************/

void init_serial(void)
{
        TMOD = 0x20;
        TH1 = 0xfa;
        TL1 = 0xfa;
        PCON = 0x80;
        SCON = 0x50;
        TR1 = 1;
        ES = 1;
        EA = 1;
        rs485dir = 1;
}
                                                                                                         
/*************************************************************************/
/******************************信息发送函数*******************************/
/*************************************************************************/

void SBUFSend(uchar key)
{
        SBUF = key;
        while(TI ==0);
        TI = 0;
}
                          
/*************************************************************************/
/****************************发送地址数据函数*****************************/
/*************************************************************************/

void senddat(uchar addr,uchar dat)
{
        TB8 = 1;
        SBUFSend(addr);
        delayms(1);
        TB8 = 0;
        SBUFSend(dat);
        delayms(1);        
}
                                                                  
/*************************************************************************/
/*****************************数码管显示函数******************************/
/*************************************************************************/

void display(uchar addr,uchar dat)
{
        P1 = tab[addr];                /*显示发送的地址*/
        LED1 = 0;
        LED2 = 1;
        delayms(1000);
        P1 = 0x00;
        P1 = tab[dat];                /*显示发送的数据*/
        LED1 = 1;
        LED2 = 0;
        delayms(1000);
        P1 = 0x00;
}

void main()
{                           
        char addr,dat;        
        init_serial();
        dat = keyscan();
        while(1)
        {
                if(MCU1==0)
                {
                        addr = 1;
                        dat = keyscan();
                        senddat(1,dat);
                        display(1,dat);
                }
                if(MCU2==0)
                {
                        addr = 2;
                        dat = keyscan();
                        senddat(2,dat);
                        senddat(2,dat);
                }
        }
}

void serial_init()        interrupt 4
{
        if(RI==1)
                RI = 0;
        if(TI==1)
                TI = 0;
}

接收端:
#include <reg52.h>

#define uchar unsigned char

sbit LED1 = P1^0;
sbit LED2 = P1^1;

uchar DispCode[16] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};

void SerialInit()
{
        SCON = 0xf0;
        PCON = 0x00;
        TMOD = 0x20;
        TH1 = 0xfd;
        TH1 = 0xfd;
        TR1 = 1;
        ES = 1;
        EA = 1;
}

void SBUFSend(uchar Ch)
{
        SBUF = Ch;
        while(TI==0);
        TI = 0;
}

void main()
{
        P2 = 0xff;
        SerialInit();
        while(1);
}

void SerialServer()        interrupt 4
{
        uchar Ch;
        if(RI == 1)
        {
                uchar i;
                RI = 0;
                Ch = SBUF;
                if(RB8 == 1)
                {
                        if(Ch==1)
                        {
                                SM2 = 0;
                                SBUFSend(1);
                                LED1 = 0;
                                LED2 = 1;
                                for(i=500;i>0;i--)
                                        P2 = DispCode[Ch];
                        }
                        else
                        {
                                SM2 = 1;
                        }
                }
                if(RB8 == 0)
                {
                        P2 = 0xff;
                        LED1 = 1;
                        LED2 = 0;
                        for(i=500;i>0;i--)
                                P2 = DispCode[Ch];
                        SM2 = 1;
                }
        }
}

回复

使用道具 举报

ID:640671 发表于 2019-11-14 20:47 | 显示全部楼层
把主机发送数据改在收到分机应答后再发送
回复

使用道具 举报

ID:508562 发表于 2019-11-15 10:15 | 显示全部楼层
faiwong 发表于 2019-11-14 20:47
把主机发送数据改在收到分机应答后再发送

必须验证地址后才能再发送数据么?那后面发送完数据后是不是也还要在验证?
回复

使用道具 举报

ID:508562 发表于 2019-11-15 10:21 | 显示全部楼层
faiwong 发表于 2019-11-14 20:47
把主机发送数据改在收到分机应答后再发送

void senddat(uchar addr,uchar dat)
{
        TB8 = 1;
        SBUFSend(addr);
        rs485dir = 0;
        while(!RI);
        RI = 0;
        rs485dir = 1;
        TB8 = 0;
        SBUFSend(dat);       
}
吧这个数据发送函数改成了这样还是不行啊
回复

使用道具 举报

ID:93224 发表于 2019-11-15 18:48 | 显示全部楼层
RS485通讯这一部分我比较擅长,可以加我QQ详细教你下
回复

使用道具 举报

ID:123289 发表于 2019-11-16 09:10 | 显示全部楼层
先弄清楚通讯原理,再构思出通讯的协议,而后再写程序才靠谱。
回复

使用道具 举报

ID:508562 发表于 2019-11-18 10:51 | 显示全部楼层
yzwzfyz 发表于 2019-11-16 09:10
先弄清楚通讯原理,再构思出通讯的协议,而后再写程序才靠谱。

通信原理知道哈, 第一次些 细节肯定没法都注意到,所以才会找例程这样学习才是最快的,啥都自己摸索有些东西没有那个思维很难解决,我在这提问肯定是遇到了自己无法解决的问题,别老是觉得什么都很轻松一样靠自学都行,要是这样了师傅下岗得了,学生只要发本教材自己学就可以了
回复

使用道具 举报

ID:508562 发表于 2019-11-18 10:52 | 显示全部楼层
faiwong 发表于 2019-11-14 20:47
把主机发送数据改在收到分机应答后再发送

亲,有没有完整能用的例程给小弟一下,万分 感谢
回复

使用道具 举报

ID:508562 发表于 2019-11-18 11:59
lele5211314 发表于 2019-11-15 18:48
RS485通讯这一部分我比较擅长,可以加我QQ详细教你下

你QQ多少

ID:640671 发表于 2019-11-19 15:20 | 显示全部楼层
tomli561 发表于 2019-11-15 10:21
void senddat(uchar addr,uchar dat)
{
        TB8 = 1;


faiwong 发表于 2019-11-14 20:47
把主机发送数据改在收到分机应答后再发送

void senddat(uchar addr,uchar dat)
{
        TB8 = 1;
        SBUFSend(addr);
        while(!TI);
        TI=0;
        rs485dir = 0;
        while(!RI);
        RI = 0;
        rs485dir = 1;
        TB8 = 0;
        SBUFSend(dat);        
}
这样试试,要让CPU数据发送完毕才 rs485dir = 0;不然你的数据送不到485总线上
正常情况不建议用  while(!RI);
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表