You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
4.6 KiB

12 months ago
12 months ago
12 months ago
12 months ago
  1. #include "modbus_block_host.hpp"
  2. #include "modbus_basic.hpp"
  3. using namespace iflytop;
  4. #define PRV_DEBUG 0
  5. ModbusBlockHost::ModbusBlockHost() {}
  6. ModbusBlockHost::~ModbusBlockHost() {}
  7. extern "C" {
  8. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {}
  9. }
  10. void ModbusBlockHost::initialize(UART_HandleTypeDef *huart) {
  11. this->huart = huart;
  12. m_modbus_lock.init();
  13. }
  14. void ModbusBlockHost::enableDump(bool enable) { m_dump = enable; }
  15. void ModbusBlockHost::cleanRxBuff() { //
  16. HAL_StatusTypeDef status;
  17. do {
  18. status = HAL_UART_Receive(huart, rxbuff, 1, 1);
  19. } while (status == HAL_OK);
  20. }
  21. void ModbusBlockHost::uarttx(uint8_t *buff, size_t len) {
  22. ZASSERT(len < sizeof(txbuff));
  23. if (m_dump) {
  24. printf("uart_tx:\n");
  25. for (size_t i = 0; i < len; i++) {
  26. printf("%02x ", buff[i]);
  27. }
  28. printf("\n");
  29. }
  30. // HAL_UART_Transmit(huart, buff, len, 1000);
  31. HAL_UART_DMAStop(huart);
  32. HAL_StatusTypeDef ret = HAL_UART_Transmit_DMA(huart, buff, len);
  33. ZASSERT(ret == HAL_OK);
  34. // 等待DMA传输完成
  35. while (true) {
  36. if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) break;
  37. }
  38. return;
  39. }
  40. bool ModbusBlockHost::uartrx(uint8_t *buff, size_t len, int overtimems) {
  41. HAL_StatusTypeDef status;
  42. ZASSERT(len < sizeof(rxbuff));
  43. status = HAL_UART_Receive_DMA(huart, buff, len);
  44. if (status != HAL_OK) {
  45. return false;
  46. }
  47. for (size_t i = 0; i < overtimems; i++) {
  48. osDelay(3);
  49. if (HAL_UART_GetState(huart) == HAL_UART_STATE_READY) {
  50. if (m_dump) {
  51. if (status == HAL_OK) {
  52. printf("uart_rx:");
  53. for (size_t i = 0; i < len; i++) {
  54. printf("%02x ", buff[i]);
  55. }
  56. printf("\n");
  57. }
  58. }
  59. return true;
  60. }
  61. }
  62. #if PRV_DEBUG
  63. printf("uart_rx timeout\n");
  64. #endif
  65. HAL_UART_Abort(huart);
  66. HAL_UART_DMAStop(huart);
  67. return false;
  68. }
  69. bool ModbusBlockHost::readReg03(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int overtimems) {
  70. zlock_guard lck(m_modbus_lock);
  71. txbuff[0] = slaveAddr;
  72. txbuff[1] = 0x03;
  73. txbuff[2] = regAddr >> 8;
  74. txbuff[3] = regAddr & 0xff;
  75. txbuff[4] = 0x00;
  76. txbuff[5] = 0x01;
  77. modbus_pack_crc_to_packet(txbuff, 6 + 2);
  78. cleanRxBuff();
  79. uarttx(txbuff, 6 + 2);
  80. bool status;
  81. status = uartrx(rxbuff, 5 + 2, overtimems);
  82. if (!status) {
  83. return false;
  84. }
  85. if (!modbus_checkcrc16(rxbuff, 7)) {
  86. ZLOGE("ModbusBlockHost", "crc error");
  87. return false;
  88. }
  89. *regVal = (((uint16_t)(rxbuff[3])) << 8) | rxbuff[4];
  90. return true;
  91. }
  92. // static const char *hex2str(uint8_t *buff, size_t len) {
  93. // static char str[100];
  94. // for (size_t i = 0; i < len; i++) {
  95. // sprintf(str + i * 2, "%02x", buff[i]);
  96. // }
  97. // return str;
  98. // }
  99. bool ModbusBlockHost::readReg03Muti(uint8_t slaveAddr, uint16_t regAddr, uint16_t *regVal, int regNum, int overtimems) {
  100. zlock_guard lck(m_modbus_lock);
  101. txbuff[0] = slaveAddr;
  102. txbuff[1] = 0x03;
  103. txbuff[2] = regAddr >> 8;
  104. txbuff[3] = regAddr & 0xff;
  105. txbuff[4] = 0x00;
  106. txbuff[5] = regNum;
  107. modbus_pack_crc_to_packet(txbuff, 6 + 2);
  108. cleanRxBuff();
  109. uarttx(txbuff, 6 + 2);
  110. bool status;
  111. // 14*2 = 28
  112. status = uartrx(rxbuff, 5 + regNum * 2, overtimems);
  113. if (!status) {
  114. return false;
  115. }
  116. if (!modbus_checkcrc16(rxbuff, 5 + regNum * 2)) {
  117. ZLOGE("ModbusBlockHost", "crc error");
  118. return false;
  119. }
  120. for (int i = 0; i < regNum; i++) {
  121. regVal[i] = ((uint16_t)(rxbuff[3 + i * 2]) << 8) | rxbuff[4 + i * 2];
  122. // int16_t val = regVal[i] ;
  123. // ZLOGI("RX", "%d", val);
  124. }
  125. return true;
  126. }
  127. bool ModbusBlockHost::writeReg06(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
  128. zlock_guard lck(m_modbus_lock);
  129. txbuff[0] = slaveAddr;
  130. txbuff[1] = 0x06;
  131. txbuff[2] = regAddr >> 8;
  132. txbuff[3] = regAddr & 0xff;
  133. txbuff[4] = regVal >> 8;
  134. txbuff[5] = regVal & 0xff;
  135. modbus_pack_crc_to_packet(txbuff, 6 + 2);
  136. cleanRxBuff();
  137. uarttx(txbuff, 6 + 2);
  138. bool status;
  139. status = uartrx(rxbuff, 8, overtimems);
  140. if (status && modbus_checkcrc16(rxbuff, 8)) {
  141. return true;
  142. }
  143. return false;
  144. }
  145. bool ModbusBlockHost::writeReg10(uint8_t slaveAddr, uint16_t regAddr, uint16_t regVal, int overtimems) {
  146. zlock_guard lck(m_modbus_lock);
  147. txbuff[0] = slaveAddr;
  148. txbuff[1] = 0x10;
  149. txbuff[2] = regAddr >> 8;
  150. txbuff[3] = regAddr & 0xff;
  151. txbuff[4] = 0x00;
  152. txbuff[5] = 0x01;
  153. txbuff[6] = 0x02; // 字节数
  154. txbuff[7] = regVal >> 8;
  155. txbuff[8] = regVal & 0xff;
  156. modbus_pack_crc_to_packet(txbuff, 9 + 2);
  157. cleanRxBuff();
  158. uarttx(txbuff, 9 + 2);
  159. bool status;
  160. status = uartrx(rxbuff, 8, overtimems);
  161. if (status && modbus_checkcrc16(rxbuff, 8)) {
  162. return true;
  163. }
  164. return false;
  165. }