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

QQ登錄

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

搜索
查看: 9777|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

觸摸屏和單片機(jī)進(jìn)行modbus通訊 RTU slave 文件源碼,希望可以幫助到大家

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
觸摸屏和單片機(jī)進(jìn)行modbus通訊,觸摸屏需要設(shè)置為主機(jī),單片機(jī)為從機(jī),modbusRTU slave 源碼需要植入單片機(jī),希望可以幫助到大家。


全部資料下載:
ModbusSlave.zip (13.59 KB, 下載次數(shù): 249)

  1. /****************************************Copyright (c)**************************************************
  2. **                                  廣州致遠(yuǎn)電子有限公司
  3. **
  4. **--------------File Info-------------------------------------------------------------------------------
  5. ** File name:                        MB_PFunction.c
  6. ** Last modified Date:  2005-01-11
  7. ** Last Version:                1.0
  8. ** Descriptions:               
  9. **
  10. **------------------------------------------------------------------------------------------------------
  11. ** Created by:                        ZhouLishan
  12. ** Created date:                2005-01-11
  13. ** Version:                                1.0
  14. ** Descriptions:               
  15. **
  16. **------------------------------------------------------------------------------------------------------
  17. ** Modified by:
  18. ** Modified date:
  19. ** Version:
  20. ** Descriptions:
  21. **
  22. ********************************************************************************************************/
  23. #include        "config.h"

  24. #include        "modbus.h"



  25. //**************************************************
  26. // 函數(shù)名稱(chēng):MB_GetDiscrete
  27. // 輸入?yún)?shù):Address,線(xiàn)圈地址
  28. // 輸出參數(shù):返回線(xiàn)圈值(0\1)
  29. // 功能描述:獲取離散值函數(shù),訪(fǎng)函數(shù)由用戶(hù)編寫(xiě)
  30. //**************************************************
  31. uint8_t MB_GetDiscrete(uint16_t Address)
  32. {
  33.         if(Address/2)
  34.                 return 1;
  35.         else
  36.                 return 0;
  37. }

  38. //**************************************************
  39. // 函數(shù)名稱(chēng):MB_GetCoils
  40. // 輸入?yún)?shù):Address,線(xiàn)圈地址
  41. // 輸出參數(shù):返回線(xiàn)圈值(0\1)
  42. // 功能描述:獲取線(xiàn)圈值函數(shù),訪(fǎng)函數(shù)由用戶(hù)編寫(xiě)
  43. //**************************************************
  44. uint8_t MB_GetCoils(uint16_t Address)
  45. {
  46.         if(Address/2)
  47.                 return 1;
  48.         else
  49.                 return 0;
  50. }

  51. //**************************************************
  52. // 函數(shù)名稱(chēng):MB_SetCoil
  53. // 輸入?yún)?shù):Address,線(xiàn)圈地址
  54. //                         CoilValue,線(xiàn)圈值(0\1)
  55. // 輸出參數(shù):返回寄存器值
  56. // 功能描述:設(shè)置線(xiàn)圈值函數(shù),訪(fǎng)函數(shù)由用戶(hù)編寫(xiě)
  57. //**************************************************
  58. uint8_t MB_SetCoil(uint16_t Address,uint8_t CoilValue)
  59. {

  60.         return CoilValue;
  61. }


  62. //**************************************************
  63. // 函數(shù)名稱(chēng):MB_GetInputRegValue
  64. // 輸入?yún)?shù):Address,寄存器地址
  65. // 輸出參數(shù):返回寄存器值
  66. // 功能描述:讀輸入寄存器值函數(shù),訪(fǎng)函數(shù)由用戶(hù)編寫(xiě)
  67. //**************************************************
  68. uint16_t MB_GetInputRegValue(uint16_t Address)
  69. {

  70.         return Address;
  71. }

  72. //**************************************************
  73. // 函數(shù)名稱(chēng):MB_GetRegValue
  74. // 輸入?yún)?shù):Address,寄存器地址
  75. // 輸出參數(shù):返回寄存器值
  76. // 功能描述:讀保持寄存器值函數(shù),訪(fǎng)函數(shù)由用戶(hù)編寫(xiě)
  77. //**************************************************
  78. uint16_t MB_GetRegValue(uint16_t Address)
  79. {

  80.         return Address;
  81. }

  82. //**************************************************
  83. // 函數(shù)名稱(chēng):MB_SetRegValue
  84. // 輸入?yún)?shù):Address,寄存器地址
  85. //                         Value,寫(xiě)入的值
  86. // 輸出參數(shù):無(wú)
  87. // 功能描述:寫(xiě)保持寄存器值函數(shù),訪(fǎng)函數(shù)由用戶(hù)編寫(xiě)
  88. //**************************************************
  89. void MB_SetRegValue(uint16_t Address,uint16_t Value)
  90. {

  91. }

  92. /****************************************************************************************/
  93. // 函數(shù)名稱(chēng):FReadCoils
  94. // 輸入?yún)?shù):Response
  95. // 輸出參數(shù):無(wú)
  96. // 功能描述:處理讀單線(xiàn)圈指令01
  97. /***************************************************************************************/
  98. void FReadCoils(PDU_RESPONSE *Response);
  99. /****************************************************************************************/
  100. // 函數(shù)名稱(chēng):FReadDiscreteInputs
  101. // 輸入?yún)?shù):Response
  102. // 輸出參數(shù):無(wú)
  103. // 功能描述:處理讀離散輸入指令02
  104. /***************************************************************************************/
  105. void FReadDiscreteInputs(PDU_RESPONSE *Response);
  106. /****************************************************************************************/
  107. // 函數(shù)名稱(chēng):FReadHoldingReg
  108. // 輸入?yún)?shù):Response
  109. // 輸出參數(shù):無(wú)
  110. // 功能描述:處理讀保持寄存器指令03
  111. /****************************************************************************************/
  112. void FReadHoldingReg(PDU_RESPONSE *Response);
  113. /****************************************************************************************/
  114. // 函數(shù)名稱(chēng):FReadInputReg
  115. // 輸入?yún)?shù):Response
  116. // 輸出參數(shù):無(wú)
  117. // 功能描述:處理讀輸入寄存器指令04
  118. /****************************************************************************************/
  119. void FReadInputReg(PDU_RESPONSE *Response);
  120. /****************************************************************************************/
  121. // 函數(shù)名稱(chēng):FWriteSingleCoil
  122. // 輸入?yún)?shù):Response
  123. // 輸出參數(shù):無(wú)
  124. // 功能描述:處理寫(xiě)單線(xiàn)圈指令05
  125. /****************************************************************************************/
  126. void FWriteSingleCoil(PDU_RESPONSE *Response);
  127. /****************************************************************************************/
  128. // 函數(shù)名稱(chēng):FWriteSingleReg
  129. // 輸入?yún)?shù):Response
  130. // 輸出參數(shù):無(wú)
  131. // 功能描述:處理寫(xiě)單線(xiàn)圈指令06
  132. /****************************************************************************************/
  133. void FWriteSingleReg(PDU_RESPONSE *Response);
  134. /****************************************************************************************/
  135. // 函數(shù)名稱(chēng):FWriteMultipleCoils
  136. // 輸入?yún)?shù):Response
  137. // 輸出參數(shù):無(wú)
  138. // 功能描述:處理寫(xiě)多線(xiàn)圈指令15
  139. /****************************************************************************************/
  140. void FWriteMultipleCoils(PDU_RESPONSE *Response);
  141. /****************************************************************************************/
  142. // 函數(shù)名稱(chēng):FWriteMultipleReg
  143. // 輸入?yún)?shù):Response
  144. // 輸出參數(shù):無(wú)
  145. // 功能描述:處理寫(xiě)多寄存器指令16
  146. /****************************************************************************************/
  147. void FWriteMultipleReg(PDU_RESPONSE *Response);
  148. /****************************************************************************************/
  149. // 函數(shù)名稱(chēng):FMaskWriteReg
  150. // 輸入?yún)?shù):Response
  151. // 輸出參數(shù):無(wú)
  152. // 功能描述:處理屏蔽寄存器指令22
  153. /****************************************************************************************/
  154. void FMaskWriteReg(PDU_RESPONSE *Response);
  155. /****************************************************************************************/
  156. // 函數(shù)名稱(chēng):FRWMultipleReg
  157. // 輸入?yún)?shù):Response
  158. // 輸出參數(shù):無(wú)
  159. // 功能描述:處理讀寫(xiě)多寄存器指令23
  160. /****************************************************************************************/
  161. void FRWMultipleReg(PDU_RESPONSE *Response);

  162. void FTest(PDU_RESPONSE *Response){}

  163. AT_CODE FUNCTION_ARRAY        FCodeHandleArray[MAX_FUNCTION]={
  164. #if READ_COILS_EN > 0
  165.         {0x01,FReadCoils},                        // 讀線(xiàn)圈
  166. #endif
  167. #if READ_DIS_INPUT_EN > 0
  168.         {0x02,FReadDiscreteInputs},        // 讀離散量輸入
  169. #endif
  170. #if READ_HOLD_REG_EN > 0
  171.         {0x03,FReadHoldingReg},                // 讀保持寄存器
  172. #endif
  173. #if READ_INPUT_REG_EN > 0
  174.         {0x04,FReadInputReg},                // 讀輸入寄存器
  175. #endif
  176. #if WRITE_SING_COIL_EN > 0
  177.         {0x05,FWriteSingleCoil},        // 寫(xiě)單個(gè)線(xiàn)圈
  178. #endif
  179. #if WRITE_SING_REG_EN > 0
  180.         {0x06,FWriteSingleReg},                // 寫(xiě)單個(gè)寄存器
  181. #endif
  182. #if WRITE_MULT_COIL_EN > 0
  183.         {0x0f,FWriteMultipleCoils},        // 寫(xiě)多個(gè)線(xiàn)圈
  184. #endif
  185. #if WRITE_MULT_REG_EN > 0
  186.         {0x10,FWriteMultipleReg},        // 寫(xiě)多個(gè)寄存器
  187. #endif
  188. #if MASK_WRITE_REG_EN > 0
  189.         {0x16,FMaskWriteReg},                // 處理屏蔽寄存器指令
  190. #endif
  191. #if READ_WRITE_REG_EN > 0
  192.         {0x17,FRWMultipleReg},                // 讀寫(xiě)多個(gè)寄存器
  193. #endif
  194.         {0x00,FTest}                                // 測(cè)試功能代碼
  195. };

  196. #if READ_DIS_INPUT_EN
  197. //************************************************************************************
  198. // 函數(shù)名稱(chēng):ReadDiscreteInputs
  199. // 輸入?yún)?shù):CoilsDataPtr,存放離散輸入數(shù)據(jù)指針
  200. //                         StAddr,離散的起始地址
  201. //                         Quantity,離散的數(shù)量
  202. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  203. // 功能描述:讀離散輸入操作函數(shù)
  204. //************************************************************************************        
  205. uint8_t ReadDiscreteInputs(uint8_t *CoilsDataPtr,uint16_t StAddr ,uint16_t Quantity)
  206. {
  207.         uint8_t *CoilsInByte;
  208.         uint8_t offset;
  209.         uint16_t i=0 ;
  210.         CoilsInByte = CoilsDataPtr;
  211.         while(i<Quantity)
  212.         {        
  213.                 *CoilsInByte = 0;
  214.                 for(offset=0;offset<8;offset++,i++)                // 將線(xiàn)圈值寫(xiě)入一個(gè)字節(jié)
  215.                 {
  216.                         if(i<Quantity)
  217.                         {
  218.                                 *CoilsInByte |= MB_GetDiscrete(StAddr+i)<<offset;
  219.                         }
  220.                 }
  221.                 CoilsInByte++;
  222.         }
  223.         return TRUE;
  224. }
  225. #endif


  226. #if READ_COILS_EN
  227. //************************************************************************************
  228. // 函數(shù)名稱(chēng):ReadCoils
  229. // 輸入?yún)?shù):CoilsDataPtr,存放線(xiàn)圈數(shù)據(jù)指針
  230. //                         StAddr,線(xiàn)圈的起始地址
  231. //                         Quantity,線(xiàn)圈的數(shù)量
  232. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  233. // 功能描述:讀多線(xiàn)圈操作函數(shù)
  234. //************************************************************************************        
  235. uint8_t ReadCoils(uint8_t *CoilsDataPtr,uint16_t StAddr ,uint16_t Quantity)
  236. {
  237.         uint8_t *CoilsInByte;
  238.         uint8_t offset;
  239.         uint16_t i=0 ;
  240.         CoilsInByte = CoilsDataPtr;
  241.         while(i<Quantity)
  242.         {        
  243.                 *CoilsInByte = 0;
  244.                 for(offset=0;offset<8;offset++,i++)                // 將線(xiàn)圈值寫(xiě)入一個(gè)字節(jié)
  245.                 {
  246.                         if(i<Quantity)
  247.                         {
  248.                                 *CoilsInByte |= MB_GetCoils(StAddr+i)<<offset;
  249.                         }
  250.                 }
  251.                 CoilsInByte++;
  252.         }
  253.         return TRUE;
  254. }
  255. #endif

  256. #if WRITE_SING_COIL_EN
  257. //************************************************************************************
  258. // 函數(shù)名稱(chēng):WriteSingleCoil
  259. // 輸入?yún)?shù):DataPtr,數(shù)據(jù)指針,
  260. //                         StAddr,寄存器起始地址
  261. //                         Quantity,寄存器數(shù)量。
  262. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  263. // 功能描述:寫(xiě)單線(xiàn)圈處理函數(shù)
  264. //************************************************************************************        
  265. uint8_t WriteSingleCoil(uint16_t OutputAddr,uint16_t OutputValue)
  266. {
  267.         return MB_SetCoil(OutputAddr,(OutputValue==0xff00)?1:0);
  268. }
  269. #endif

  270. #if WRITE_MULT_COIL_EN
  271. //************************************************************************************
  272. // 函數(shù)名稱(chēng):WriteMultipleCoils
  273. // 輸入?yún)?shù):DataPtr,數(shù)據(jù)指針,
  274. //                         StAddr,寄存器起始地址
  275. //                         Quantity,寄存器數(shù)量。
  276. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  277. // 功能描述:寫(xiě)多線(xiàn)圈處理函數(shù)
  278. //************************************************************************************        
  279. uint8 WriteMultipleCoils(uint8 *DataPtr,uint16 StAddr ,uint16 Quantity)
  280. {
  281.         uint16 i;
  282.         uint8         CoilInByte;
  283.         for(i=0;i<Quantity;i++)
  284.         {
  285.                 if((i%8)==0)        
  286.                         CoilInByte = *(DataPtr+(i/8));
  287.                 if( FALSE == MB_SetCoil(StAddr+i,(CoilInByte>>(i%8))&0x01))
  288.                         return FALSE;        
  289.         }
  290.         return TRUE;
  291. }
  292. #endif

  293. #if READ_INPUT_REG_EN
  294. //************************************************************************************
  295. // 函數(shù)名稱(chēng):ReadInputReg
  296. // 輸入?yún)?shù):DataPtr,數(shù)據(jù)指針,
  297. //                         StAddr,寄存器起始地址
  298. //                         Quantity,寄存器數(shù)量。
  299. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  300. // 功能描述:讀輸入寄存器
  301. //************************************************************************************        
  302. uint8_t ReadInputReg(uint8_t *DataPtr,uint16_t StAddr ,uint16_t Quantity)
  303. {
  304.         uint8_t i;
  305.         uint16_t        Value;
  306.         for(i=0;i<Quantity;i++)
  307.         {
  308.                 Value = MB_GetInputRegValue(StAddr+i);
  309.                 *(DataPtr+i*2)   = (uint8)(Value>>8);                 // 先傳高位
  310.                 *(DataPtr+i*2+1) = (uint8)Value;                          // 后傳低位
  311.         }
  312.         return TRUE;
  313. }
  314. #endif


  315. #if READ_HOLD_REG_EN+READ_WRITE_REG_EN+MASK_WRITE_REG_EN
  316. //************************************************************************************
  317. // 函數(shù)名稱(chēng):ReadHoldingReg
  318. // 輸入?yún)?shù):DataPtr,數(shù)據(jù)指針,16位數(shù)據(jù)高8位在低字節(jié),低8位在高字節(jié)
  319. //                         StAddr,寄存器起始地址
  320. //                         Quantity,寄存器數(shù)量。
  321. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  322. // 功能描述:讀寄存器處理函數(shù)
  323. //************************************************************************************        
  324. uint8_t ReadHoldingReg(uint8_t *DataPtr,uint16_t StAddr ,uint16_t Quantity)
  325. {
  326.         uint8_t i;
  327.         uint16_t        Value;
  328.         for(i=0;i<Quantity;i++)
  329.         {
  330.                 Value = MB_GetRegValue(StAddr+i);
  331.                 *(DataPtr+i*2)   = (uint8)(Value>>8);         // 先傳高位
  332.                 *(DataPtr+i*2+1) = (uint8)Value;                  // 后傳低位
  333.         }
  334.         return TRUE;
  335. }
  336. #endif

  337. #if WRITE_MULT_REG_EN+READ_WRITE_REG_EN+MASK_WRITE_REG_EN+WRITE_SING_REG_EN
  338. //************************************************************************************
  339. // 函數(shù)名稱(chēng):WriteHoldingReg
  340. // 輸入?yún)?shù):DataPtr,數(shù)據(jù)指針,16位數(shù)據(jù)高8位在低字節(jié),低8位在高字節(jié)
  341. //                         StAddr,寄存器起始地址
  342. //                         Quantity,寄存器數(shù)量。
  343. // 輸出參數(shù):正常返回TRUE,出錯(cuò)返回FALSE。
  344. // 功能描述:寫(xiě)寄存器處理函數(shù)
  345. //************************************************************************************        
  346. uint8_t WriteHoldingReg(uint8_t *KeepDataPtr,uint16_t StAddr ,uint16_t Quantity)
  347. {
  348.         uint8_t i;
  349.         uint16_t        Value;
  350.         for(i=0;i<Quantity;i++)
  351.         {
  352.                 Value = (*(KeepDataPtr+i*2)<<8)|(*(KeepDataPtr+i*2+1));
  353.                 MB_SetRegValue(StAddr+i,Value);
  354.         }
  355.         return TRUE;
  356. }
  357. #endif










  358. #if READ_COILS_EN > 0
  359. /****************************************************************************************/
  360. // 函數(shù)名稱(chēng):FReadCoils
  361. // 輸入?yún)?shù):Response,為PDU_RESPONSE類(lèi)型的指針,PDU_RESPONSE:
  362. //                         typedef struct __PDU_RESPONSE{
  363. //                                uint8*        PDUDataPtr;   請(qǐng)求數(shù)據(jù)指針,功能代碼處理函數(shù)必需將處理的數(shù)據(jù)包存在該指針的開(kāi)始位始
  364. //                                  uint8        PDUByteLength;請(qǐng)求數(shù)據(jù)數(shù)長(zhǎng)度
  365. //                                uint8        ExceptionCode;僅為輸出錯(cuò)異常代碼,正常操作設(shè)為0
  366. //                         }PDU_RESPONSE
  367. // 輸出參數(shù):無(wú)
  368. // 功能描述:處理讀多線(xiàn)圈指令01
  369. /***************************************************************************************/
  370. void FReadCoils(PDU_RESPONSE *Response)
  371. {
  372.         uint8_t * PDUPtr;
  373.         uint16_t StAddr ,Quantity;
  374.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  375.         PDUPtr = Response->PDUDataPtr;
  376.         StAddr = PDUPtr[1]<<8|PDUPtr[2];
  377.         Quantity =  PDUPtr[3]<<8|PDUPtr[4];
  378.         
  379.         Response->PDUByteLength = 2 + Quantity/8+((Quantity%8)?1:0) ;        // 正常返回的數(shù)據(jù)長(zhǎng)度
  380.         
  381.         if((Quantity>=0x001)&&(Quantity<=0x07d0))
  382.         {
  383.                 if((StAddr<END_COILS_ADDR)&&((StAddr+Quantity)<=END_COILS_ADDR))
  384.                 {                        
  385.                         if(ReadCoils(PDUPtr+2,StAddr,Quantity))
  386.                         {
  387.                                 *(PDUPtr+1) = Quantity/8+(Quantity%8)?1:0;        // 字節(jié)數(shù)
  388.                                 Response->ExceptionCode = 0x00;
  389.                         }
  390.                         else
  391.                                 Response->ExceptionCode = 0x04;
  392.                 }
  393.                 else
  394.                         Response->ExceptionCode = 0x02;
  395.         }
  396.         else
  397.                 Response->ExceptionCode = 0x03;
  398. }
  399. #endif

  400. #if READ_DIS_INPUT_EN >0
  401. /****************************************************************************************/
  402. // 函數(shù)名稱(chēng):FReadDiscreteInputs
  403. // 輸入?yún)?shù):Response
  404. // 輸出參數(shù):無(wú)
  405. // 功能描述:處理讀離散輸入指令02
  406. /***************************************************************************************/
  407. void FReadDiscreteInputs(PDU_RESPONSE *Response)
  408. {
  409.         uint8_t * PDUPtr;
  410.         uint16_t StAddr ,Quantity;
  411.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  412.         PDUPtr = Response->PDUDataPtr;
  413.         StAddr = PDUPtr[1]<<8|PDUPtr[2];
  414.         Quantity =  PDUPtr[3]<<8|PDUPtr[4];
  415.         
  416.         Response->PDUByteLength = 2 + Quantity/8+((Quantity%8)?1:0) ;        // 正常返回的數(shù)據(jù)長(zhǎng)度
  417.         
  418.         if((Quantity>=0x001)&&(Quantity<=0x07d0))
  419.         {
  420.                 if((StAddr<END_DISC_INPUT_ADDR)&&((StAddr+Quantity)<=END_DISC_INPUT_ADDR))
  421.                 {                        
  422.                         if(ReadDiscreteInputs(PDUPtr+2,StAddr,Quantity))
  423.                         {
  424.                                 *(PDUPtr+1) = Quantity/8+(Quantity%8)?1:0;        // 字節(jié)數(shù)
  425.                                 Response->ExceptionCode = 0x00;
  426.                         }
  427.                         else
  428.                                 Response->ExceptionCode = 0x04;
  429.                 }
  430.                 else
  431.                         Response->ExceptionCode = 0x02;
  432.         }
  433.         else
  434.                 Response->ExceptionCode = 0x03;
  435. }
  436. #endif

  437. #if READ_HOLD_REG_EN >0
  438. /****************************************************************************************/
  439. // 函數(shù)名稱(chēng):FReadHoldingReg
  440. // 輸入?yún)?shù):Response
  441. // 輸出參數(shù):無(wú)
  442. // 功能描述:處理讀保持寄存器指令03
  443. /****************************************************************************************/
  444. void FReadHoldingReg(PDU_RESPONSE *Response)
  445. {
  446.         uint8_t * PDUPtr;
  447.         uint16_t StAddr ,Quantity;
  448.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  449.         PDUPtr = Response->PDUDataPtr;
  450.         StAddr = PDUPtr[1]<<8|PDUPtr[2];
  451.         Quantity =  PDUPtr[3]<<8|PDUPtr[4];
  452.         
  453.         Response->PDUByteLength = 2 + Quantity*2 ;        // 正常返回的數(shù)據(jù)長(zhǎng)度
  454.         
  455.         if((Quantity>=0x001)&&(Quantity<=0x007d))
  456.         {
  457.                 if((StAddr<END_HOLDING_REG_ADDR)&&((StAddr+Quantity)<=END_HOLDING_REG_ADDR))
  458.                 {                        
  459.                         if(ReadHoldingReg(PDUPtr+2,StAddr,Quantity))
  460.                         {
  461.                                 *(PDUPtr+1) = Quantity*2;
  462.                                 Response->ExceptionCode = 0x00;
  463.                         }
  464.                         else
  465.                                 Response->ExceptionCode = 0x04;
  466.                 }
  467.                 else
  468.                         Response->ExceptionCode = 0x02;
  469.         }
  470.         else
  471.                 Response->ExceptionCode = 0x03;
  472. }
  473. #endif

  474. #if READ_INPUT_REG_EN >0
  475. /****************************************************************************************/
  476. // 函數(shù)名稱(chēng):FReadInputReg
  477. // 輸入?yún)?shù):Response
  478. // 輸出參數(shù):無(wú)
  479. // 功能描述:處理讀輸入寄存器指令04
  480. /****************************************************************************************/
  481. void FReadInputReg(PDU_RESPONSE *Response)
  482. {
  483.         uint8_t * PDUPtr;
  484.         uint16_t StAddr ,Quantity;
  485.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  486.         PDUPtr = Response->PDUDataPtr;
  487.         StAddr = PDUPtr[1]<<8|PDUPtr[2];
  488.         Quantity =  PDUPtr[3]<<8|PDUPtr[4];
  489.         
  490.         Response->PDUByteLength = 2 + Quantity*2 ;        // 正常返回的數(shù)據(jù)長(zhǎng)度
  491.         
  492.         if((Quantity>=0x001)&&(Quantity<=0x007d))
  493.         {
  494.                 if((StAddr<END_INPUT_REG_ADDR) && ((StAddr+Quantity)<=END_INPUT_REG_ADDR))
  495.                 {                        
  496.                         if(ReadInputReg(PDUPtr+2,StAddr,Quantity))
  497.                         {
  498.                                 *(PDUPtr+1) = Quantity*2;
  499.                                 Response->ExceptionCode = 0x00;
  500.                         }
  501.                         else
  502.                                 Response->ExceptionCode = 0x04;
  503.                 }
  504.                 else
  505.                         Response->ExceptionCode = 0x02;
  506.         }
  507.         else
  508.                 Response->ExceptionCode = 0x03;
  509. }
  510. #endif


  511. #if WRITE_SING_COIL_EN >0
  512. /****************************************************************************************/
  513. // 函數(shù)名稱(chēng):FWriteSingleCoil
  514. // 輸入?yún)?shù):Response
  515. // 輸出參數(shù):無(wú)
  516. // 功能描述:處理寫(xiě)單線(xiàn)圈指令05
  517. /****************************************************************************************/
  518. void FWriteSingleCoil(PDU_RESPONSE *Response)
  519. {
  520.         uint8_t * PDUPtr;
  521.         uint16_t OutputAddr ,OutputValue;
  522.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  523.         PDUPtr = Response->PDUDataPtr;
  524.         OutputAddr = PDUPtr[1]<<8|PDUPtr[2];
  525.         OutputValue =  PDUPtr[3]<<8|PDUPtr[4];
  526.         
  527.         Response->PDUByteLength = 5 ;        // 正常返回的數(shù)據(jù)長(zhǎng)度
  528.         
  529.         if((OutputValue==0x0000)||(OutputValue==0xff00))
  530.         {
  531.                 if( OutputAddr < END_COILS_ADDR )
  532.                 {                        
  533.                         if(WriteSingleCoil(OutputAddr,OutputValue))
  534.                         {
  535.                                 *(PDUPtr+1) = OutputAddr>>8;
  536.                                 *(PDUPtr+2) = OutputAddr;
  537.                                 *(PDUPtr+3)        = OutputValue>>8;
  538.                                 *(PDUPtr+4)        = OutputValue;
  539.                                 Response->ExceptionCode = 0x00;
  540.                         }
  541.                         else
  542.                                 Response->ExceptionCode = 0x04;
  543.                 }
  544.                 else
  545.                         Response->ExceptionCode = 0x02;
  546.         }
  547.         else
  548.                 Response->ExceptionCode = 0x03;
  549. }
  550. #endif

  551. #if WRITE_SING_REG_EN >0
  552. /****************************************************************************************/
  553. // 函數(shù)名稱(chēng):FWriteSingleReg
  554. // 輸入?yún)?shù):Response
  555. // 輸出參數(shù):無(wú)
  556. // 功能描述:處理寫(xiě)單線(xiàn)圈指令06
  557. /****************************************************************************************/
  558. void FWriteSingleReg(PDU_RESPONSE *Response)
  559. {
  560.         uint8 * PDUPtr;
  561.         uint16 OutputAddr ,OutputValue;
  562.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  563.         PDUPtr = Response->PDUDataPtr;
  564.         OutputAddr = PDUPtr[1]<<8|PDUPtr[2];
  565.         OutputValue =  PDUPtr[3]<<8|PDUPtr[4];
  566.         
  567.         Response->PDUByteLength = 2 + 5 ;        // 正常返回的數(shù)據(jù)長(zhǎng)度
  568.         
  569.         if(OutputValue<=0xffff)
  570.         {
  571.                 if(OutputAddr<END_HOLDING_REG_ADDR)
  572.                 {                        
  573.                         if(WriteHoldingReg(&PDUPtr[3],OutputAddr,1))
  574.                         {
  575.                                 *(PDUPtr+1) = OutputAddr>>8;
  576.                                 *(PDUPtr+2) = OutputAddr;
  577.                                 *(PDUPtr+3)        = OutputValue>>8;
  578.                                 *(PDUPtr+4)        = OutputValue;
  579.                                 Response->ExceptionCode = 0x00;
  580.                         }
  581.                         else
  582.                                 Response->ExceptionCode = 0x04;
  583.                 }
  584.                 else
  585.                         Response->ExceptionCode = 0x02;
  586.         }
  587.         else
  588.                 Response->ExceptionCode = 0x03;
  589. }
  590. #endif

  591. #if WRITE_MULT_COIL_EN >0
  592. /****************************************************************************************/
  593. // 函數(shù)名稱(chēng):FWriteMultipleCoils
  594. // 輸入?yún)?shù):Response
  595. // 輸出參數(shù):無(wú)
  596. // 功能描述:處理寫(xiě)多線(xiàn)圈指令15
  597. /****************************************************************************************/
  598. void FWriteMultipleCoils(PDU_RESPONSE *Response)
  599. {
  600.         uint8_t * PDUPtr;
  601.         uint16_t StAddr ,Quantity;
  602.         uint8_t         ByteCount;
  603.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  604.         PDUPtr = Response->PDUDataPtr;
  605.         StAddr = PDUPtr[1]<<8|PDUPtr[2];
  606.         Quantity =  PDUPtr[3]<<8|PDUPtr[4];
  607.         ByteCount = PDUPtr[5];
  608.         
  609.         Response->PDUByteLength = 5 ;        // 正常返回的數(shù)據(jù)長(zhǎng)度

  610.         if((Quantity>=0x001)&&(Quantity<=0x07d0)&&(ByteCount==(Quantity/8+((Quantity%8)?1:0))))
  611.         {
  612.                 if((StAddr<END_COILS_ADDR)&&((StAddr+Quantity)<=(END_COILS_ADDR+1)))
  613.                 {                        
  614.                         if(WriteMultipleCoils(PDUPtr+6,StAddr,Quantity))
  615.                         {
  616.                                 *(PDUPtr+1) = StAddr>>8;
  617.                                 *(PDUPtr+2) = StAddr;
  618.                                 *(PDUPtr+3) = Quantity>>8;
  619.                                 *(PDUPtr+4) = Quantity;
  620.                                 Response->ExceptionCode = 0x00;
  621.                         }
  622.                         else
  623.                                 Response->ExceptionCode = 0x04;
  624.                 }
  625.                 else
  626.                         Response->ExceptionCode = 0x02;
  627.         }
  628.         else
  629.                 Response->ExceptionCode = 0x03;
  630. }
  631. #endif

  632. #if WRITE_MULT_REG_EN >0
  633. /****************************************************************************************/
  634. // 函數(shù)名稱(chēng):FWriteMultipleReg
  635. // 輸入?yún)?shù):Response
  636. // 輸出參數(shù):無(wú)
  637. // 功能描述:處理寫(xiě)多寄存器指令16
  638. /****************************************************************************************/
  639. void FWriteMultipleReg(PDU_RESPONSE *Response)
  640. {
  641.         uint8_t * PDUPtr;
  642.         uint16_t StAddr ,Quantity;
  643.         uint8_t         ByteCount;
  644.         // 從請(qǐng)求PDU中提取相關(guān)參數(shù)
  645.         PDUPtr = Response->PDUDataPtr;
  646.         StAddr = PDUPtr[1]<<8|PDUPtr[2];
  647.         Quantity =  PDUPtr[3]<<8|PDUPtr[4];
  648.         ByteCount = PDUPtr[5];
  649.         
  650.         Response->PDUByteLength = 5 ;        // 正常返回的數(shù)據(jù)長(zhǎng)度

  651.         if((Quantity>=0x001)&&(Quantity<=0x007d)&&(ByteCount==(Quantity*2)))
  652.         {
  653.                 if((StAddr<END_HOLDING_REG_ADDR) && ((StAddr+Quantity)<=(END_HOLDING_REG_ADDR+1)))
  654.                 {                        
  655.                         if(WriteHoldingReg(PDUPtr+6,StAddr,Quantity))
  656.                         {
  657.                                 *(PDUPtr+1) = StAddr>>8;
  658.                                 *(PDUPtr+2) = StAddr;
  659.                                 *(PDUPtr+3) = Quantity>>8;
  660.                                 *(PDUPtr+4) = Quantity;
  661.                                 Response->ExceptionCode = 0x00;
  662.                         }
  663.                         else
  664.                                 Response->ExceptionCode = 0x04;
  665.                 }
  666.                 else
  667.                         Response->ExceptionCode = 0x02;
  668.         }
  669.         else
  670.                 Response->ExceptionCode = 0x03;
  671. }
  672. #endif

  673. #if MASK_WRITE_REG_EN >0
  674. /****************************************************************************************/
  675. // 函數(shù)名稱(chēng):FMaskWriteReg
  676. // 輸入?yún)?shù):Response
  677. // 輸出參數(shù):無(wú)
  678. // 功能描述:處理屏蔽寄存器指令22
  679. /****************************************************************************************/
  680. void FMaskWriteReg(PDU_RESPONSE *Response)
  681. {
  682.         uint16_t RefeAddr,And_Mask,Or_Mask,RegValue;
  683.         uint8_t  *PDUPtr;
  684.         uint8_t  ValueInByte[2];               
  685.         PDUPtr = Response->PDUDataPtr;
  686.         RefeAddr = (PDUPtr[1]<<8)|(PDUPtr[2]);
  687.         And_Mask = (PDUPtr[3]<<8)|(PDUPtr[4]);
  688.         Or_Mask  = (PDUPtr[5]<<8)|(PDUPtr[6]);
  689.         
  690.         Response->PDUByteLength = 7;
  691.         
  692.         if(RefeAddr<END_HOLDING_REG_ADDR)
  693.         {
  694.                 if(ReadHoldingReg(ValueInByte,RefeAddr,1))
  695.                 {        
  696.                         RegValue = (ValueInByte[0]<<8)|(ValueInByte[1]);
  697.                         RegValue = (RegValue & And_Mask)|(Or_Mask & (~And_Mask));
  698.                         ValueInByte[0] = RegValue >> 8;
  699.                         ValueInByte[1] = RegValue ;
  700.                         if(WriteHoldingReg(ValueInByte,RefeAddr,1))
  701.                         {
  702.                                 *(PDUPtr+1) = RefeAddr>>8;
  703.                                 *(PDUPtr+2) = RefeAddr;
  704.                                 *(PDUPtr+3) = And_Mask>>8;
  705.                                 *(PDUPtr+4) = And_Mask;
  706.                                 *(PDUPtr+5) = Or_Mask>>8;
  707.                                 *(PDUPtr+6) = Or_Mask;
  708.                                 Response->ExceptionCode = 0x00;
  709.                         }
  710.                         else
  711.                                 Response->ExceptionCode = 0x04;
  712.                 }
  713.                 else
  714.                         Response->ExceptionCode = 0x03;
  715.         }
  716.         else
  717.                 Response->ExceptionCode = 0x02;
  718. }
  719. #endif

  720. #if READ_WRITE_REG_EN > 0
  721. /****************************************************************************************/
  722. // 函數(shù)名稱(chēng):FRWMultipleReg
  723. // 輸入?yún)?shù):Response
  724. // 輸出參數(shù):無(wú)
  725. // 功能描述:處理讀寫(xiě)多寄存器指令23
  726. /****************************************************************************************/
  727. void FRWMultipleReg(PDU_RESPONSE *Response)
  728. {
  729.         uint16_t ReadStaAddr,        ReadQuantity;
  730.         uint16_t WriteStaAddr,WriteQuantity;
  731.         uint8_t  WriteBytes;
  732.         uint8_t  *WriteValuePtr;
  733.         uint8_t  *PDUPtr;
  734.         PDUPtr = Response->PDUDataPtr;
  735.         ReadStaAddr   = (PDUPtr[1]<<8)|(PDUPtr[2]);
  736.         ReadQuantity  = (PDUPtr[3]<<8)|(PDUPtr[4]);
  737.         WriteStaAddr  = (PDUPtr[5]<<8)|(PDUPtr[6]);
  738.         WriteQuantity = (PDUPtr[7]<<8)|(PDUPtr[8]);
  739.         WriteBytes    = PDUPtr[9];
  740.         WriteValuePtr = &PDUPtr[10];

  741.         Response->PDUByteLength = ReadQuantity*2 + 2;
  742.         
  743.         if((ReadQuantity>=0x001)&&(ReadQuantity<=0x007d)&&                // 讀寄存器的數(shù)量是否在有效范圍內(nèi)
  744.            (WriteQuantity>=0x001)&&(WriteQuantity<=0x0079)&&        // 寫(xiě)寄存器的數(shù)量是否在有效范圍內(nèi)
  745.            (WriteBytes==(WriteQuantity*2)))                                                // 接收到的字節(jié)數(shù)是否與寫(xiě)入的寄存器數(shù)量一至
  746.         {
  747.                 if((ReadStaAddr<END_HOLDING_REG_ADDR)&&((ReadStaAddr+ReadQuantity)<=END_HOLDING_REG_ADDR)&&
  748.                    (WriteStaAddr<END_HOLDING_REG_ADDR)&&((WriteStaAddr+WriteQuantity)<=END_HOLDING_REG_ADDR))
  749.                 {
  750.                         if(WriteHoldingReg(WriteValuePtr,WriteStaAddr,WriteQuantity))        // 寫(xiě)寄存器
  751.                         {
  752.                            if(ReadHoldingReg(PDUPtr+2,ReadStaAddr,ReadQuantity))                // 讀寄存器
  753.                                 {
  754.                                         *(PDUPtr+1) = ReadQuantity*2;
  755.                                         Response->ExceptionCode = 0x00;
  756.                                 }
  757.                                 else
  758.                                         Response->ExceptionCode = 0x04;
  759.                         }
  760.                         else
  761.                                 Response->ExceptionCode = 0x04;
  762.                 }
  763.                 else
  764.                         Response->ExceptionCode = 0x02;
  765.         }
  766.         else
  767.                 Response->ExceptionCode = 0x03;
  768. }
  769. #endif












