test_pulse_encoder.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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)
  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)
  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. }
  72. static void _pulse_cmd_print_usage(void)
  73. {
  74. rt_kprintf("encoder_sample devname [option1] [option2]\n");
  75. rt_kprintf(" devname: [pulse_a1/pulse_61..] pulse uint\n");
  76. rt_kprintf(" option1: number of positive pulses\n");
  77. rt_kprintf(" option2: number of reversal pulses\n");
  78. rt_kprintf(" e.g. MSH >encoder_sample pulse_a1 2000 1000\n");
  79. printf_connect();
  80. }
  81. static void GenClkUp(const uint16_t cnt)
  82. {
  83. uint32_t i, j;
  84. rt_int32_t count;
  85. const uint8_t bAin[4U] = {1U, 1U, 0U, 0U};
  86. const uint8_t bBin[4U] = {0U, 1U, 1U, 0U};
  87. for (j = 0UL; j < cnt; j++)
  88. {
  89. for (i = 0UL; i < 4UL; i++)
  90. {
  91. if (0U == bAin[i])
  92. {
  93. rt_pin_write(TEST_IO_A_PIN, PIN_LOW);
  94. }
  95. else
  96. {
  97. rt_pin_write(TEST_IO_A_PIN, PIN_HIGH);
  98. }
  99. if (0U == bBin[i])
  100. {
  101. rt_pin_write(TEST_IO_B_PIN, PIN_LOW);
  102. }
  103. else
  104. {
  105. rt_pin_write(TEST_IO_B_PIN, PIN_HIGH);
  106. }
  107. rt_thread_mdelay(1UL);
  108. }
  109. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  110. rt_kprintf("%d\r\n", count);
  111. }
  112. }
  113. static void GenClkDown(const uint16_t cnt)
  114. {
  115. uint32_t i, j;
  116. rt_int32_t count;
  117. const uint8_t bAin[4U] = {0U, 1U, 1U, 0U};
  118. const uint8_t bBin[4U] = {1U, 1U, 0U, 0U};
  119. for (j = 0UL; j < cnt; j++)
  120. {
  121. for (i = 0UL; i < 4UL; i++)
  122. {
  123. if (0U == bAin[i])
  124. {
  125. rt_pin_write(TEST_IO_A_PIN, PIN_LOW);
  126. }
  127. else
  128. {
  129. rt_pin_write(TEST_IO_A_PIN, PIN_HIGH);
  130. }
  131. if (0U == bBin[i])
  132. {
  133. rt_pin_write(TEST_IO_B_PIN, PIN_LOW);
  134. }
  135. else
  136. {
  137. rt_pin_write(TEST_IO_B_PIN, PIN_HIGH);
  138. }
  139. rt_thread_mdelay(1UL);
  140. }
  141. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  142. rt_kprintf("%d\r\n", count);
  143. }
  144. }
  145. static int encoder_sample(int argc, char **argv)
  146. {
  147. rt_int32_t count;
  148. if ((argc != 4))
  149. {
  150. _pulse_cmd_print_usage();
  151. return -RT_ERROR;
  152. }
  153. rt_pin_mode(TEST_IO_A_PIN, PIN_MODE_OUTPUT);
  154. rt_pin_mode(TEST_IO_B_PIN, PIN_MODE_OUTPUT);
  155. pulse_encoder_dev = rt_device_find(argv[1]);
  156. if (pulse_encoder_dev == RT_NULL)
  157. {
  158. rt_kprintf("encoder_sample run failed! can't find %s device!\n", argv[1]);
  159. _pulse_cmd_print_usage();
  160. return -RT_ERROR;
  161. }
  162. rt_device_open(pulse_encoder_dev, RT_DEVICE_OFLAG_RDONLY);
  163. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
  164. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
  165. /* 自测DISABLE和CLEAR功能 */
  166. GenClkUp(100);
  167. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_DISABLE, RT_NULL);
  168. /* 测试DISABLE后是否还会计数 */
  169. GenClkUp(10);
  170. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  171. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_CLEAR_COUNT, RT_NULL);
  172. if (count != 100)
  173. {
  174. rt_kprintf("**************Self-test failed**************\n");
  175. rt_device_close(pulse_encoder_dev);
  176. _pulse_cmd_print_usage();
  177. return -RT_ERROR;
  178. }
  179. else
  180. {
  181. rt_kprintf("**************Self-test success**************\n");
  182. rt_device_control(pulse_encoder_dev, PULSE_ENCODER_CMD_ENABLE, RT_NULL);
  183. GenClkUp(atoi(argv[2]));
  184. GenClkDown(atoi(argv[3]));
  185. rt_device_read(pulse_encoder_dev, 0, &count, 1);
  186. if (count == (atoi(argv[2]) - atoi(argv[3])))
  187. {
  188. rt_kprintf("encoder_sample test success\n");
  189. }
  190. else
  191. {
  192. rt_kprintf("encoder_sample test failed\n");
  193. }
  194. rt_device_close(pulse_encoder_dev);
  195. }
  196. return RT_EOK;
  197. }
  198. /* 导出到 msh 命令列表中 */
  199. MSH_CMD_EXPORT(encoder_sample, encoder sample devname [option1] [option2]);
  200. #endif