找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5934|回复: 12
打印 上一主题 下一主题
收起左侧

利用keil+Proteus实现 51单片机的modbus通讯 附源程序

  [复制链接]
跳转到指定楼层
楼主
ID:86450 发表于 2020-6-4 13:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
利用keil proteus 实现 51单片机的modbus通讯https://www.bilibili.com/video/BV1Et4y1y7Sx  录了一个小视频
https://www.bilibili.com/video/BV1Et4y1y7Sx/




//FIRMWARE FOR SLAVE
#include <reg52.h>
#include <intrins.h>

#define Uint16 unsigned int
#define Uint32 unsigned long
#define uchar  unsigned char


//函数定义//
void InitUART(void);
void SendOneByte(unsigned);
void Send(uchar * a,uchar b);
void mdproc(uchar);
Uint16 Crc16(Uint16 *puchMsg, Uint16 usDataLen);
void modbus_read_back();
void modbus_write_back(uchar add , uchar val);
//变量定义
Uint16  temp16;
uchar rx_buff[20];
//灯和开关定义
sbit led1=P3^2;
sbit led2=P3^3;
sbit led3=P3^4;
sbit led4=P3^5;

sbit k0 = P1^0;
sbit k1 = P1^1;
sbit k2 = P1^2;
sbit k3 = P1^3;



/* CRC 高位字节值表 */
const Uint16 code auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;

/* CRC低位字节值表*/
const Uint16 code auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
//主函数
void main(void)
{
        InitUART();
        while(1)
        {        
        }
}


Uint16 Crc16(uchar *puchMsg, Uint16 usDataLen)
{
        Uint16 uchCRCHi = 0xFF ;              /* 高CRC字节初始化  */
        Uint16 uchCRCLo = 0xFF ;              /* 低CRC 字节初始化 */
        Uint16 temp16;
        Uint32 uIndex ;                      /* CRC循环中的索引  */
        while (usDataLen--)                  /* 传输消息缓冲区   */
        {
                temp16=*puchMsg++;
                uIndex = uchCRCHi ^ temp16 ; /* 计算CRC          */
                uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex] ;
                uchCRCLo = auchCRCLo[uIndex] ;
        }
        return (uchCRCHi << 8 | uchCRCLo) ;
}


void Timer0Interrupt(void) interrupt 1
{
    TH0 = 0x3C;
    TL0 = 0x0B0;
}
//串口中断函数
void UARTInterrupt(void) interrupt 4
{
    if(RI)
    {
                RI = 0;
               
                mdproc(SBUF);//处理数据
    }
    else
      TI = 0;
}

void mdproc(uchar b)  
{        
        rx_buff[0] = rx_buff[1];
        rx_buff[1] = rx_buff[2];
        rx_buff[2] = rx_buff[3];
        rx_buff[3] = rx_buff[4];
        rx_buff[4] = rx_buff[5];
        rx_buff[5] = rx_buff[6];
        rx_buff[6] = rx_buff[7];
        rx_buff[7] =         b ;
        
        if((rx_buff[0] == 0x11 ) &&
                        (rx_buff[1] == 0x01) &&
                        (rx_buff[2] == 0x00) &&
                        (rx_buff[3] == 0x13)
                )
        {
                modbus_read_back();//返回本机的状态
        }

        if((rx_buff[0] == 0x11 ) &&
                        (rx_buff[1] == 0x05) &&
                        (rx_buff[2] == 0x00) &&
                        (rx_buff[3] == 0x00)    //控制第一路灯
                )
        {
                        if(rx_buff[4] == 0xff)
                        {
                                modbus_write_back(0,1);        
                                led1 = 1;
                        }
                        else
                        {
                                modbus_write_back(0,0);
                                        led1 = 0;
                        }
        }

                if((rx_buff[0] == 0x11 ) &&
                        (rx_buff[1] == 0x05) &&
                        (rx_buff[2] == 0x00) &&
                        (rx_buff[3] == 0x01)    //控制第二路灯
                )
        {
                        if(rx_buff[4] == 0xff)
                        {
                                modbus_write_back(1,1);        
                                        led2 = 1;
                        }
                        else
                        {
                                modbus_write_back(1,0);
                                        led2 = 0;
                        }
        }
        
        if((rx_buff[0] == 0x11 ) &&
                        (rx_buff[1] == 0x05) &&
                        (rx_buff[2] == 0x00) &&
                        (rx_buff[3] == 0x02)    //控制第三路灯
                )
        {
                        if(rx_buff[4] == 0xff)
                        {
                                modbus_write_back(2,1);        
                                        led3 = 1;
                        }
                        else
                        {
                                modbus_write_back(2,0);
                                        led3= 0;
                        }
        }        
        
        
                if((rx_buff[0] == 0x11 ) &&
                        (rx_buff[1] == 0x05) &&
                        (rx_buff[2] == 0x00) &&
                        (rx_buff[3] == 0x03)    //控制第四路灯
                )
        {
                        if(rx_buff[4] == 0xff)
                        {
                                modbus_write_back(3,1);        
                                        led4 = 1;
                        }
                        else
                        {
                                modbus_write_back(3,0);
                                        led4 = 0;
                        }
        }
}

