test_pulse_encoder.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024-12-30 CDT first version
  9. */
  10. /*
  11. * 程序清单: Pulse encoder 设备使用例程, 请在图形化配置界面打开pulse encoder device,
  12. * 并使能tmra_1和tmr6_1.
  13. * 例程导出了 encoder_sample 命令到控制终端, 通过串口可查看当前的count数值
  14. * 命令调用格式:pulse_encoder_sample devname [option1] [option2]
  15. * devname: [pulse_a1/pulse_61] 编码器单元名称
  16. * option1: 正转脉冲数
  17. * option2: 反转脉冲数
  18. * eg:encoder_sample pulse_a1 2000 1000
  19. * 编码器的分辨率是1000
  20. * 硬件IO查看对应board/board_config.h中相关端口定义,并且需要正确连接到对应模拟脉冲生成的端口
  21. * 程序功能:
  22. */
  23. #include <rtthread.h>
  24. #include <rtdevice.h>
  25. #include <stdlib.h>
  26. #include "board_config.h"
  27. #include <board.h>
  28. #ifdef BSP_USING_PULSE_ENCODER
  29. #if defined (HC32F4A0) || defined (HC32F4A8)
  30. #define TEST_IO_A_PIN GET_PIN(A, 5)
  31. #define TEST_IO_B_PIN GET_PIN(A, 6)
  32. #else
  33. #define TEST_IO_A_PIN GET_PIN(B, 0)
  34. #define TEST_IO_B_PIN GET_PIN(B, 1)
  35. #endif
  36. static rt_device_t pulse_encoder_dev = RT_NULL;
  37. static void printf_connect(void)
  38. {
  39. #if defined (HC32F4A0) || defined (HC32F4A8)
  40. #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
  41. rt_kprintf(" [tmra]*connect PA5-->PA8 PA6-->PA9\n");
  42. #endif
  43. #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
  44. rt_kprintf(" [tmr6]*connect PA5-->PB9 PA6-->PB8\n");
  45. #endif
  46. #endif
  47. #if defined (HC32F460)
  48. #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
  49. rt_kprintf(" [tmra]*connect PB0-->PA8 PB1-->PA9\n");
  50. #endif
  51. #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
  52. rt_kprintf(" [tmr6]*connect PB0-->PE9 PB1-->PE8\n");
  53. #endif
  54. #endif
  55. #if defined (HC32F448)
  56. #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
  57. rt_kprintf(" [tmra]*connect PB0-->PA8 PB1-->PA9\n");
  58. #endif
  59. #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
  60. rt_kprintf(" [tmr6]*connect PB0-->PB5 PB1-->PB13\n");
  61. #endif
  62. #endif
  63. #if defined (HC32F472)
  64. #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
  65. rt_kprintf(" [tmra]*connect PB0-->PA0 PB1-->PA1\n");
  66. #endif
  67. #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
  68. rt_kprintf(" [tmr6]*connect PB0-->PA3 PB1-->PA7\n");
  69. #endif
  70. #endif
  71. #if defined (HC32F334)
  72. #if defined(BSP_USING_PULSE_ENCODER_TMRA_1)
  73. rt_kprintf(" [tmra]*connect PB0-->PA0 PB1-->PA1\n");
  74. #endif
  75. #if defined(BSP_USING_PULSE_ENCODER_TMR6_1)
  76. rt_kprintf(" [tmr6]*connect PB0-->PA7 PB1-->PA3\n");
  77. #endif
  78. #endif
  79. }
  80. static void _pulse_cmd_print_usage(void)
  81. {
  82. rt_kprintf("encoder_sample devname [option1] [option2]\n");
  83. rt_kprintf(" devname: [pulse_a1/pulse_61..] pulse uint\n");
  84. rt_kprintf(" option1: number of positive pulses\n");
  85. rt_kprintf(" option2: number of reversal pulses\n");
  86. rt_kprintf(" e.g. MSH >encoder_sample pulse_a1 2000 1000\n");
  87. printf_connect();
  88. }
  89. static void GenClkUp(const uint16_t cnt)
  90. {
  91. uint32_t i, j;
  92. rt_int32_t count;
  93. const uint8_t bAin[4U] = {1U, 1U, 0U, 0U};
  94. const uint8_t bBin[4U] = {0U, 1U, 1U, 0U};
  95. for (j = 0UL; j < cnt; j++)
  96. {
  97. for (i = 0UL; i < 4UL; i++)
  98. {
  99. if (0U == bAin[i])
  100. {
  101. rt_pin_write(TEST_IO_A_PIN, PIN_LOW);
  102. }
  103. else
  104. {
  105. rt_pin_write(TEST_IO_A_PIN, PIN_HIGH);
  106. }
  107. if (0U == bBin[i])
  108. {
  109. rt_pin_write(TEST_IO_B_PIN, PIN_LOW);
  110. }
  111. else
  112. {
  113. rt_pin_write(TEST_IO_B_PIN, PIN_HIGH);
  114. }
  115. rt_thread_mdelay(1UL);
  116. }
  117. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  118. rt_kprintf("%d\r\n", count);
  119. }
  120. }
  121. static void GenClkDown(const uint16_t cnt)
  122. {
  123. uint32_t i, j;
  124. rt_int32_t count;
  125. const uint8_t bAin[4U] = {0U, 1U, 1U, 0U};
  126. const uint8_t bBin[4U] = {1U, 1U, 0U, 0U};
  127. for (j = 0UL; j < cnt; j++)
  128. {
  129. for (i = 0UL; i < 4UL; i++)
  130. {
  131. if (0U == bAin[i])
  132. {
  133. rt_pin_write(TEST_IO_A_PIN, PIN_LOW);
  134. }
  135. else
  136. {
  137. rt_pin_write(TEST_IO_A_PIN, PIN_HIGH);
  138. }
  139. if (0U == bBin[i])
  140. {
  141. rt_pin_write(TEST_IO_B_PIN, PIN_LOW);
  142. }
  143. else
  144. {
  145. rt_pin_write(TEST_IO_B_PIN, PIN_HIGH);
  146. }
  147. rt_thread_mdelay(1UL);
  148. }
  149. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  150. rt_kprintf("%d\r\n", count);
  151. }
  152. }
  153. static int encoder_sample(int argc, char **argv)
  154. {
  155. rt_int32_t count;
  156. if ((argc != 4))
  157. {
  158. _pulse_cmd_print_usage();
  159. return -RT_ERROR;
  160. }
  161. rt_pin_mode(TEST_IO_A_PIN, PIN_MODE_OUTPUT);
  162. rt_pin_mode(TEST_IO_B_PIN, PIN_MODE_OUTPUT);
  163. pulse_encoder_dev = rt_device_find(argv[1]);
  164. if (pulse_encoder_dev == RT_NULL)
  165. {
  166. rt_kprintf("encoder_sample run failed! can't find %s device!\n", argv[1]);
  167. _pulse_cmd_print_usage();
  168. return -RT_ERROR;
  169. }
  170. rt_device_open(pulse_encoder_dev, RT_DEVICE_OFLAG_RDONLY);
  171. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
  172. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
  173. /* 自测DISABLE和CLEAR功能 */
  174. GenClkUp(100);
  175. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_DISABLE, RT_NULL);
  176. /* 测试DISABLE后是否还会计数 */
  177. GenClkUp(10);
  178. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  179. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
  180. if (count != 100)
  181. {
  182. rt_kprintf("**************Self-test failed**************\n");
  183. rt_device_close(pulse_encoder_dev);
  184. _pulse_cmd_print_usage();
  185. return -RT_ERROR;
  186. }
  187. else
  188. {
  189. rt_kprintf("**************Self-test success**************\n");
  190. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
  191. GenClkUp(atoi(argv[2]));
  192. GenClkDown(atoi(argv[3]));
  193. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  194. if (count == (atoi(argv[2]) - atoi(argv[3])))
  195. {
  196. rt_kprintf("encoder_sample test success\n");
  197. }
  198. else
  199. {
  200. rt_kprintf("encoder_sample test failed\n");
  201. }
  202. rt_device_close(pulse_encoder_dev);
  203. }
  204. return RT_EOK;
  205. }
  206. /* 导出到 msh 命令列表中 */
  207. MSH_CMD_EXPORT(encoder_sample, encoder sample devname [option1] [option2]);
  208. #endif