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