void SendOneByte(unsigned char c)
{
    SBUF = c;
    while(!TI);
    TI = 0;
}
void Send(uchar * a,uchar b)
{
        uchar i;
        uchar *p;
        p= a;
        for(i=0;i<b;i++)
        {
        SendOneByte (*p);
                p++;
        }
}


void InitUART(void)
{
    TMOD = 0x20;
    SCON = 0x50;
    TH1 = 0xFE;
    TL1 = TH1;
    PCON = 0x00;
    EA = 1;
    ES = 1;
    TR1 = 1;
        
                TMOD |= 0x01;
    TH0 = 0x3C;
    TL0 = 0x0B0;  
    ET0 = 1;
    TR0 = 1;

}


void delay(void)                                                        
{
        _nop_();_nop_();_nop_();_nop_();_nop_();

}

//按照网页的说明发送数据
void modbus_write_back(uchar add , uchar val)
{
uchar buff[8];
buff[0] = 0x11;
buff[1]        = 0x05;
buff[2] = 0x00;
buff[3] = add;
if(val == 1)
{
buff[4] = 0xff;
buff[5] = 0x00;               
}
else
{
buff[4] = 0x00;
buff[5] = 0x00;        
}        
temp16=Crc16(buff,6);
buff[6]         = (temp16>>8)&0x00ff;
buff[7]         = temp16&0x00ff;                        
Send(buff,8);
}
//按照网页的说明发送数据
void modbus_read_back()
{
uchar buff[8];
buff[0] = 0x11;
buff[1]        = 0x01;
buff[2] = 0x01;
buff[3] = P1;
temp16=Crc16(buff,4);
buff[4]         = (temp16>>8)&0x00ff;
buff[5]         = temp16&0x00ff;                        
Send(buff,6);
}
全部资料51hei下载地址:

MODBUS 使用proteus仿真.zip

24.53 KB, 下载次数: 243

用proteus仿真

modbus从机源码4路输入4路输出.zip

54.88 KB, 下载次数: 253

keil源码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:292427 发表于 2020-6-22 21:10 | 只看该作者
牛逼 大神
回复

使用道具 举报

板凳
ID:789645 发表于 2020-6-25 21:19 | 只看该作者
大哥,版本太高打不开啊,不可能我再重新安装一个吧
回复

使用道具 举报

地板
ID:495287 发表于 2020-6-27 13:42 | 只看该作者
马克,谢谢楼主分享,好人一生平安。
回复

使用道具 举报

5#
ID:856085 发表于 2020-12-8 18:48 | 只看该作者
你好大哥,我下了你的keil'+proteus实现moobus通讯附件,程序烧录到板子里,运行之后有虚拟窗口,但是没有协议命令,请教一下为什么
回复

使用道具 举报

6#
ID:862860 发表于 2020-12-20 16:11 | 只看该作者
楼主,为什么我用proteus仿真,虚拟窗口什么都没有显示啊
回复

使用道具 举报

7#
ID:462629 发表于 2021-3-6 21:51 | 只看该作者
是完整正确的版本吗?
回复

使用道具 举报

8#
ID:28992 发表于 2021-3-7 01:28 | 只看该作者
正在學習,謝謝大師!
回复

使用道具 举报

9#
ID:28992 发表于 2021-3-7 01:43 | 只看该作者
download for study, thanks a lot.
回复

使用道具 举报

10#
ID:380987 发表于 2021-3-7 14:32 | 只看该作者
正在學習,謝謝大師! 正在學習,謝謝大師!
回复

使用道具 举报

11#
ID:1017095 发表于 2022-5-17 20:24 来自手机 | 只看该作者
资料是不是不全呀,没有主站的程序
回复

使用道具 举报

12#
ID:18797 发表于 2022-6-9 23:55 | 只看该作者
有没有实际电路中调试成功了的回复?
回复

使用道具 举报

13#
ID:513507 发表于 2023-1-28 15:55 | 只看该作者
没有主站资料,可能调不通的
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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