久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6520|回復: 12
打印 上一主題 下一主題
收起左側

我的ModBus主機-調度篇

  [復制鏈接]
跳轉到指定樓層
樓主
ID:446156 發表于 2021-11-15 13:29 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
開始本篇之前我想先談一下為什么要把一個ModBus主機分成4篇來寫,一是代碼的分層理念,隨著工作時間的增長以及工作的深入你會發現分層是那么的至關重要不僅僅是代碼的可讀性更重要的是更方便的維護。初期寫代碼一個文件中甚至一個函數中既有功能代碼又有底層代碼,當增刪功能或者平臺移植的時候都不知道去哪里哭,分層也許在初期會增加代碼量顯得很麻煩但是當你的架構建立起來之后會變得十分方便,解決問題得心應手。操作系統幫你做好了底層的分層和軟件層面的任務調度,但是應用層面依然需要個人來做好。分層理念需要時時有處處有。二是ModBus的一對多特性,當一個主機任務讀取某個從機的數據并等待從機應答時,必須保證別的主機任務不要來動ModBus總線,如果有個不長眼的主機任務過來咔咔操作了總線那么之前等待從機應答的任務就崩潰了。可能有人說了等待應答的時候我直接while死等不就行了,直接斷了別的主機任務的念想,當然這樣是可以解決問題的不過要是某個從機不在線就會導致整個系統卡死一段時間,要是你用了操作系統還好如果是裸機那就非常影響用戶體驗并且會使其他任務比如刷屏按鍵出現一些莫名其妙的問題,我們都知道人的新陳代謝越快身體越強壯,同樣任務輪詢越快系統也越強壯。無論你使用操作系統還是裸機都要避免使用阻塞式的寫法。所以我們才大費周章分4層來解決一個ModBus主機問題。本篇調度篇內容很少但是整個ModBus主機系統的重中之重。
我們先來看代碼。
  1. #ifndef __RS485_H
  2. #define __RS485_H

  3. #include "Header.h"
  4. #include "THP.h"
  5. #include "EPC.h"
  6. #include "Delay.h"

  7. extern uint16_t RS485BusSilentTime1;

  8. void RS485Device1Init(void);
  9. void RS485Device1Handle(void);

  10. #endif
復制代碼
  1. #include "RS485Device.h"

  2. uint16_t RS485BusSilentTime1;

  3. void RS485Device1Init(void)
  4. {
  5.         THPInit();
  6.         EPCInit();
  7. }

  8. static uint8_t TaskHandle(uint8_t En, uint8_t (*Task)(void*), void *Dev, uint8_t *BusTake, uint8_t TaskID, uint16_t *DelayTime)
  9. {
  10.         if((En!=0) && ((*BusTake==0)||(*BusTake==TaskID)))
  11.         {
  12.                 if(Task(Dev) != 0)
  13.                 {
  14.                         /*釋放總線*/
  15.                         *BusTake = 0;
  16.                         Set_Delay_Time(10,DelayTime);
  17.                 }
  18.                 else
  19.                 {
  20.                         /*占用總線*/
  21.                         *BusTake = TaskID;
  22.                         return 1;
  23.                 }
  24.         }
  25.         return 0;
  26. }
  27. void RS485Device1Handle(void)
  28. {
  29.         static uint8_t BusTake=0;
  30.        
  31.         if(CheckDelay(&RS485BusSilentTime1) == 0)
  32.         {
  33.                 if(TaskHandle(EPC1.S_P_En,SetPreVal,&EPC1,&BusTake,1,&RS485BusSilentTime1) != 0)
  34.                 {
  35.                         return;
  36.                 }
  37.                 if(TaskHandle(THP1.Enable,ReadTHP,&THP1,&BusTake,2,&RS485BusSilentTime1) != 0)
  38.                 {
  39.                         return;
  40.                 }
  41.                 if(TaskHandle(EPC1.R_En,ReadEPC,&EPC1,&BusTake,3,&RS485BusSilentTime1) != 0)
  42.                 {
  43.                         return;
  44.                 }
  45.         }
  46. }
