找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2456|回复: 13
收起左侧

基于依然王的人Modbus RTU 从机程序修改的通用版

  [复制链接]
ID:161164 发表于 2022-2-4 15:16 | 显示全部楼层 |阅读模式
在上班摸鱼时看到温柔的郎的贴子
当晚成功测试出适用于STC89单片机的代码
在春节假期空闲时修改并测试成功用于STC12/15/8的程序
现分享给大家,欢迎测试交流

Readme20220204.txt:
  1. Modbus RTU 示范程序
  2. 此程序修改后在以下单片机上测试通过
  3. STC89C52RC/STC12C4052AD/STC15W408AS/STC8F1K08/STC8G1K08A
  4. 单片机要求:Ram >= 256, Code >= 3k
  5. Function 15 设置多个线圈不能使用

  6. 通讯设置:
  7. 波特率:9600(1T单片机可于System.h中选择)
  8. 数据位:8
  9. 停止位:1
  10. 检验位:无

  11. 程序默认地址:1  (可以通过修改Modbus.c: localAddr变量改变地址)
  12. 程序默认数据长度:16  (可以通过修改Modbus.h: RegisterMax变量改变长度,但要注意生成代码Ram不可多于256)
  13. 程序默认晶振频率:11.0592M(可以于System.h中选择)
  14. 程序默认单片机:STC89C52RC(可以通过修改Project.h: MCU_Type选择单片机类型)
  15. 工程编译环境:KeilC V5.14.2.1
复制代码

STC15W408AS

STC15W408AS



2022-02-04_145615.png

地址4x00002:闪灯时间10ms
地址4x00004:闪灯累计数


Modbus 8051 Client.rar (184.26 KB, 下载次数: 112)

评分

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

查看全部评分

回复

使用道具 举报

ID:476652 发表于 2022-2-4 22:56 | 显示全部楼层
NB的大神!!
现在做工控,做控制器,要是没有通信,或者不能通信,那简直就是个鸡肋!!
51单片机再便宜,不能与其他设备Modbus RTU通信,那照样没人选择!!
回复

使用道具 举报

ID:476652 发表于 2022-2-5 10:24 | 显示全部楼层
敢问大神,请教几个问题
1 你这测试时,单片机和电脑硬件连接是通过RS232还是RS485接口的啊?
   若用RS485接口,程序里是要切换485使能端的,
  没看见对485使能端的操作,你这应该是用的是RS232接口吧。
2 你这通信应该用的是串口1吧。
  看程序里对串口初始化的操作,都是串口1的地址, 51hei截图_20220205102307.png

回复

使用道具 举报

ID:161164 发表于 2022-2-5 11:59 | 显示全部楼层
温柔的郎 发表于 2022-2-5 10:24
敢问大神,请教几个问题
1 你这测试时,单片机和电脑硬件连接是通过RS232还是RS485接口的啊?
   若用RS4 ...

1。不是232或485,是用USB转串口下载线CP2102
如果想加485使能控制
可在Modbus.c内的beginSend内加上相关代码,例
  1. void beginSend(void)
  2. {
  3.         EN_485 = 1;
  4.     UartSendBytes (sendBuf, sendCount);
  5.         EN_485 = 0;
  6. }
复制代码


2。对~因为某些型号只有一个串口
回复

使用道具 举报

ID:476652 发表于 2022-2-5 16:22 | 显示全部楼层
感谢感谢!!实现Modbus控制的途径有好几种,大神引导大家在STC单片机上走了一条正确,简单,快速的路!!
回复

使用道具 举报

ID:525244 发表于 2022-2-8 11:43 来自手机 | 显示全部楼层
温柔的郎 发表于 2022-2-5 10:24
敢问大神,请教几个问题
1 你这测试时,单片机和电脑硬件连接是通过RS232还是RS485接口的啊?
   若用RS4 ...

有可能串口输出接一个非门,控制485模式,做一个自控流电路,就不用程序控制485模式了
回复

使用道具 举报

ID:476652 发表于 2022-2-9 15:27 | 显示全部楼层
NB的lkc8210大神,又来打扰你了!!你的程序用到是串口1通信,我试着改成串口2通信,但中断用的定时器没改,依然用的是定时器0,
改完编译无误,下载进芯片,用Modbus Poll软件通信连接,通信不通,
检查,测试后发现定时器0中断不运行,这是什么原因啊?
难道串口1中断只能用定时器0吗?我改成串口2,也得用定时器2吗?这是对应捆绑着的吗?
请大神有时间指导指导!!
感谢!!

定时器程序如下(串口1通信时也用的这个定时器0)
Timer.c
#include "Project.h"

UINT8        idata c10ms;                        //10ms 计时
bit                b1ms,bt1ms,b10ms,bt10ms,b100ms,bt100ms;        //定义定时标志位
//定时器0初始化
void TimerInit(void)
{
    TMOD = (TMOD & 0XF0) | 0X01;//定时器0模式配置
    TH0 = TIMER_HIGHT;//定义初始装载值
    TL0 = TIMER_LOW;//定义初始装载值
    TR0 = 1;     //定时器0开始计时
    ET0 = 1;     //使能定时器0的溢出中断允许位
}

