阅读量:0
目录
概述
本文主要介绍Renesa Version Board开发RT-Thread 开发超声波测距模块(HC-SR04)的功能,该功能需要定时器和外部中断配合起来才能工作。笔者详细分析了HC-SR04的工作原理,使用FSP配置IO接口和定时器的参数。最后在OLED上显示测得数据的数值。
1 硬件接口介绍
1.1 Version Board上的IO接口
在如下网址能看见该IO所对应的Pin引脚:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/hw-board/ra8d1-vision-board/ra8d1-vision-board
模块引脚 | Arduino UNO 引脚 | 注释 |
SR-04 TRIG | PORT_05_PIN_10 | 测距触发信号 |
SR-04 ECHO | PORT_00_PIN_06 | 测距信息 |
1.2 HC-SR4模块介绍
1.2.1 HC-SR04特性
1.2.2 HC-SR04操作时序
工作原理:
Step -1: TRIG IO 收到10us 高电平
step - 2: SR04自动发送8个40hz方波,并检测是否有信号返回
step - 3:SR04检测到返回信号,ECHO IO发送高电平,高电平持续时间为SR04发送波信号到返回波信号的时间。
具体工作波形图如下:
1.2.3 计算距离
以厘米为单位计算公式:
距离 = us/58(单位: cm), us为ECHO IO接收的高电平的持续时间,时间单位为: 微妙
以英寸为单位计算公式:
距离 = us/148(单位: 英寸), us为ECHO IO接收的高电平的持续时间,时间单位为: 微妙
2 功能实现
2.1 FSP配置IO
1)配置PORT_0_PIN_06为输出端口,用于Trig HC-SR04响应
2)配置PORT_5_PIN_10为输入中断
3)配置定时器Timer0,定时时间为10us
2.2 测距代码实现
1) 触发测距功能
2)输入中断响应测距信号
2.3 源代码
创建HC_SR04.c,编写如下代码:
/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2024-08-11 Administrator the first version */ #include <string.h> #include "hal_data.h" #include <stdio.h> #include <stdbool.h> #include "user/hc_SR04.h" #include "common_data.h" #define timeDelayUS(us) R_BSP_SoftwareDelay(us, BSP_DELAY_UNITS_MICROSECONDS); #define ICU_IRQN_PIN BSP_IO_PORT_05_PIN_10 #define ICU_IRQN 3 #define TRIG BSP_IO_PORT_00_PIN_06 #define TRIG_H R_IOPORT_PinWrite(&g_ioport_ctrl, TRIG, BSP_IO_LEVEL_HIGH) #define TRIG_L R_IOPORT_PinWrite(&g_ioport_ctrl, TRIG, BSP_IO_LEVEL_LOW) static bool bl_trigger = false; static uint32_t tick_cnt_1us; static int state =0; static float distance; static void timer0_Init(void) { fsp_err_t err = FSP_SUCCESS; /* Initializes the module. */ err = R_AGT_Open(&g_timer0_ctrl, &g_timer0_cfg); /* Handle any errors. This function should be defined by the user. */ assert(FSP_SUCCESS == err); /* Start the timer. */ err = R_AGT_Start(&g_timer0_ctrl); assert(FSP_SUCCESS == err); err = R_AGT_Enable(&g_timer0_ctrl); assert(FSP_SUCCESS == err); } void HC_SR04_Init ( void ) { /* Configure the external interrupt. */ fsp_err_t err = R_ICU_ExternalIrqOpen(&g_external_irq3_ctrl, &g_external_irq3_cfg); assert(FSP_SUCCESS == err); /* Enable the external interrupt. */ /* Enable not required when used with ELC or DMAC. */ err = R_ICU_ExternalIrqEnable(&g_external_irq3_ctrl); assert(FSP_SUCCESS == err); timer0_Init(); } void HC_SR04_Trigger( void ) { bl_trigger = true; TRIG_H; timeDelayUS(12); TRIG_L; state = 0; } void g_timer0_Callback (timer_callback_args_t * p_args) { if (TIMER_EVENT_CYCLE_END == p_args->event) { tick_cnt_1us++; } } /* Called from icu_irq_isr */ void external_irq3_callback (external_irq_callback_args_t * p_args) { fsp_err_t err = FSP_SUCCESS; (void) p_args; switch( state ) { default: case 0: tick_cnt_1us = 0; state = 1; err = R_AGT_Enable(&g_timer0_ctrl); assert(FSP_SUCCESS == err); break; case 1: distance = (tick_cnt_1us)/5.8; state = 0; tick_cnt_1us = 0; err = R_AGT_Disable(&g_timer0_ctrl); assert(FSP_SUCCESS == err); break; } } void debug_SR04_LOG( void ) { user_get_rtc(); } float HC_SR04_getValue( void ) { return distance; }
3 功能测试
3.1 监控波形
使用逻辑分析仪,测试ECHO接口上的波形数据
改变距离后的波形数据
3.2 测试程序实现
在主函数中调用函数float HC_SR04_getValue( void ),就能获取到HC-SR04的值
在OLED上显示HC-SR04的值:
运行程序,在OLED上查看结果: