user_mb_app.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. #include "user_mb_app.h"
  2. /*------------------------Slave mode use these variables----------------------*/
  3. //Slave mode:DiscreteInputs variables
  4. USHORT usSDiscInStart = S_DISCRETE_INPUT_START;
  5. #if S_DISCRETE_INPUT_NDISCRETES%8
  6. UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8+1];
  7. #else
  8. UCHAR ucSDiscInBuf[S_DISCRETE_INPUT_NDISCRETES/8] ;
  9. #endif
  10. //Slave mode:Coils variables
  11. USHORT usSCoilStart = S_COIL_START;
  12. #if S_COIL_NCOILS%8
  13. UCHAR ucSCoilBuf[S_COIL_NCOILS/8+1] ;
  14. #else
  15. UCHAR ucSCoilBuf[S_COIL_NCOILS/8] ;
  16. #endif
  17. //Slave mode:InputRegister variables
  18. USHORT usSRegInStart = S_REG_INPUT_START;
  19. USHORT usSRegInBuf[S_REG_INPUT_NREGS] ;
  20. //Slave mode:HoldingRegister variables
  21. USHORT usSRegHoldStart = S_REG_HOLDING_START;
  22. USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] ;
  23. /*-----------------------Master mode use these variables----------------------*/
  24. #if MB_MASTER_RTU_ENABLED > 0 || MB_MASTER_ASCII_ENABLED > 0
  25. //Master mode:DiscreteInputs variables
  26. USHORT usMDiscInStart = M_DISCRETE_INPUT_START;
  27. #if M_DISCRETE_INPUT_NDISCRETES%8
  28. UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8+1];
  29. #else
  30. UCHAR ucMDiscInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_DISCRETE_INPUT_NDISCRETES/8];
  31. #endif
  32. //Master mode:Coils variables
  33. USHORT usMCoilStart = M_COIL_START;
  34. #if M_COIL_NCOILS%8
  35. UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8+1];
  36. #else
  37. UCHAR ucMCoilBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_COIL_NCOILS/8];
  38. #endif
  39. //Master mode:InputRegister variables
  40. USHORT usMRegInStart = M_REG_INPUT_START;
  41. USHORT usMRegInBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_INPUT_NREGS];
  42. //Master mode:HoldingRegister variables
  43. USHORT usMRegHoldStart = M_REG_HOLDING_START;
  44. USHORT usMRegHoldBuf[MB_MASTER_TOTAL_SLAVE_NUM][M_REG_HOLDING_NREGS];
  45. #endif
  46. //******************************输入寄存器回调函数**********************************
  47. //函数定义: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
  48. //描 述:输入寄存器相关的功能(读、连续读)
  49. //入口参数:pucRegBuffer : 回调函数将Modbus寄存器的当前值写入的缓冲区
  50. // usAddress : 寄存器的起始地址,输入寄存器的地址范围是1-65535。
  51. // usNRegs : 寄存器数量
  52. //出口参数:eMBErrorCode : 这个函数将返回的错误码
  53. //备 注:Editor:Armink 2010-10-31 Company: BXXJS
  54. //**********************************************************************************
  55. eMBErrorCode
  56. eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
  57. {
  58. eMBErrorCode eStatus = MB_ENOERR;
  59. int iRegIndex;
  60. USHORT * pusRegInputBuf;
  61. UCHAR REG_INPUT_START;
  62. UCHAR REG_INPUT_NREGS;
  63. UCHAR usRegInStart;
  64. //Determine the master or slave
  65. if (xMBMasterGetCBRunInMasterMode())
  66. {
  67. pusRegInputBuf = usMRegInBuf[ucMBMasterGetDestAddress()];
  68. REG_INPUT_START = M_REG_INPUT_START;
  69. REG_INPUT_NREGS = M_REG_INPUT_NREGS;
  70. usRegInStart = usMRegInStart;
  71. }
  72. else
  73. {
  74. pusRegInputBuf = usSRegInBuf;
  75. REG_INPUT_START = S_REG_INPUT_START;
  76. REG_INPUT_NREGS = S_REG_INPUT_NREGS;
  77. usRegInStart = usSRegInStart;
  78. }
  79. if( ( usAddress >= REG_INPUT_START )
  80. && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
  81. {
  82. iRegIndex = ( int )( usAddress - usRegInStart );
  83. while( usNRegs > 0 )
  84. {
  85. //Determine the master or slave
  86. if (xMBMasterGetCBRunInMasterMode())
  87. {
  88. pusRegInputBuf[iRegIndex] = *pucRegBuffer++ << 8;
  89. pusRegInputBuf[iRegIndex] |= *pucRegBuffer++;
  90. }
  91. else
  92. {
  93. *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] >> 8 );
  94. *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] & 0xFF );
  95. }
  96. iRegIndex++;
  97. usNRegs--;
  98. }
  99. }
  100. else
  101. {
  102. eStatus = MB_ENOREG;
  103. }
  104. return eStatus;
  105. }
  106. //******************************保持寄存器回调函数**********************************
  107. //函数定义: eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
  108. //描 述:保持寄存器相关的功能(读、连续读、写、连续写)
  109. //入口参数:pucRegBuffer : 如果需要更新用户寄存器数值,这个缓冲区必须指向新的寄存器数值。
  110. // 如果协议栈想知道当前的数值,回调函数必须将当前值写入这个缓冲区
  111. // usAddress : 寄存器的起始地址。
  112. // usNRegs : 寄存器数量
  113. // eMode : 如果该参数为eMBRegisterMode::MB_REG_WRITE,用户的应用数值将从pucRegBuffer中得到更新。
  114. // 如果该参数为eMBRegisterMode::MB_REG_READ,用户需要将当前的应用数据存储在pucRegBuffer中
  115. //出口参数:eMBErrorCode : 这个函数将返回的错误码
  116. //备 注:Editor:Armink 2010-10-31 Company: BXXJS
  117. //**********************************************************************************
  118. eMBErrorCode
  119. eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
  120. {
  121. eMBErrorCode eStatus = MB_ENOERR;
  122. int iRegIndex;
  123. USHORT * pusRegHoldingBuf;
  124. UCHAR REG_HOLDING_START;
  125. UCHAR REG_HOLDING_NREGS;
  126. UCHAR usRegHoldStart;
  127. //Determine the master or slave
  128. if (xMBMasterGetCBRunInMasterMode())
  129. {
  130. pusRegHoldingBuf = usMRegHoldBuf[ucMBMasterGetDestAddress()];
  131. REG_HOLDING_START = M_REG_HOLDING_START;
  132. REG_HOLDING_NREGS = M_REG_HOLDING_NREGS;
  133. usRegHoldStart = usMRegHoldStart;
  134. //If mode is read,the master will wirte the received date to bufffer.
  135. eMode = MB_REG_WRITE;
  136. }
  137. else
  138. {
  139. pusRegHoldingBuf = usSRegHoldBuf;
  140. REG_HOLDING_START = S_REG_HOLDING_START;
  141. REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
  142. usRegHoldStart = usSRegHoldStart;
  143. }
  144. if( ( usAddress >= REG_HOLDING_START ) &&
  145. ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
  146. {
  147. iRegIndex = ( int )( usAddress - usRegHoldStart );
  148. switch ( eMode )
  149. {
  150. /* Pass current register values to the protocol stack. */
  151. case MB_REG_READ:
  152. while( usNRegs > 0 )
  153. {
  154. *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] >> 8 );
  155. *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] & 0xFF );
  156. iRegIndex++;
  157. usNRegs--;
  158. }
  159. break;
  160. /* Update current register values with new values from the
  161. * protocol stack. */
  162. case MB_REG_WRITE:
  163. while( usNRegs > 0 )
  164. {
  165. pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
  166. pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
  167. iRegIndex++;
  168. usNRegs--;
  169. }
  170. break;
  171. }
  172. }
  173. else
  174. {
  175. eStatus = MB_ENOREG;
  176. }
  177. return eStatus;
  178. }
  179. //****************************线圈状态寄存器回调函数********************************
  180. //函数定义: eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
  181. //描 述:线圈状态寄存器相关的功能(读、连续读、写、连续写)
  182. //入口参数:pucRegBuffer : 位组成一个字节,起始寄存器对应的位处于该字节pucRegBuffer的最低位LSB。
  183. // 如果回调函数要写这个缓冲区,没有用到的线圈(例如不是8个一组的线圈状态)对应的位的数值必须设置位0。
  184. // usAddress : 第一个线圈地址。
  185. // usNCoils : 请求的线圈个数
  186. // eMode ;如果该参数为eMBRegisterMode::MB_REG_WRITE,用户的应用数值将从pucRegBuffer中得到更新。
  187. // 如果该参数为eMBRegisterMode::MB_REG_READ,用户需要将当前的应用数据存储在pucRegBuffer中
  188. //出口参数:eMBErrorCode : 这个函数将返回的错误码
  189. //备 注:Editor:Armink 2010-10-31 Company: BXXJS
  190. //**********************************************************************************
  191. eMBErrorCode
  192. eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
  193. {
  194. eMBErrorCode eStatus = MB_ENOERR;
  195. int iRegIndex , iRegBitIndex , iNReg;
  196. UCHAR * pucCoilBuf;
  197. UCHAR COIL_START;
  198. UCHAR COIL_NCOILS;
  199. UCHAR usCoilStart;
  200. iNReg = usNCoils / 8 + 1; //占用寄存器数量
  201. //Determine the master or slave
  202. if (xMBMasterGetCBRunInMasterMode())
  203. {
  204. pucCoilBuf = ucMCoilBuf[ucMBMasterGetDestAddress()];
  205. COIL_START = M_COIL_START;
  206. COIL_NCOILS = M_COIL_NCOILS;
  207. usCoilStart = usMCoilStart;
  208. //If mode is read,the master will wirte the received date to bufffer.
  209. eMode = MB_REG_WRITE;
  210. }
  211. else
  212. {
  213. pucCoilBuf = ucSCoilBuf;
  214. COIL_START = S_COIL_START;
  215. COIL_NCOILS = S_COIL_NCOILS;
  216. usCoilStart = usSCoilStart;
  217. }
  218. if( ( usAddress >= COIL_START ) &&
  219. ( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
  220. {
  221. iRegIndex = ( int )( usAddress - usCoilStart ) / 8 ; //每个寄存器存8个
  222. iRegBitIndex = ( int )( usAddress - usCoilStart ) % 8 ; //相对于寄存器内部的位地址
  223. switch ( eMode )
  224. {
  225. /* Pass current coil values to the protocol stack. */
  226. case MB_REG_READ:
  227. while( iNReg > 0 )
  228. {
  229. *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex , 8);
  230. iNReg --;
  231. }
  232. pucRegBuffer --;
  233. usNCoils = usNCoils % 8; //余下的线圈数
  234. *pucRegBuffer = *pucRegBuffer <<(8 - usNCoils); //高位补零
  235. *pucRegBuffer = *pucRegBuffer >>(8 - usNCoils);
  236. break;
  237. /* Update current coil values with new values from the
  238. * protocol stack. */
  239. case MB_REG_WRITE:
  240. while(iNReg > 1) //最后面余下来的数单独算
  241. {
  242. xMBUtilSetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex , 8 , *pucRegBuffer++);
  243. iNReg--;
  244. }
  245. usNCoils = usNCoils % 8; //余下的线圈数
  246. if (usNCoils != 0) //xMBUtilSetBits方法 在操作位数量为0时存在bug
  247. {
  248. xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
  249. *pucRegBuffer++);
  250. }
  251. break;
  252. }
  253. }
  254. else
  255. {
  256. eStatus = MB_ENOREG;
  257. }
  258. return eStatus;
  259. }
  260. //****************************离散输入寄存器回调函数********************************
  261. //函数定义: eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
  262. //描 述:离散输入寄存器相关的功能(读、连续读)
  263. //入口参数:pucRegBuffer : 用当前的线圈数据更新这个寄存器,起始寄存器对应的位处于该字节pucRegBuffer的最低位LSB。
  264. // 如果回调函数要写这个缓冲区,没有用到的线圈(例如不是8个一组的线圈状态)对应的位的数值必须设置为0。
  265. // usAddress : 离散输入的起始地址
  266. // usNDiscrete : 离散输入点数量
  267. //出口参数:eMBErrorCode : 这个函数将返回的错误码
  268. //备 注:Editor:Armink 2010-10-31 Company: BXXJS
  269. //**********************************************************************************
  270. eMBErrorCode
  271. eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
  272. {
  273. eMBErrorCode eStatus = MB_ENOERR;
  274. int iRegIndex , iRegBitIndex , iNReg;
  275. UCHAR * pucDiscreteInputBuf;
  276. UCHAR DISCRETE_INPUT_START;
  277. UCHAR DISCRETE_INPUT_NDISCRETES;
  278. UCHAR usDiscreteInputStart;
  279. iNReg = usNDiscrete / 8 + 1; //占用寄存器数量
  280. //Determine the master or slave
  281. if (xMBMasterGetCBRunInMasterMode())
  282. {
  283. pucDiscreteInputBuf = ucMDiscInBuf[ucMBMasterGetDestAddress()];
  284. DISCRETE_INPUT_START = M_DISCRETE_INPUT_START;
  285. DISCRETE_INPUT_NDISCRETES = M_DISCRETE_INPUT_NDISCRETES;
  286. usDiscreteInputStart = usMDiscInStart;
  287. }
  288. else
  289. {
  290. pucDiscreteInputBuf = ucSDiscInBuf;
  291. DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
  292. DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
  293. usDiscreteInputStart = usSDiscInStart;
  294. }
  295. if( ( usAddress >= DISCRETE_INPUT_START )
  296. && ( usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES ) )
  297. {
  298. iRegIndex = ( int )( usAddress - usDiscreteInputStart ) / 8 ; //每个寄存器存8个
  299. iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ; //相对于寄存器内部的位地址
  300. //Determine the master or slave
  301. if (xMBMasterGetCBRunInMasterMode())
  302. {
  303. /* Update current coil values with new values from the
  304. * protocol stack. */
  305. while(iNReg > 1) //最后面余下来的数单独算
  306. {
  307. xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8 , *pucRegBuffer++);
  308. iNReg--;
  309. }
  310. usNDiscrete = usNDiscrete % 8; //余下的线圈数
  311. if (usNDiscrete != 0) //xMBUtilSetBits方法 在操作位数量为0时存在bug
  312. {
  313. xMBUtilSetBits(&pucDiscreteInputBuf[iRegIndex++], iRegBitIndex,
  314. usNDiscrete, *pucRegBuffer++);
  315. }
  316. }
  317. else
  318. {
  319. while( iNReg > 0 )
  320. {
  321. *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8);
  322. iNReg --;
  323. }
  324. pucRegBuffer --;
  325. usNDiscrete = usNDiscrete % 8; //余下的线圈数
  326. *pucRegBuffer = *pucRegBuffer <<(8 - usNDiscrete); //高位补零
  327. *pucRegBuffer = *pucRegBuffer >>(8 - usNDiscrete);
  328. }
  329. }
  330. else
  331. {
  332. eStatus = MB_ENOREG;
  333. }
  334. return eStatus;
  335. }