找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7838|回复: 6
打印 上一主题 下一主题
收起左侧

触摸屏和单片机进行modbus通讯 RTU slave 文件源码,希望可以帮助到大家

  [复制链接]
跳转到指定楼层
楼主
触摸屏和单片机进行modbus通讯,触摸屏需要设置为主机,单片机为从机,modbusRTU slave 源码需要植入单片机,希望可以帮助到大家。


全部资料下载:
ModbusSlave.zip (13.59 KB, 下载次数: 227)

  1. /****************************************Copyright (c)**************************************************
  2. **                                  广州致远电子有限公司
  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. // 函数名称:MB_GetDiscrete
  27. // 输入参数:Address,线圈地址
  28. // 输出参数:返回线圈值(0\1)
  29. // 功能描述:获取离散值函数,访函数由用户编写
  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. // 函数名称:MB_GetCoils
  40. // 输入参数:Address,线圈地址
  41. // 输出参数:返回线圈值(0\1)
  42. // 功能描述:获取线圈值函数,访函数由用户编写
  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. // 函数名称:MB_SetCoil
  53. // 输入参数:Address,线圈地址
  54. //                         CoilValue,线圈值(0\1)
  55. // 输出参数:返回寄存器值
  56. // 功能描述:设置线圈值函数,访函数由用户编写
  57. //**************************************************
  58. uint8_t MB_SetCoil(uint16_t Address,uint8_t CoilValue)
  59. {

  60.         return CoilValue;
  61. }


  62. //**************************************************
  63. // 函数名称:MB_GetInputRegValue
  64. // 输入参数:Address,寄存器地址
  65. // 输出参数:返回寄存器值
  66. // 功能描述:读输入寄存器值函数,访函数由用户编写
  67. //**************************************************
  68. uint16_t MB_GetInputRegValue(uint16_t Address)
  69. {

  70.         return Address;
  71. }

  72. //**************************************************
  73. // 函数名称:MB_GetRegValue
  74. // 输入参数:Address,寄存器地址
  75. // 输出参数:返回寄存器值
  76. // 功能描述:读保持寄存器值函数,访函数由用户编写
  77. //**************************************************
  78. uint16_t MB_GetRegValue(uint16_t Address)
  79. {

  80.         return Address;
  81. }

  82. //**************************************************
  83. // 函数名称:MB_SetRegValue
  84. // 输入参数:Address,寄存器地址
  85. //                         Value,写入的值
  86. // 输出参数:无
  87. // 功能描述:写保持寄存器值函数,访函数由用户编写
  88. //**************************************************
  89. void MB_SetRegValue(uint16_t Address,uint16_t Value)
  90. {

  91. }

  92. /****************************************************************************************/
  93. // 函数名称:FReadCoils
  94. // 输入参数:Response
  95. // 输出参数:无
  96. // 功能描述:处理读单线圈指令01
  97. /***************************************************************************************/
  98. void FReadCoils(PDU_RESPONSE *Response);
  99. /****************************************************************************************/
  100. // 函数名称:FReadDiscreteInputs
  101. // 输入参数:Response
  102. // 输出参数:无
  103. // 功能描述:处理读离散输入指令02
  104. /***************************************************************************************/
  105. void FReadDiscreteInputs(PDU_RESPONSE *Response);
  106. /****************************************************************************************/
  107. // 函数名称:FReadHoldingReg
  108. // 输入参数:Response
  109. // 输出参数:无
  110. // 功能描述:处理读保持寄存器指令03
  111. /****************************************************************************************/
  112. void FReadHoldingReg(PDU_RESPONSE *Response);
  113. /****************************************************************************************/
  114. // 函数名称:FReadInputReg
  115. // 输入参数:Response
  116. // 输出参数:无
  117. // 功能描述:处理读输入寄存器指令04
  118. /****************************************************************************************/
  119. void FReadInputReg(PDU_RESPONSE *Response);
  120. /****************************************************************************************/
  121. // 函数名称:FWriteSingleCoil
  122. // 输入参数:Response
  123. // 输出参数:无
  124. // 功能描述:处理写单线圈指令05
  125. /****************************************************************************************/
  126. void FWriteSingleCoil(PDU_RESPONSE *Response);
  127. /****************************************************************************************/
  128. // 函数名称:FWriteSingleReg
  129. // 输入参数:Response
  130. // 输出参数:无
  131. // 功能描述:处理写单线圈指令06
  132. /****************************************************************************************/
  133. void FWriteSingleReg(PDU_RESPONSE *Response);
  134. /****************************************************************************************/
  135. // 函数名称:FWriteMultipleCoils
  136. // 输入参数:Response
  137. // 输出参数:无
  138. // 功能描述:处理写多线圈指令15
  139. /****************************************************************************************/
  140. void FWriteMultipleCoils(PDU_RESPONSE *Response);
  141. /****************************************************************************************/
  142. // 函数名称:FWriteMultipleReg
  143. // 输入参数:Response
  144. // 输出参数:无
  145. // 功能描述:处理写多寄存器指令16
  146. /****************************************************************************************/
  147. void FWriteMultipleReg(PDU_RESPONSE *Response);
  148. /****************************************************************************************/
  149. // 函数名称:FMaskWriteReg
  150. // 输入参数:Response
  151. // 输出参数:无
  152. // 功能描述:处理屏蔽寄存器指令22
  153. /****************************************************************************************/
  154. void FMaskWriteReg(PDU_RESPONSE *Response);
  155. /****************************************************************************************/
  156. // 函数名称:FRWMultipleReg
  157. // 输入参数:Response
  158. // 输出参数:无
  159. // 功能描述:处理读写多寄存器指令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},                        // 读线圈
  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},        // 写单个线圈
  178. #endif
  179. #if WRITE_SING_REG_EN > 0
  180.         {0x06,FWriteSingleReg},                // 写单个寄存器
  181. #endif
  182. #if WRITE_MULT_COIL_EN > 0
  183.         {0x0f,FWriteMultipleCoils},        // 写多个线圈
  184. #endif
  185. #if WRITE_MULT_REG_EN > 0
  186.         {0x10,FWriteMultipleReg},        // 写多个寄存器
  187. #endif
  188. #if MASK_WRITE_REG_EN > 0
  189.         {0x16,FMaskWriteReg},                // 处理屏蔽寄存器指令
  190. #endif
  191. #if READ_WRITE_REG_EN > 0
  192.         {0x17,FRWMultipleReg},                // 读写多个寄存器
  193. #endif
  194.         {0x00,FTest}                                // 测试功能代码
  195. };

  196. #if READ_DIS_INPUT_EN
  197. //************************************************************************************
  198. // 函数名称:ReadDiscreteInputs
  199. // 输入参数:CoilsDataPtr,存放离散输入数据指针
  200. //                         StAddr,离散的起始地址
  201. //                         Quantity,离散的数量
  202. // 输出参数:正常返回TRUE,出错返回FALSE。
  203. // 功能描述:读离散输入操作函数
  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++)                // 将线圈值写入一个字节
  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. // 函数名称:ReadCoils
  229. // 输入参数:CoilsDataPtr,存放线圈数据指针
  230. //                         StAddr,线圈的起始地址
  231. //                         Quantity,线圈的数量
  232. // 输出参数:正常返回TRUE,出错返回FALSE。
  233. // 功能描述:读多线圈操作函数
  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++)                // 将线圈值写入一个字节
  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. // 函数名称:WriteSingleCoil
  259. // 输入参数:DataPtr,数据指针,
  260. //                         StAddr,寄存器起始地址
  261. //                         Quantity,寄存器数量。
  262. // 输出参数:正常返回TRUE,出错返回FALSE。
  263. // 功能描述:写单线圈处理函数
  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. // 函数名称:WriteMultipleCoils
  273. // 输入参数:DataPtr,数据指针,
  274. //                         StAddr,寄存器起始地址
  275. //                         Quantity,寄存器数量。
  276. // 输出参数:正常返回TRUE,出错返回FALSE。
  277. // 功能描述:写多线圈处理函数
  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. // 函数名称:ReadInputReg
  296. // 输入参数:DataPtr,数据指针,
  297. //                         StAddr,寄存器起始地址
  298. //                         Quantity,寄存器数量。
  299. // 输出参数:正常返回TRUE,出错返回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. // 函数名称:ReadHoldingReg
  318. // 输入参数:DataPtr,数据指针,16位数据高8位在低字节,低8位在高字节
  319. //                         StAddr,寄存器起始地址
  320. //                         Quantity,寄存器数量。
  321. // 输出参数:正常返回TRUE,出错返回FALSE。
  322. // 功能描述:读寄存器处理函数
  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. // 函数名称:WriteHoldingReg
  340. // 输入参数:DataPtr,数据指针,16位数据高8位在低字节,低8位在高字节
  341. //                         StAddr,寄存器起始地址
  342. //                         Quantity,寄存器数量。
  343. // 输出参数:正常返回TRUE,出错返回FALSE。
  344. // 功能描述:写寄存器处理函数
  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. // 函数名称:FReadCoils
  361. // 输入参数:Response,为PDU_RESPONSE类型的指针,PDU_RESPONSE:
  362. //                         typedef struct __PDU_RESPONSE{
  363. //                                uint8*        PDUDataPtr;   请求数据指针,功能代码处理函数必需将处理的数据包存在该指针的开始位始
  364. //                                  uint8        PDUByteLength;请求数据数长度
  365. //                                uint8        ExceptionCode;仅为输出错异常代码,正常操作设为0
  366. //                         }PDU_RESPONSE
  367. // 输出参数:无
  368. // 功能描述:处理读多线圈指令01
  369. /***************************************************************************************/
  370. void FReadCoils(PDU_RESPONSE *Response)
  371. {
  372.         uint8_t * PDUPtr;
  373.         uint16_t StAddr ,Quantity;
  374.         // 从请求PDU中提取相关参数
  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) ;        // 正常返回的数据长度
  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;        // 字节数
  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. // 函数名称:FReadDiscreteInputs
  403. // 输入参数:Response
  404. // 输出参数:无
  405. // 功能描述:处理读离散输入指令02
  406. /***************************************************************************************/
  407. void FReadDiscreteInputs(PDU_RESPONSE *Response)
  408. {
  409.         uint8_t * PDUPtr;
  410.         uint16_t StAddr ,Quantity;
  411.         // 从请求PDU中提取相关参数
  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) ;        // 正常返回的数据长度
  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;        // 字节数
  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. // 函数名称:FReadHoldingReg
  440. // 输入参数:Response
  441. // 输出参数:无
  442. // 功能描述:处理读保持寄存器指令03
  443. /****************************************************************************************/
  444. void FReadHoldingReg(PDU_RESPONSE *Response)
  445. {
  446.         uint8_t * PDUPtr;
  447.         uint16_t StAddr ,Quantity;
  448.         // 从请求PDU中提取相关参数
  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 ;        // 正常返回的数据长度
  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. // 函数名称:FReadInputReg
  477. // 输入参数:Response
  478. // 输出参数:无
  479. // 功能描述:处理读输入寄存器指令04
  480. /****************************************************************************************/
  481. void FReadInputReg(PDU_RESPONSE *Response)
  482. {
  483.         uint8_t * PDUPtr;
  484.         uint16_t StAddr ,Quantity;
  485.         // 从请求PDU中提取相关参数
  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 ;        // 正常返回的数据长度
  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. // 函数名称:FWriteSingleCoil
  514. // 输入参数:Response
  515. // 输出参数:无
  516. // 功能描述:处理写单线圈指令05
  517. /****************************************************************************************/
  518. void FWriteSingleCoil(PDU_RESPONSE *Response)
  519. {
  520.         uint8_t * PDUPtr;
  521.         uint16_t OutputAddr ,OutputValue;
  522.         // 从请求PDU中提取相关参数
  523.         PDUPtr = Response->PDUDataPtr;
  524.         OutputAddr = PDUPtr[1]<<8|PDUPtr[2];
  525.         OutputValue =  PDUPtr[3]<<8|PDUPtr[4];
  526.         
  527.         Response->PDUByteLength = 5 ;        // 正常返回的数据长度
  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. // 函数名称:FWriteSingleReg
  554. // 输入参数:Response
  555. // 输出参数:无
  556. // 功能描述:处理写单线圈指令06
  557. /****************************************************************************************/
  558. void FWriteSingleReg(PDU_RESPONSE *Response)
  559. {
  560.         uint8 * PDUPtr;
  561.         uint16 OutputAddr ,OutputValue;
  562.         // 从请求PDU中提取相关参数
  563.         PDUPtr = Response->PDUDataPtr;
  564.         OutputAddr = PDUPtr[1]<<8|PDUPtr[2];
  565.         OutputValue =  PDUPtr[3]<<8|PDUPtr[4];
  566.         
  567.         Response->PDUByteLength = 2 + 5 ;        // 正常返回的数据长度
  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. // 函数名称:FWriteMultipleCoils
  594. // 输入参数:Response
  595. // 输出参数:无
  596. // 功能描述:处理写多线圈指令15
  597. /****************************************************************************************/
  598. void FWriteMultipleCoils(PDU_RESPONSE *Response)
  599. {
  600.         uint8_t * PDUPtr;
  601.         uint16_t StAddr ,Quantity;
  602.         uint8_t         ByteCount;
  603.         // 从请求PDU中提取相关参数
  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 ;        // 正常返回的数据长度

  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. // 函数名称:FWriteMultipleReg
  635. // 输入参数:Response
  636. // 输出参数:无
  637. // 功能描述:处理写多寄存器指令16
  638. /****************************************************************************************/
  639. void FWriteMultipleReg(PDU_RESPONSE *Response)
  640. {
  641.         uint8_t * PDUPtr;
  642.         uint16_t StAddr ,Quantity;
  643.         uint8_t         ByteCount;
  644.         // 从请求PDU中提取相关参数
  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 ;        // 正常返回的数据长度

  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. // 函数名称:FMaskWriteReg
  676. // 输入参数:Response
  677. // 输出参数:无
  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. // 函数名称:FRWMultipleReg
  723. // 输入参数:Response
  724. // 输出参数:无
  725. // 功能描述:处理读写多寄存器指令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)&&                // 读寄存器的数量是否在有效范围内
  744.            (WriteQuantity>=0x001)&&(WriteQuantity<=0x0079)&&        // 写寄存器的数量是否在有效范围内
  745.            (WriteBytes==(WriteQuantity*2)))                                                // 接收到的字节数是否与写入的寄存器数量一至
  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))        // 写寄存器
  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












复制代码


评分

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

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:151192 发表于 2016-11-30 13:11 | 只看该作者
你好,我想将单片机读取的 一个温度值通过modbus协议 传输到上位机  我的设计思路应该是怎样的呢 能把我简单的说明下吗  谢谢你了!
回复

使用道具 举报

板凳
ID:156580 发表于 2017-1-10 10:18 | 只看该作者
这个资料很好,尤其是在工业控制应用方面,能制作成符合工业标准的控制器
回复

使用道具 举报

地板
ID:698773 发表于 2020-2-28 15:56 来自手机 | 只看该作者
lisc5920 发表于 2016-11-30 13:11
你好,我想将单片机读取的 一个温度值通过modbus协议 传输到上位机  我的设计思路应该是怎样的呢 能把我简 ...

你的问题解决没有?
回复

使用道具 举报

5#
ID:698773 发表于 2020-2-28 16:00 来自手机 | 只看该作者
这个有原理图嘛?
回复

使用道具 举报

6#
ID:595103 发表于 2021-9-22 13:14 | 只看该作者
好资料,接下来的设计正好需要用到MODbus
回复

使用道具 举报

7#
ID:138205 发表于 2022-1-26 21:40 | 只看该作者
路过学习,好东西,收藏一下,
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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