找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 4778|回復(fù): 16
收起左側(cè)

基于依然王的人Modbus RTU 從機(jī)程序修改的通用版

  [復(fù)制鏈接]
ID:161164 發(fā)表于 2022-2-4 15:16 | 顯示全部樓層 |閱讀模式
在上班摸魚(yú)時(shí)看到溫柔的郎的貼子
當(dāng)晚成功測(cè)試出適用于STC89單片機(jī)的代碼
在春節(jié)假期空閑時(shí)修改并測(cè)試成功用于STC12/15/8的程序
現(xiàn)分享給大家,歡迎測(cè)試交流

Readme20220204.txt:
  1. Modbus RTU 示范程序
  2. 此程序修改后在以下單片機(jī)上測(cè)試通過(guò)
  3. STC89C52RC/STC12C4052AD/STC15W408AS/STC8F1K08/STC8G1K08A
  4. 單片機(jī)要求:Ram >= 256, Code >= 3k
  5. Function 15 設(shè)置多個(gè)線(xiàn)圈不能使用

  6. 通訊設(shè)置:
  7. 波特率:9600(1T單片機(jī)可于System.h中選擇)
  8. 數(shù)據(jù)位:8
  9. 停止位:1
  10. 檢驗(yàn)位:無(wú)

  11. 程序默認(rèn)地址:1  (可以通過(guò)修改Modbus.c: localAddr變量改變地址)
  12. 程序默認(rèn)數(shù)據(jù)長(zhǎng)度:16  (可以通過(guò)修改Modbus.h: RegisterMax變量改變長(zhǎng)度,但要注意生成代碼Ram不可多于256)
  13. 程序默認(rèn)晶振頻率:11.0592M(可以于System.h中選擇)
  14. 程序默認(rèn)單片機(jī):STC89C52RC(可以通過(guò)修改Project.h: MCU_Type選擇單片機(jī)類(lèi)型)
  15. 工程編譯環(huán)境:KeilC V5.14.2.1
復(fù)制代碼

STC15W408AS

STC15W408AS



2022-02-04_145615.png

地址4x00002:閃燈時(shí)間10ms
地址4x00004:閃燈累計(jì)數(shù)


Modbus 8051 Client.rar (184.26 KB, 下載次數(shù): 152)

2022-02-04_151455.png

2022-02-04_151503.png


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:476652 發(fā)表于 2022-2-4 22:56 | 顯示全部樓層
NB的大神!
現(xiàn)在做工控,做控制器,要是沒(méi)有通信,或者不能通信,那簡(jiǎn)直就是個(gè)雞肋!
51單片機(jī)再便宜,不能與其他設(shè)備Modbus RTU通信,那照樣沒(méi)人選擇!!
回復(fù)

使用道具 舉報(bào)

ID:476652 發(fā)表于 2022-2-5 10:24 | 顯示全部樓層
敢問(wèn)大神,請(qǐng)教幾個(gè)問(wèn)題
1 你這測(cè)試時(shí),單片機(jī)和電腦硬件連接是通過(guò)RS232還是RS485接口的啊?
   若用RS485接口,程序里是要切換485使能端的,
  沒(méi)看見(jiàn)對(duì)485使能端的操作,你這應(yīng)該是用的是RS232接口吧。
2 你這通信應(yīng)該用的是串口1吧。
  看程序里對(duì)串口初始化的操作,都是串口1的地址, 51hei截圖_20220205102307.png

回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2022-2-5 11:59 | 顯示全部樓層
溫柔的郎 發(fā)表于 2022-2-5 10:24
敢問(wèn)大神,請(qǐng)教幾個(gè)問(wèn)題
1 你這測(cè)試時(shí),單片機(jī)和電腦硬件連接是通過(guò)RS232還是RS485接口的啊?
   若用RS4 ...

1。不是232或485,是用USB轉(zhuǎn)串口下載線(xiàn)CP2102
如果想加485使能控制
可在Modbus.c內(nèi)的beginSend內(nèi)加上相關(guān)代碼,例
  1. void beginSend(void)
  2. {
  3.         EN_485 = 1;
  4.     UartSendBytes (sendBuf, sendCount);
  5.         EN_485 = 0;
  6. }