//定时处理//timerProc定时器0回调函数
//在C中,static主要定义全局静态变量、定义局部静态变量、定义静态函数。
void timerProc(void)
{
    static UINT8 c200ms;
    static UINT8 c1s;

    b1ms = 0;
    b10ms = 0;
    b100ms = 0;

    ET0 = 0;//复位定时器0溢出中断允许位
    //dwTickCount = dwIntTick;
    ET0 = 1;//置位定时器0溢出中断允许位

    if(bt1ms)
    {                       
        bt1ms = 0;
        b1ms = 1;
        if(receTimeOut>0)//若接收超时>0
        {
            receTimeOut--;
            if(receTimeOut==0 && receCount>0)   //判断通讯接收是否超时
            {
              receCount = 0;    //将接收地址偏移寄存器清零
              checkoutError = 0;//校验错标志位复位                                                       
            }
        }                       
    }

    if(bt100ms)
    {
      bt100ms = 0;
      b100ms = 1;
    }
    if(bt10ms)//判断中断10ms标志位是否1
    {
      bt10ms = 0; //清中断10ms标志位
      b10ms = 1;

      c200ms++;        //200ms计时器加1
        if(c200ms >= 20) //判断是否计时到200ms
          {
            c200ms = 0;  //清200ms计时器
          }
      c1s++;           //1s计时器加1
        if(c1s >= testRegister[2]) //判断是否计时到1s
        {
          c1s = 0;     //清1s计时器
                                        testCoil[0]++;
                                        testRegister[4]++;
//                                        P14 ^= 1;
        }
    }
}

//定时器0 1ms 中断
void timer0IntProc() interrupt 1
{
    TL0 = TIMER_LOW;
    TH0 = TIMER_HIGHT;
    //dwIntTick++;
    bt1ms = 1;//设bt1ms初值=1
    c10ms++;  //c10ms自+1
    if(c10ms >= 10)//如果c10ms>=10
    {
      c10ms = 0; //把c10ms计时器清零
      bt10ms = 1;//把bt10ms置1
    }
       
}


回复

使用道具 举报

ID:161164 发表于 2022-2-10 09:31 | 显示全部楼层
如果你没动过Timer.c和Timer.h的代码
那肯定是你的串口设置影响了定时器0

你要把你改过的代码贴上来
贴原代码上来干嘛呢?

定时器0的主要功作只是产生1毫秒的节拍
对Modbus信号计时看有没有超时
  1.    
  2.         if(bt1ms)
  3.     {                       
  4.         bt1ms = 0;
  5.         b1ms = 1;
  6.         if(receTimeOut>0)//若接收超时>0
  7.         {
  8.             receTimeOut--;
  9.             if(receTimeOut==0 && receCount>0)   //判断通讯接收是否超时
  10.             {
  11.               receCount = 0;    //将接收地址偏移寄存器清零
  12.               checkoutError = 0;//校验错标志位复位                                                      
  13.             }
  14.         }                       
  15.     }
复制代码

没有捆不捆绑的说法
回复

使用道具 举报

ID:476652 发表于 2022-2-10 11:14 | 显示全部楼层
感谢大神指点
这是我的2个工程文件,
文件3,是大神的源文件,我经过整理,借鉴一些其他大神的风格,把一些子程序从主程序里分离出来,单独存放,增加了OLED显示程序,可以查看程序一些参数,把说明文字单独归类,
程序主控用的是STC8A8K控制器,依然用的是串口1通信,通信正常,Modbus上位软件可以修改STC8的内部寄存器文件5,是在程序3的基础上,增加了RS485接口,准备改成用串口2通信,但通信不成功,就是上面我发的那些情况,
烦劳大神有时间指点指点!!感谢!
我是做PLC电气自动化控制工作的,闲了没事也学习下单片机。
在plc行业里,通信已经做成个模块了,不需要怀疑他的好坏,因为专业的工程师已经验证过了,
开发人员只需要集中精力做好自己的控制就行了。
可单片机的里面,STM32已经有人做成模块了,但51依然是需要开发者自己搭建,测试每个模块,若用于开发,效率极其低下。
Modbus Client3.rar (195.5 KB, 下载次数: 21)
回复

使用道具 举报

ID:137005 发表于 2022-2-11 08:28 | 显示全部楼层
modbus rtu有些转成modbus tcp了,通过串口透传,哪位大侠有示例可参考?
回复

使用道具 举报

ID:476652 发表于 2022-2-11 12:48 | 显示全部楼层
lkc8210大神,我的串口1改串口2好像成功了,软件编译通过了,下载运行,计数啥的都正常,但是加入串口2中断后,程序运行速度明显变得很慢很慢了,有网友说这是程序频繁进入串口2中断导致的,我看了半天也没看明白,道行太浅!!
这个串口2 RS485通信估计就差一点了,但还不成功啊,还望大神指点指点啊!!感谢感谢!!
回复

使用道具 举报

ID:161164 发表于 2022-2-11 14:15 | 显示全部楼层
温柔的郎 发表于 2022-2-10 11:14
感谢大神指点
这是我的2个工程文件,
文件3,是大神的源文件,我经过整理,借鉴一些其他大神的风格,把一 ...

看了一下你的串口2相关代码
有很多错处

串口2的寄存器不是位于位可寻的地址
所以位操作串口2的寄存器的时候要用"&","|","~"等运算子

不同的串口有不同的中断数,详情请看手册

STP-ISP软件里已经有串口2用定时器2的例程
照着设定就可以

以下是错处截图
Uart.c
2022-02-11_140747.png

2022-02-11_140759.png

2022-02-11_140805.png


Uart.h
2022-02-11_140820.png


我手上没STC8A, 你照着改看看有没有问题

回复

使用道具 举报

ID:90212 发表于 2022-2-11 21:46 | 显示全部楼层
楼主的电脑可能中毒了,每个文件夹下都有 desktop.ini !
回复

使用道具 举报

ID:99525 发表于 2022-2-12 17:03 | 显示全部楼层
gongzhu 发表于 2022-2-11 21:46
楼主的电脑可能中毒了,每个文件夹下都有 desktop.ini !

那是微软的文件夹信息文件!正常的!
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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