復制代碼
通過代碼可以看到該層引用了任務篇創建的"THP.h"和"EPC.h",在這里我們要對三個主機任務進行調度。
首先來看函數“static uint8_t TaskHandle(uint8_t En, uint8_t (Task)(void), void *Dev, uint8_t *BusTake, uint8_t TaskID, uint16_t *DelayTime)”;
該函數參數比較多,分別為任務使能信號(uint8_t En)、任務主體(uint8_t (Task)(void))、設備名稱(void *Dev)、是誰在使用總線(uint8_t *BusTake)、任務編號(uint8_t TaskID)、總線靜默時間控制(uint16_t *DelayTime);
該函數邏輯很簡單,就是判斷任務使能信號是否置位了并查看總線被哪個任務占用,若總線空閑或者被自己占用就去占用總線去執行任務主體函數,若任務主體函數返回0說明正在等待從機應答接著占用總線并返回1告知調度器我還沒用完,否則說明任務完成了釋放總線并給總線插入10ms的靜默時間然后返回0告訴調度器我完事了讓別人來吧。
函數“void RS485Device1Handle(void)”就是最終的調度器它在main函數的while循環中被執行,它首先實現10ms的總線靜默然后挨個詢問主機任務的當前狀態并滿足他們的需求。
至此,我的ModBus主機就完結了。



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏14 分享淘帖 頂2 踩
回復

使用道具 舉報

沙發
ID:939553 發表于 2021-11-20 09:49 | 只看該作者
謝謝分享,能否提供一些關于分層的思想的文章,學習。
回復

使用道具 舉報

板凳
ID:1005484 發表于 2022-2-16 21:05 | 只看該作者

謝謝分享,能否提供一些關于分層的思想的文章,學習。
回復

使用道具 舉報

地板
ID:97078 發表于 2022-3-9 08:33 | 只看該作者
mark,標記學習下
回復

使用道具 舉報

5#
ID:1012071 發表于 2022-3-21 22:25 | 只看該作者
mark,標記學習下
回復

使用道具 舉報

6#
ID:195496 發表于 2022-5-7 14:38 | 只看該作者
上的操作系統?
回復

使用道具 舉報

7#
ID:434978 發表于 2022-5-20 12:10 | 只看該作者
謝謝分享,能否提供一些關于分層的思想的文章,學習
回復

使用道具 舉報

8#
ID:1056996 發表于 2022-12-11 15:36 | 只看該作者
mark,標記學習下
回復

使用道具 舉報

9#
ID:821429 發表于 2023-4-16 09:43 | 只看該作者
,標記學習一下,感謝分享
回復

使用道具 舉報

10#
ID:27536 發表于 2023-5-12 16:42 | 只看該作者

mark,標記學習下
回復

使用道具 舉報

11#
ID:1045571 發表于 2023-8-6 14:58 | 只看該作者
moubus在工作中我遇到了,也看了大概的基本原理,但程序寫不出來,借鑒一下樓主的
回復

使用道具 舉報

12#
ID:939553 發表于 2023-8-15 14:34 來自手機 | 只看該作者
思路清晰,程序扎實
回復

使用道具 舉報

13#
ID:446156 發表于 2024-10-30 16:59 | 只看該作者

裸機,我自己的框架
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产乱码精品一区二区三区中文 | 日韩成人一区 | 毛片免费在线观看 | 国产精品综合久久 | 欧美精品一区二区三区在线 | 午夜成人免费视频 | 国产精品久久一区二区三区 | 精品亚洲一区二区三区四区五区 | 日日操视频 | 国产在线高清 | 亚洲免费高清 | 欧美日韩不卡 | 噜噜噜色网| 亚洲一区二区 | 精品一区二区三区视频在线观看 | 91亚洲精华国产 | 国产日韩精品在线 | 国产美女一区二区 | 91精品国产自产精品男人的天堂 | 久在线 | 在线中文字幕视频 | 尹人av| 日韩av一区二区在线观看 | 视频1区2区 | 噜噜噜噜狠狠狠7777视频 | 999热视频 | 欧美国产精品 | 天天影视综合 | 国产一区二区欧美 | 黄色网址免费看 | 国产精品久久久久久久久久免费看 | 色爱综合网 | 亚洲精品乱码久久久久久按摩观 | 国产线视频精品免费观看视频 | 色播视频在线观看 | 女人毛片a毛片久久人人 | 欧美久久久久久久久 | 一区在线免费视频 | 国产精品一区二区免费 | 国产成人精品网站 | 日本特黄a级高清免费大片 特黄色一级毛片 |