• Home
Name Date Size #Lines LOC

..--

include/12-May-2024-678

src/12-May-2024-420209

BUILD.gnD12-May-2024880 2723

README_zh.mdD12-May-202410 KiB287222

e53_intelligent_vehicle_01_example.cD12-May-20243.1 KiB10653

README_zh.md

1# 小凌派-RK2206开发板E53模块开发——智慧车载
2
3本示例将演示如何在小凌派-RK2206开发板上实现智慧车载的应用案例。
4
5![小凌派-RK2206开发板](../../docs/figures/lockzhiner-rk2206.jpg)
6
7## 硬件资源
8
9硬件资源图如下所示:
10![智慧车载模块硬件资源](/vendor/lockzhiner/lingpi/docs/figures/e53_iv01/e53_iv01_resource_map.jpg)
11
12EEPROM 24C02的设备地址为:0x1010001* ;
13
14## 硬件接口说明
15
16引脚名称开发者可在硬件资源图中查看,也可在智慧车载模块背面查看。
17
18| 引脚名称    | 功能描述                                     |
19| :---------- | :------------------------------------------- |
20| ECHO        | 测距脉宽输出,高电平的宽度代表超声波往返时间 |
21| TRIG        | 测距触发,输入10us的高电平脉冲,开始测距     |
22| BUZZER      | 蜂鸣器控制线,推荐3KHz的方波信号             |
23| LED_Warning | LED控制线,低电平有效                        |
24| I2C_SCL     | I2C时钟信号线                                |
25| I2C-SDA     | I2C数据信号线                                |
26| GND         | 电源地引脚                                   |
27| 3V3         | 3.3V电源输入引脚                             |
28| GND         | 电源地引脚                                   |
29
30## 硬件设计
31
32硬件电路如下图所示:
33![智慧车载模块硬件电路图](/vendor/lockzhiner/lingpi/docs/figures/e53_iv01/lz_e53_iv01_sch.jpg)
34
35模块整体硬件电路如上图所示,电路中包含了E53接口连接器,EEPROM存储器、超声波处理电路,声光报警电路。
36
37超声波测距芯片,选用CS-100A,其是一款工业级超声波测距芯片,内部集成超声波发射电路,超声波接收电路,数字处理电路等,单片即可完成超声波测距,测距结果通过脉宽的方式进行输出。
38
39CS100A配合使用40KHz的开放式超声波探头,在超声波发射端并联一个电阻R2到地和8MHz的晶振,即可实现高性能的测距功能,电阻R2的大小决定了超声波测量的距离。
40
41三极管Q1为NPN管,基极为高电平时,三极管才能够导通,蜂鸣器需PWM波驱动,人耳可识别的频率范围为20Hz-20KHz,故PWM频率需在该范围内,我们默认使用3KHz的PWM波驱动。
42
43### 硬件连接
44
45小凌派开发板与模块均带有防呆设计,故很容易区分安装方向,直接将模块插入到开发板的E53母座接口上即可,安装图如下所示:
46![智慧车载模块硬件连接图](/vendor/lockzhiner/lingpi/docs/figures/e53_iv01/e53_iv01_connection_diagram.png)
47
48## 程序设计
49
50### API分析
51
52### GPIO接口
53
54[GPIO接口文档](/device/rockchip/hardware/docs/GPIO.md)
55
56### PWM接口
57
58[PWM接口文档](/device/rockchip/hardware/docs/PWM.md)
59
60### LiteOS信号量
61
62[LiteOS信号量接口文档](/vendor/lockzhiner/lingpi/samples/a2_kernel_semaphore/README_zh.md)
63
64## 主要代码分析
65
66### 初始化代码分析
67
68**初始化GPIO**
69
70初始化GPIO0_PC4和GPIO0_PA5为GPIO。首先通过 `LzGpioInit()`初始化GPIO引脚,其次通过 `LzGpioSetDir()`设置GPIO为输出模式,最后通过 `LzGpioSetVal()`设置输出高电平/低电平。
71
72```c
73/***************************************************************
74 * 函数名称: e53_iv01_init_gpio
75 * 说    明: 初始化GPIO
76 * 参    数: 无
77 * 返 回 值: 无
78 ***************************************************************/
79static void e53_iv01_init_gpio()
80{
81    /* Trig引脚设置为GPIO输出模式 */
82    PinctrlSet(E53_IV01_TRIG_GPIO, MUX_FUNC0, PULL_KEEP, DRIVE_KEEP);
83    LzGpioInit(E53_IV01_TRIG_GPIO);
84    LzGpioSetDir(E53_IV01_TRIG_GPIO, LZGPIO_DIR_OUT);
85    E53_IV01_TRIG_Clr();
86
87    /* LED_WARNING灯引脚设置为GPIO输出模式 */
88    PinctrlSet(E53_IV01_LED_WARNING_GPIO, MUX_FUNC0, PULL_KEEP, DRIVE_KEEP);
89    LzGpioInit(E53_IV01_LED_WARNING_GPIO);
90    LzGpioSetDir(E53_IV01_LED_WARNING_GPIO, LZGPIO_DIR_OUT);
91    e53_iv01_led_warning_set(0);
92}
93```
94
95**初始化GPIO中断**
96
97初始化GPIO0_PA2为GPIO。首先通过 `LzGpioInit()`初始化GPIO引脚,其次通过 `LzGpioSetDir()`设置GPIO为输入模式,最后通过 `LzGpioRegisterIsrFunc()`设置该引脚为中断模式,触发模式为边沿触发(即上升沿+下降沿都可触发)。
98
99```c
100/***************************************************************
101 * 函数名称: e53_iv01_init_interrupt
102 * 说    明: 初始化GPIO中断
103 * 参    数: 无
104 * 返 回 值: 无
105 ***************************************************************/
106static void e53_iv01_init_interrupt()
107{
108    LzI2cInit(0, 400000);
109
110    /* 创建信号量 */
111    LOS_SemCreate(0, &m_task_sem);
112
113    /* Echo引脚设置为GPIO输出模式 */
114    PinctrlSet(E53_IV01_ECHO0_GPIO, MUX_FUNC0, PULL_KEEP, DRIVE_KEEP);
115    LzGpioInit(E53_IV01_ECHO0_GPIO);
116    LzGpioSetDir(E53_IV01_ECHO0_GPIO, LZGPIO_DIR_IN);
117    LzGpioRegisterIsrFunc(E53_IV01_ECHO0_GPIO, GPIO_INT_EDGE_BOTH, e53_iv01_interrupt_echo_func, NULL);
118}
119```
120
121**初始化PWM**
122
123初始化GPIO0_PC7为GPIO。首先通过 `PwmIoInit()`初始化PWM配置,最后通过 `LzPwmInit()`初始化PWM配置id。
124
125```c
126/***************************************************************
127 * 函数名称: e53_iv01_init_pwm
128 * 说    明: 初始化PWM
129 * 参    数: 无
130 * 返 回 值: 无
131 ***************************************************************/
132static unsigned int e53_iv01_init_pwm()
133{
134    /* 初始化pwm */
135    PinctrlSet(E53_IV01_BUZZER_GPIO, MUX_FUNC2, PULL_DOWN, DRIVE_KEEP);
136    if (PwmIoInit(m_buzzer_config) != LZ_HARDWARE_SUCCESS)
137    {
138        printf("%s, %d: PwmIoInit failed\n", __func__, __LINE__);
139        return __LINE__;
140    }
141    if (LzPwmInit(E53_IV01_PWM_IO) != LZ_HARDWARE_SUCCESS)
142    {
143        printf("%s, %d: LzPwmInit failed\n", __func__, __LINE__);
144        return __LINE__;
145    }
146
147    return 0;
148}
149```
150
151### 车载测距流程代码分析
152
153首先,初始化相关变量,使能GPIO中断,并控制TRIG引脚往E53模块发送一个至少10usec的高电平,通知E53模块开始工作。具体代码如下所示:
154
155```c
156/* 初始化采集相关信息 */
157m_echo_info.flag = EECHO_FLAG_CAPTURE_RISE;
158/* 使能GPIO中断 */
159LzGpioEnableIsr(E53_IV01_ECHO0_GPIO);
160/* 等待1msec */
161LOS_Msleep(1);
162/* 发送10Usec的高电平 */
163e53_iv01_send_trig();
164```
165
166其次,等待信号量(该信号量最长等待时间为200msec)。具体代码如下所示:
167
168```c
169/* 等待200msec(最长等待时间),整个测距最长为66msec */
170LOS_SemPend(m_task_sem, LOS_MS2Tick(200));
171```
172
173在GPIO中断处理函数中记录E53模块用ECHO引脚发送过来的一个高电平时间宽度(该高电平的时间宽度为超声波来回的时间宽度)。具体实现方式为:
174
175* 上升沿触发时,记录系统时钟(即定时器5)的当前节拍数,修改触发状态;
176* 下降沿出发时,记录系统时钟(即定时器5)的当前节拍数,修改触发状态,释放信号量。
177
178具体代码如下:
179
180```c
181/***************************************************************
182 * 函数名称: e53_iv01_interrupt_echo_func
183 * 说    明: GPIO中断处理函数,通过中断捕获定时器计数器当前值
184 * 参    数:
185 *      @arg,
186 * 返 回 值: 无
187 ***************************************************************/
188static VOID e53_iv01_interrupt_echo_func(VOID *arg)
189{
190    if (m_echo_info.flag == EECHO_FLAG_CAPTURE_RISE)
191    {
192        /* 获取上升沿的定时器计数器当前值 */
193        m_echo_info.time_rise = *m_ptimer5_current_value_low;
194        m_echo_info.flag = EECHO_FLAG_CAPTURE_FALL;
195    }
196    else if (m_echo_info.flag == EECHO_FLAG_CAPTURE_FALL)
197    {
198        /* 获取下降沿的定时器计数器当前值 */
199        m_echo_info.time_fall = *m_ptimer5_current_value_low;
200        m_echo_info.flag = EECHO_FLAG_CAPTURE_SUCCESS;
201        LOS_SemPost(m_task_sem);
202    }
203    else
204    {
205        /* 什么都不做 */
206    }
207}
208```
209
210然后禁用GPIO中断,判断中断状态判断E53模块是否采集成功。具体代码如下:
211
212```c
213/* 禁用GPIO中断 */
214LzGpioDisableIsr(E53_IV01_ECHO0_GPIO);
215
216if (m_echo_info.flag == EECHO_FLAG_CAPTURE_SUCCESS)
217{/* 如果是采集成功,则计算距离 */
218    if (m_echo_info.time_rise <= m_echo_info.time_fall)
219    {
220        time_diff = m_echo_info.time_fall - m_echo_info.time_rise;
221    }
222    else
223    {
224        time_diff = 0xFFFFFFFF - m_echo_info.time_rise + m_echo_info.time_fall + 1;
225    }
226
227    e53_iv01_calc_cm(time_diff, ECHO_TIMER_FREQ, distance_cm);
228    return 1;
229}
230else
231{
232    printf("%s, %d: flag(%d) is error!\n", __func__, __LINE__, m_echo_info.flag);
233    return 0;
234}
235```
236
237最后,根据上升沿和下降沿的节拍数差计算距离。其中,系统时钟为40MHz,超声波速度为340米/秒,高电平时间宽度为超声波的往返之和,所以实际距离 = 节拍数差 / 40MHz / 340(米/秒) / 2(往返2次)。具体计算代码如下:
238
239```c
240/***************************************************************
241 * 函数名称: e53_iv01_calc_cm
242 * 说    明: 计算超声波测距
243 * 参    数:
244 *      @time:节拍数
245 *      @freq:节拍频率,以Hz为单位
246 *      @meter:距离差,以厘米为单位
247 * 返 回 值: 无
248 ***************************************************************/
249static inline void e53_iv01_calc_cm(uint32_t time, uint32_t freq, float *cmeter)
250{
251    float f_time = (float)time;
252    float f_freq = (float)freq;
253
254    /* 距离 = 时间差 * 340米/秒 / 2(超时波来回2次) * 100厘米/米 */
255    *cmeter = f_time / f_freq * 170.0 * 100.0;
256}
257```
258
259## 编译调试
260
261### 修改 BUILD.gn 文件
262
263修改 `vendor/lockzhiner/lingpi/sample` 路径下 BUILD.gn 文件,指定 `e53_iv01_example` 参与编译。
264
265```r
266"e53_intelligent_vehicle_01",
267```
268
269在主目录下输入编译命令。
270
271```shell
272hb build -f
273```
274
275### 运行结果
276
277示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志,并请使用带有LCD屏幕显示如下:
278
279```c
280========== E53 IV Example ==========
281distance cm: 23.92
282========== E53 IV Example ==========
283distance cm: 23.89
284========== E53 IV Example ==========
285distance cm: 23.90
286```
287