復(fù)制代碼


2。對(duì)~因?yàn)槟承┬吞?hào)只有一個(gè)串口
回復(fù)

使用道具 舉報(bào)

ID:476652 發(fā)表于 2022-2-5 16:22 | 顯示全部樓層
感謝感謝!!實(shí)現(xiàn)Modbus控制的途徑有好幾種,大神引導(dǎo)大家在STC單片機(jī)上走了一條正確,簡(jiǎn)單,快速的路。
回復(fù)

使用道具 舉報(bào)

ID:525244 發(fā)表于 2022-2-8 11:43 來(lái)自觸屏版 | 顯示全部樓層
溫柔的郎 發(fā)表于 2022-2-5 10:24
敢問(wèn)大神,請(qǐng)教幾個(gè)問(wèn)題
1 你這測(cè)試時(shí),單片機(jī)和電腦硬件連接是通過(guò)RS232還是RS485接口的。
   若用RS4 ...

有可能串口輸出接一個(gè)非門(mén),控制485模式,做一個(gè)自控流電路,就不用程序控制485模式了
回復(fù)

使用道具 舉報(bào)

ID:476652 發(fā)表于 2022-2-9 15:27 | 顯示全部樓層
NB的lkc8210大神,又來(lái)打擾你了。∧愕某绦蛴玫绞谴1通信,我試著改成串口2通信,但中斷用的定時(shí)器沒(méi)改,依然用的是定時(shí)器0,
改完編譯無(wú)誤,下載進(jìn)芯片,用Modbus Poll軟件通信連接,通信不通,
檢查,測(cè)試后發(fā)現(xiàn)定時(shí)器0中斷不運(yùn)行,這是什么原因。
難道串口1中斷只能用定時(shí)器0嗎?我改成串口2,也得用定時(shí)器2嗎?這是對(duì)應(yīng)捆綁著的嗎?
請(qǐng)大神有時(shí)間指導(dǎo)指導(dǎo)!!
感謝!

定時(shí)器程序如下(串口1通信時(shí)也用的這個(gè)定時(shí)器0)
Timer.c
#include "Project.h"

UINT8        idata c10ms;                        //10ms 計(jì)時(shí)
bit                b1ms,bt1ms,b10ms,bt10ms,b100ms,bt100ms;        //定義定時(shí)標(biāo)志位
//定時(shí)器0初始化
void TimerInit(void)
{
    TMOD = (TMOD & 0XF0) | 0X01;//定時(shí)器0模式配置
    TH0 = TIMER_HIGHT;//定義初始裝載值
    TL0 = TIMER_LOW;//定義初始裝載值
    TR0 = 1;     //定時(shí)器0開(kāi)始計(jì)時(shí)
    ET0 = 1;     //使能定時(shí)器0的溢出中斷允許位
}

//定時(shí)處理//timerProc定時(shí)器0回調(diào)函數(shù)
//在C中,static主要定義全局靜態(tài)變量、定義局部靜態(tài)變量、定義靜態(tài)函數(shù)。
void timerProc(void)
{
    static UINT8 c200ms;
    static UINT8 c1s;

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

    ET0 = 0;//復(fù)位定時(shí)器0溢出中斷允許位
    //dwTickCount = dwIntTick;
    ET0 = 1;//置位定時(shí)器0溢出中斷允許位

    if(bt1ms)
    {                       
        bt1ms = 0;
        b1ms = 1;
        if(receTimeOut>0)//若接收超時(shí)>0
        {
            receTimeOut--;
            if(receTimeOut==0 && receCount>0)   //判斷通訊接收是否超時(shí)
            {
              receCount = 0;    //將接收地址偏移寄存器清零
              checkoutError = 0;//校驗(yàn)錯(cuò)標(biāo)志位復(fù)位                                                       
            }
        }                       
    }

    if(bt100ms)
    {
      bt100ms = 0;
      b100ms = 1;
    }
    if(bt10ms)//判斷中斷10ms標(biāo)志位是否1
    {
      bt10ms = 0; //清中斷10ms標(biāo)志位
      b10ms = 1;

      c200ms++;        //200ms計(jì)時(shí)器加1
        if(c200ms >= 20) //判斷是否計(jì)時(shí)到200ms
          {
            c200ms = 0;  //清200ms計(jì)時(shí)器
          }
      c1s++;           //1s計(jì)時(shí)器加1
        if(c1s >= testRegister[2]) //判斷是否計(jì)時(shí)到1s
        {
          c1s = 0;     //清1s計(jì)時(shí)器
                                        testCoil[0]++;
                                        testRegister[4]++;
//                                        P14 ^= 1;
        }
    }
}

