test_modbus_rtu_matser.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. #include "stdio.h"
  2. #include "string.h"
  3. #include "board.h"
  4. #include "small_modbus.h"
  5. #include "board_virtualIO.h"
  6. static small_modbus_t modbus_rtu_master = {0};
  7. //#define MODBUS_PRINTF(...)
  8. #define MODBUS_PRINTF(...) modbus_debug_info((&modbus_rtu_master), __VA_ARGS__)
  9. // rtthread device name
  10. #define UART_DEVICE_NAME "uart2"
  11. // rtthread pin index
  12. static int rs485_rts_pin = 0;
  13. //收发控制引脚回调函数
  14. static int uart_rts(int on)
  15. {
  16. if (on)
  17. {
  18. rt_pin_write(rs485_rts_pin, PIN_HIGH);
  19. rt_thread_mdelay(2); // 9600 bps 3.5 个字符延迟时间
  20. }
  21. else
  22. {
  23. rt_thread_mdelay(2); // 9600 bps 3.5 个字符延迟时间
  24. rt_pin_write(rs485_rts_pin, PIN_LOW);
  25. }
  26. return 0;
  27. }
  28. static int count_ok = 0;
  29. static int count_err = 0;
  30. #define MASTER_SEM_POLL
  31. #ifdef MASTER_SEM_POLL
  32. // send modbus 的信号量
  33. struct rt_semaphore send_modbus_sem;
  34. //实现vio立即通知master发送modbus写指令
  35. RT_WEAK void vio_lowlevel_update(void)
  36. {
  37. rt_sem_release(&(send_modbus_sem));
  38. }
  39. // msh命令行调用函数
  40. void test_modbus_rtu_master_sem(void)
  41. {
  42. vio_lowlevel_update();
  43. }
  44. // msh命令行启动
  45. #if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
  46. #include <finsh.h>
  47. MSH_CMD_EXPORT(test_modbus_rtu_master_sem, test_modbus_rtu_master sem);
  48. #endif
  49. #endif
  50. static uint8_t temp_buff[256];
  51. void master_sem_poll(small_modbus_t *smb_master)
  52. {
  53. int index = 0;
  54. int rc = rt_sem_take(&(send_modbus_sem), 3000); //等待vio_lowlevel_update释放信号量,如果没有会一直等待3000ms
  55. if (rc == RT_EOK) //释放成功
  56. {
  57. vio_read_hold_coils(0, 16, temp_buff); //从vio读取保持寄存器值
  58. modbus_error_recovery(smb_master);
  59. modbus_set_slave(smb_master, 1);
  60. rc = modbus_write_bits(smb_master, 00000, 16, temp_buff); // modbus_write_bits
  61. MODBUS_PRINTF("modbus_write_bits:%d\n", rc);
  62. if (rc >= MODBUS_OK)
  63. {
  64. count_ok++;
  65. }
  66. else
  67. {
  68. count_err++;
  69. }
  70. rt_thread_mdelay(10);
  71. modbus_error_recovery(smb_master);
  72. modbus_set_slave(smb_master, 1);
  73. rc = modbus_read_input_bits(smb_master, 10000, 8, temp_buff); // modbus_read_input_bits
  74. MODBUS_PRINTF("modbus_read_input_bits:%d\n", rc);
  75. if (rc >= MODBUS_OK)
  76. {
  77. vio_lowlevel_update_input_coils(0, 8, temp_buff); //更新输入寄存器的值到vio
  78. for (index = 0; index < 8; index++)
  79. {
  80. rt_kprintf("[%d]", dio_get_val(temp_buff, index));
  81. }
  82. rt_kputs("\n\r");
  83. count_ok++;
  84. }
  85. else
  86. {
  87. count_err++;
  88. }
  89. }
  90. }
  91. void master_poll(small_modbus_t *smb_master)
  92. {
  93. int rc = 0;
  94. int index = 0;
  95. rt_thread_mdelay(30);
  96. modbus_error_recovery(smb_master);
  97. modbus_set_slave(smb_master, 1);
  98. rc = modbus_read_input_bits(smb_master, 10000, 8, temp_buff); // modbus_read_input_bits
  99. MODBUS_PRINTF("modbus_read_input_bits:%d\n", rc);
  100. if (rc >= MODBUS_OK)
  101. {
  102. for (index = 0; index < 8; index++)
  103. {
  104. rt_kprintf("[%d]", dio_get_val(temp_buff, index));
  105. }
  106. rt_kputs("\n\r");
  107. count_ok++;
  108. }
  109. else
  110. {
  111. count_err++;
  112. }
  113. rt_thread_mdelay(30);
  114. modbus_error_recovery(smb_master);
  115. modbus_set_slave(smb_master, 1);
  116. rc = modbus_write_bits(smb_master, 00000, 8, temp_buff); // modbus_write_bits
  117. MODBUS_PRINTF("modbus_write_bits:%d\n", rc);
  118. if (rc >= MODBUS_OK)
  119. {
  120. count_ok++;
  121. }
  122. else
  123. {
  124. count_err++;
  125. }
  126. rt_thread_mdelay(30);
  127. modbus_error_recovery(smb_master);
  128. modbus_set_slave(smb_master, 1);
  129. rc = modbus_read_bits(smb_master, 00000, 8, temp_buff); // modbus_read_bits
  130. MODBUS_PRINTF("modbus_read_bits:%d\n", rc);
  131. if (rc >= MODBUS_OK)
  132. {
  133. for (index = 0; index < 8; index++)
  134. {
  135. rt_kprintf("[%d]", dio_get_val(temp_buff, index));
  136. }
  137. rt_kputs("\n\r");
  138. count_ok++;
  139. }
  140. else
  141. {
  142. count_err++;
  143. }
  144. rt_thread_mdelay(30);
  145. modbus_error_recovery(smb_master);
  146. modbus_set_slave(smb_master, 1);
  147. rc = modbus_read_input_registers(smb_master, 30000, 8, (uint16_t *)temp_buff); // modbus_read_input_registers
  148. MODBUS_PRINTF("modbus_read_input_registers:%d\n", rc);
  149. if (rc >= MODBUS_OK)
  150. {
  151. for (index = 0; index < 8; index++)
  152. {
  153. rt_kprintf("[%d]", aio_get_val((uint16_t *)temp_buff, index));
  154. }
  155. rt_kputs("\n\r");
  156. count_ok++;
  157. }
  158. else
  159. {
  160. count_err++;
  161. }
  162. rt_thread_mdelay(30);
  163. modbus_error_recovery(smb_master);
  164. modbus_set_slave(smb_master, 1);
  165. rc = modbus_write_registers(smb_master, 40000, 8, (uint16_t *)temp_buff); // modbus_write_registers
  166. MODBUS_PRINTF("modbus_write_registers:%d\n", rc);
  167. if (rc >= MODBUS_OK)
  168. {
  169. count_ok++;
  170. }
  171. else
  172. {
  173. count_err++;
  174. }
  175. rt_thread_mdelay(30);
  176. modbus_error_recovery(smb_master);
  177. modbus_set_slave(smb_master, 1);
  178. rc = modbus_read_registers(smb_master, 40000, 8, (uint16_t *)temp_buff); // modbus_read_registers
  179. MODBUS_PRINTF("modbus_read_registers:%d\n", rc);
  180. if (rc >= MODBUS_OK)
  181. {
  182. for (index = 0; index < 8; index++)
  183. {
  184. rt_kprintf("[%d]", aio_get_val((uint16_t *)temp_buff, index));
  185. }
  186. rt_kputs("\n\r");
  187. count_ok++;
  188. }
  189. else
  190. {
  191. count_err++;
  192. }
  193. }
  194. static void test_modbus_rtu_master_thread(void *param)
  195. {
  196. int rc = 0;
  197. small_modbus_t *smb_master = param;
  198. rs485_rts_pin = rt_pin_get("PB.1"); //根据mcu平台修改引脚号
  199. rt_pin_mode(rs485_rts_pin, PIN_MODE_OUTPUT);
  200. rt_pin_write(rs485_rts_pin, PIN_LOW);
  201. modbus_init(smb_master, MODBUS_CORE_RTU, modbus_port_rtdevice_create(UART_DEVICE_NAME)); // init modbus RTU mode
  202. struct serial_configure serial_config;
  203. serial_config.baud_rate = BAUD_RATE_9600;
  204. serial_config.data_bits = DATA_BITS_8;
  205. serial_config.stop_bits = STOP_BITS_1;
  206. serial_config.bufsz = RT_SERIAL_RB_BUFSZ;
  207. serial_config.parity = PARITY_NONE;
  208. modbus_rtu_set_serial_config(smb_master, &serial_config); // config serial
  209. modbus_rtu_set_serial_rts(smb_master, uart_rts);
  210. modbus_rtu_set_oflag(smb_master, RT_DEVICE_FLAG_INT_RX);
  211. // modbus_rtu_set_oflag(smb_master,RT_DEVICE_FLAG_DMA_RX);
  212. modbus_connect(smb_master);
  213. MODBUS_PRINTF("modbus master\n");
  214. rt_sem_init(&(send_modbus_sem), "sendsem", 0, RT_IPC_FLAG_FIFO);
  215. while (1)
  216. {
  217. #ifdef MASTER_SEM_POLL
  218. master_sem_poll(smb_master); //主机信号量触发读写
  219. #else
  220. master_poll(smb_master); //主机轮询从机示例代码,该操作比较费时
  221. #endif
  222. }
  223. // modbus_disconnect(smb_master);
  224. //如果while中没有break应该不会运行到这里
  225. }
  226. int test_modbus_rtu_master(void)
  227. {
  228. rt_thread_t tid;
  229. tid = rt_thread_create("master", test_modbus_rtu_master_thread, &modbus_rtu_master, 2048, 20, 10);
  230. if (tid != RT_NULL)
  231. rt_thread_startup(tid);
  232. return 0;
  233. }
  234. // msh命令行启动
  235. #if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
  236. #include <finsh.h>
  237. MSH_CMD_EXPORT(test_modbus_rtu_master, test_modbus_rtu_master);
  238. #endif