復(fù)制代碼


評(píng)分

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

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏13 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:151192 發(fā)表于 2016-11-30 13:11 | 只看該作者
你好,我想將單片機(jī)讀取的 一個(gè)溫度值通過(guò)modbus協(xié)議 傳輸?shù)缴衔粰C(jī)  我的設(shè)計(jì)思路應(yīng)該是怎樣的呢 能把我簡(jiǎn)單的說(shuō)明下嗎  謝謝你了!
回復(fù)

使用道具 舉報(bào)

板凳
ID:156580 發(fā)表于 2017-1-10 10:18 | 只看該作者
這個(gè)資料很好,尤其是在工業(yè)控制應(yīng)用方面,能制作成符合工業(yè)標(biāo)準(zhǔn)的控制器
回復(fù)

使用道具 舉報(bào)

地板
ID:698773 發(fā)表于 2020-2-28 15:56 來(lái)自手機(jī) | 只看該作者
lisc5920 發(fā)表于 2016-11-30 13:11
你好,我想將單片機(jī)讀取的 一個(gè)溫度值通過(guò)modbus協(xié)議 傳輸?shù)缴衔粰C(jī)  我的設(shè)計(jì)思路應(yīng)該是怎樣的呢 能把我簡(jiǎn) ...

你的問(wèn)題解決沒(méi)有?
回復(fù)

使用道具 舉報(bào)

5#
ID:698773 發(fā)表于 2020-2-28 16:00 來(lái)自手機(jī) | 只看該作者
這個(gè)有原理圖嘛?
回復(fù)

使用道具 舉報(bào)

6#
ID:595103 發(fā)表于 2021-9-22 13:14 | 只看該作者
好資料,接下來(lái)的設(shè)計(jì)正好需要用到MODbus
回復(fù)

使用道具 舉報(bào)

7#
ID:138205 發(fā)表于 2022-1-26 21:40 | 只看該作者
路過(guò)學(xué)習(xí),好東西,收藏一下,
回復(fù)

使用道具 舉報(bào)

8#
ID:1129695 發(fā)表于 2024-7-27 15:46 | 只看該作者

好資料,接下來(lái)的設(shè)計(jì)正好需要用到MODbus
回復(fù)

使用道具 舉報(bào)

9#
ID:811685 發(fā)表于 2024-8-2 19:43 | 只看該作者
路過(guò)學(xué)習(xí),好東西,收藏一下,
回復(fù)

使用道具 舉報(bào)

10#
ID:884711 發(fā)表于 2024-10-8 08:52 | 只看該作者
好資料,正好用到MODbus,謝謝分享!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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