//定時(shí)器0 1ms 中斷
void timer0IntProc() interrupt 1
{
    TL0 = TIMER_LOW;
    TH0 = TIMER_HIGHT;
    //dwIntTick++;
    bt1ms = 1;//設(shè)bt1ms初值=1
    c10ms++;  //c10ms自+1
    if(c10ms >= 10)//如果c10ms>=10
    {
      c10ms = 0; //把c10ms計(jì)時(shí)器清零
      bt10ms = 1;//把bt10ms置1
    }
       
}


回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2022-2-10 09:31 | 顯示全部樓層
如果你沒(méi)動(dòng)過(guò)Timer.c和Timer.h的代碼
那肯定是你的串口設(shè)置影響了定時(shí)器0

你要把你改過(guò)的代碼貼上來(lái)
貼原代碼上來(lái)干嘛呢?

定時(shí)器0的主要功作只是產(chǎn)生1毫秒的節(jié)拍
對(duì)Modbus信號(hào)計(jì)時(shí)看有沒(méi)有超時(shí)
  1.    
  2.         if(bt1ms)
  3.     {                       
  4.         bt1ms = 0;
  5.         b1ms = 1;
  6.         if(receTimeOut>0)//若接收超時(shí)>0
  7.         {
  8.             receTimeOut--;
  9.             if(receTimeOut==0 && receCount>0)   //判斷通訊接收是否超時(shí)
  10.             {
  11.               receCount = 0;    //將接收地址偏移寄存器清零
  12.               checkoutError = 0;//校驗(yàn)錯(cuò)標(biāo)志位復(fù)位                                                      
  13.             }
  14.         }                       
  15.     }
復(fù)制代碼

沒(méi)有捆不捆綁的說(shuō)法
回復(fù)

使用道具 舉報(bào)

ID:476652 發(fā)表于 2022-2-10 11:14 | 顯示全部樓層
感謝大神指點(diǎn)
這是我的2個(gè)工程文件,
文件3,是大神的源文件,我經(jīng)過(guò)整理,借鑒一些其他大神的風(fēng)格,把一些子程序從主程序里分離出來(lái),單獨(dú)存放,增加了OLED顯示程序,可以查看程序一些參數(shù),把說(shuō)明文字單獨(dú)歸類(lèi),
程序主控用的是STC8A8K控制器,依然用的是串口1通信,通信正常,Modbus上位軟件可以修改STC8的內(nèi)部寄存器文件5,是在程序3的基礎(chǔ)上,增加了RS485接口,準(zhǔn)備改成用串口2通信,但通信不成功,就是上面我發(fā)的那些情況,
煩勞大神有時(shí)間指點(diǎn)指點(diǎn)。「兄x!
我是做PLC電氣自動(dòng)化控制工作的,閑了沒(méi)事也學(xué)習(xí)下單片機(jī)。
在plc行業(yè)里,通信已經(jīng)做成個(gè)模塊了,不需要懷疑他的好壞,因?yàn)閷?zhuān)業(yè)的工程師已經(jīng)驗(yàn)證過(guò)了,
開(kāi)發(fā)人員只需要集中精力做好自己的控制就行了。
可單片機(jī)的里面,STM32已經(jīng)有人做成模塊了,但51依然是需要開(kāi)發(fā)者自己搭建,測(cè)試每個(gè)模塊,若用于開(kāi)發(fā),效率極其低下。
Modbus Client3.rar (195.5 KB, 下載次數(shù): 37) Modbus Client5.rar (198.49 KB, 下載次數(shù): 31)

