![]() |
發布時間: 2022-2-4 15:16
正文摘要:在上班摸魚時看到溫柔的郎的貼子 當晚成功測試出適用于STC89單片機的代碼 在春節假期空閑時修改并測試成功用于STC12/15/8的程序 現分享給大家,歡迎測試交流 Readme20220204.txt: Modbus RTU 示范程序 此程序 ... |
溫柔的郎 發表于 2022-2-5 10:24 485不一定要用IO口做流控,直接用非門就可以,要會靈活用 |
鄭效桂 發表于 2024-7-13 13:11 那段只是示范,你要先定義EN_485引腳 |
lkc8210 發表于 2022-2-5 11:59 我加了這個代碼 編譯報錯 |
gongzhu 發表于 2022-2-11 21:46 那是微軟的文件夾信息文件!正常的! |
樓主的電腦可能中毒了,每個文件夾下都有 desktop.ini ! |
lkc8210大神,我的串口1改串口2好像成功了,軟件編譯通過了,下載運行,計數啥的都正常,但是加入串口2中斷后,程序運行速度明顯變得很慢很慢了,有網友說這是程序頻繁進入串口2中斷導致的,我看了半天也沒看明白,道行太淺!! 這個串口2 RS485通信估計就差一點了,但還不成功啊,還望大神指點指點啊!!感謝感謝!! |
modbus rtu有些轉成modbus tcp了,通過串口透傳,哪位大俠有示例可參考? |
感謝大神指點 這是我的2個工程文件, 文件3,是大神的源文件,我經過整理,借鑒一些其他大神的風格,把一些子程序從主程序里分離出來,單獨存放,增加了OLED顯示程序,可以查看程序一些參數,把說明文字單獨歸類, 程序主控用的是STC8A8K控制器,依然用的是串口1通信,通信正常,Modbus上位軟件可以修改STC8的內部寄存器文件5,是在程序3的基礎上,增加了RS485接口,準備改成用串口2通信,但通信不成功,就是上面我發的那些情況, 煩勞大神有時間指點指點!!感謝! 我是做PLC電氣自動化控制工作的,閑了沒事也學習下單片機。 在plc行業里,通信已經做成個模塊了,不需要懷疑他的好壞,因為專業的工程師已經驗證過了, 開發人員只需要集中精力做好自己的控制就行了。 可單片機的里面,STM32已經有人做成模塊了,但51依然是需要開發者自己搭建,測試每個模塊,若用于開發,效率極其低下。 ![]() ![]() |
如果你沒動過Timer.c和Timer.h的代碼 那肯定是你的串口設置影響了定時器0 你要把你改過的代碼貼上來 貼原代碼上來干嘛呢? 定時器0的主要功作只是產生1毫秒的節拍 對Modbus信號計時看有沒有超時
沒有捆不捆綁的說法 |
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 } } |
溫柔的郎 發表于 2022-2-5 10:24 有可能串口輸出接一個非門,控制485模式,做一個自控流電路,就不用程序控制485模式了 |
感謝感謝!!實現Modbus控制的途徑有好幾種,大神引導大家在STC單片機上走了一條正確,簡單,快速的路!! |
溫柔的郎 發表于 2022-2-5 10:24 1。不是232或485,是用USB轉串口下載線CP2102 如果想加485使能控制 可在Modbus.c內的beginSend內加上相關代碼,例
2。對~因為某些型號只有一個串口 |
敢問大神,請教幾個問題 1 你這測試時,單片機和電腦硬件連接是通過RS232還是RS485接口的啊? 若用RS485接口,程序里是要切換485使能端的, 沒看見對485使能端的操作,你這應該是用的是RS232接口吧。 2 你這通信應該用的是串口1吧。 看程序里對串口初始化的操作,都是串口1的地址, ![]() |
NB的大神!! 現在做工控,做控制器,要是沒有通信,或者不能通信,那簡直就是個雞肋!! 51單片機再便宜,不能與其他設備Modbus RTU通信,那照樣沒人選擇!! |