回復(fù)

使用道具 舉報(bào)

ID:137005 發(fā)表于 2022-2-11 08:28 | 顯示全部樓層
modbus rtu有些轉(zhuǎn)成modbus tcp了,通過(guò)串口透?jìng),哪位大俠有示例可參考?
回復(fù)

使用道具 舉報(bào)

ID:476652 發(fā)表于 2022-2-11 12:48 | 顯示全部樓層
lkc8210大神,我的串口1改串口2好像成功了,軟件編譯通過(guò)了,下載運(yùn)行,計(jì)數(shù)啥的都正常,但是加入串口2中斷后,程序運(yùn)行速度明顯變得很慢很慢了,有網(wǎng)友說(shuō)這是程序頻繁進(jìn)入串口2中斷導(dǎo)致的,我看了半天也沒(méi)看明白,道行太淺!!
這個(gè)串口2 RS485通信估計(jì)就差一點(diǎn)了,但還不成功啊,還望大神指點(diǎn)指點(diǎn)。!感謝感謝!
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2022-2-11 14:15 | 顯示全部樓層
溫柔的郎 發(fā)表于 2022-2-10 11:14
感謝大神指點(diǎn)
這是我的2個(gè)工程文件,
文件3,是大神的源文件,我經(jīng)過(guò)整理,借鑒一些其他大神的風(fēng)格,把一 ...

看了一下你的串口2相關(guān)代碼
有很多錯(cuò)處

串口2的寄存器不是位于位可尋的地址
所以位操作串口2的寄存器的時(shí)候要用"&","|","~"等運(yùn)算子

不同的串口有不同的中斷數(shù),詳情請(qǐng)看手冊(cè)

STP-ISP軟件里已經(jīng)有串口2用定時(shí)器2的例程
照著設(shè)定就可以

以下是錯(cuò)處截圖
Uart.c
2022-02-11_140747.png

2022-02-11_140759.png

2022-02-11_140805.png


Uart.h
2022-02-11_140820.png


我手上沒(méi)STC8A, 你照著改看看有沒(méi)有問(wèn)題

回復(fù)

使用道具 舉報(bào)

ID:90212 發(fā)表于 2022-2-11 21:46 | 顯示全部樓層
樓主的電腦可能中毒了,每個(gè)文件夾下都有 desktop.ini !
回復(fù)

使用道具 舉報(bào)

ID:99525 發(fā)表于 2022-2-12 17:03 | 顯示全部樓層
gongzhu 發(fā)表于 2022-2-11 21:46
樓主的電腦可能中毒了,每個(gè)文件夾下都有 desktop.ini !

那是微軟的文件夾信息文件!正常的!
回復(fù)

使用道具 舉報(bào)

ID:1104510 發(fā)表于 2024-7-13 13:11 | 顯示全部樓層
lkc8210 發(fā)表于 2022-2-5 11:59
1。不是232或485,是用USB轉(zhuǎn)串口下載線(xiàn)CP2102
如果想加485使能控制
可在Modbus.c內(nèi)的beginSend內(nèi)加上相 ...

我加了這個(gè)代碼   編譯報(bào)錯(cuò)
回復(fù)

使用道具 舉報(bào)

ID:161164 發(fā)表于 2024-7-13 23:19 | 顯示全部樓層
鄭效桂 發(fā)表于 2024-7-13 13:11
我加了這個(gè)代碼   編譯報(bào)錯(cuò)

那段只是示范,你要先定義EN_485引腳
回復(fù)

使用道具 舉報(bào)

ID:492633 發(fā)表于 2024-7-28 19:07 來(lái)自觸屏版 | 顯示全部樓層
溫柔的郎 發(fā)表于 2022-2-5 10:24
敢問(wèn)大神,請(qǐng)教幾個(gè)問(wèn)題
1 你這測(cè)試時(shí),單片機(jī)和電腦硬件連接是通過(guò)RS232還是RS485接口的?
   若用RS4 ...

485不一定要用IO口做流控,直接用非門(mén)就可以,要會(huì)靈活用
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表