自学内容网 自学内容网

Renesas R7FA8D1BH (Cortex®-M85) 上超声波测距模块(HC-SR04)驱动开发

目录

概述

1 软硬件

1.1 软硬件环境信息

1.2 开发板信息

1.3 调试器信息

2 硬件架构

2.1 硬件框架结构

2.2 测距模块(HC-SR04)介绍

2.2.1 HC-SR04特性

2.2.2 HC-SR04操作时序

2.2.3 计算距离

3 软件实现

3.1 FSP配置项目

3.1.1 配置IO口的外部中断

 3.1.2 配置定时器

3.2 代码架构

 3.3 驱动实现

4 测试

4.1 编译代码

4.2 验证


源代码下载地址:

https://www.firebbs.cn/forum.php?mod=viewthread&tid=37943

概述

本文主要介绍Renesas R7FA8D1BH (Cortex®-M85) 上超声波测距模块(HC-SR04)驱动开发的过程,笔者介绍了HC-SR04测距模块驱动的实现原理,并使用FSP配置外围驱动接口,并编写驱动代码,实现测距的功能。在Renesas R7FA8D1BH板卡上通过改变距离参数验证驱动程序的功能。

1 软硬件

1.1 软硬件环境信息

软硬件信息版本信息
Renesas MCUR7FA8D1BH
KeilMDK ARM 5.38
FSP 版本5.3.0
调试工具:N32G45XVL-STBDAP-LINK

1.2 开发板信息

笔者选择使用野火耀阳开发板_瑞萨RA8,该板块的主控MCU为R7FA8D1BHECBD,7FA8D1BHECBD的内核为ARM Contex-M85。

1.3 调试器信息

对于R7FA8D1BHECBD芯片,其使用的内核为Cortex®-M85 Core, ST-LINK-V2或者J-LINK-V9不支持下载和调试功能。笔者经过多次尝试,发现N32G45XVL-STB板卡上自带的DAP-LINK可以下载和调试R7FA8D1BHECBD。

下图为N32G45XVL-STB开发板实物图:

2 硬件架构

2.1 硬件框架结构

IO接口配置功能:

触发信号接口P7_10: 送触发信号(10us)的脉冲

测距数据响应接口P7_09: 该IO配置外部中断响应模式,用于接收HC-SR04发回的脉冲信号

TIMER-0: 配置为10us响应速度,用于计算数据的脉冲宽度

系统工作框架结构如下:

2.2 测距模块(HC-SR04)介绍

2.2.1 HC-SR04特性

2.2.2 HC-SR04操作时序

工作原理:

Step -1: TRIG IO 收到10us 高电平

step - 2:  SR04自动发送8个40hz方波,并检测是否有信号返回

step - 3:SR04检测到返回信号,ECHO IO发送高电平,高电平持续时间为SR04发送波信号到返回波信号的时间。

具体工作波形图如下:

2.2.3 计算距离

以厘米为单位计算公式:

距离 = us/58(单位: cm), us为ECHO IO接收的高电平的持续时间,时间单位为: 微妙

以英寸为单位计算公式:

距离 = us/148(单位: 英寸), us为ECHO IO接收的高电平的持续时间,时间单位为: 微妙

3 软件实现

3.1 FSP配置项目

3.1.1 配置IO口的外部中断

1) 创建外部中断stack

2)配置参数

需要配置的参数如下:

1)选择通道号

2)回调函数

3)IO接口

 3.1.2 配置定时器

1)创建定时器的stack

2)配置参数

需要配置的参数如下:

1)通道号

2)周期

3)  最小周期单元

4)中断回调函数

 

3.2 代码架构

完成以上参数配置后,就可以使用FSP生成工程代码,其代码架构如下:

 3.3 驱动实现

1)初始化函数

函数static void timer5_Init(void):实现定时器的驱动初始化功能

代码32行:打开定时器

代码36行:启动定时器

代码39行:启动计数功能

函数:void HC_SR04_Init ( void ):实现HC_SR04模块初始化功能,该函数可以被外部其他函数调用

代码48行: 代码IO外部中断aima

代码52行:打开外部中断

代码55行:调用定时器初始化函数,启动定时器,以实现计算脉冲宽度功能

2)触发函数和定时器回调函数

 3)外部中断回调函数

代码90行:启动定时器,开始计数

代码94行:停止定时器

代码95行:计算距离数据

 源代码文件如下:

 /*
 FILE NAME  :  sht2x.c
 Description:  user sht20 interface 
 Author     :  tangmingfei2013@126.com
 Date       :  2024/06/03
 */
#include "hal_data.h"
#include "hc_sr04.h"


#define timeDelayUS(us)      R_BSP_SoftwareDelay(us, BSP_DELAY_UNITS_MICROSECONDS);

#define ICU_IRQN_PIN         BSP_IO_PORT_07_PIN_09
#define ICU_IRQN             10

#define TRIG                 BSP_IO_PORT_07_PIN_10

#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 timer5_Init(void)
{
    fsp_err_t err = FSP_SUCCESS;
    /* Initializes the module. */
    err = R_AGT_Open(&g_timer5_ctrl, &g_timer5_cfg);
    /* Handle any errors. This function should be defined by the user. */
    assert(FSP_SUCCESS == err);
    /* Start the timer. */
    err = R_AGT_Start(&g_timer5_ctrl);
    assert(FSP_SUCCESS == err);

    err = R_AGT_Enable(&g_timer5_ctrl);
    assert(FSP_SUCCESS == err);
}



void HC_SR04_Init ( void )
{
    /* Configure the external interrupt. */
    fsp_err_t err = R_ICU_ExternalIrqOpen(&g_external_irq10_ctrl, &g_external_irq10_cfg);
    assert(FSP_SUCCESS == err);
    /* Enable the external interrupt. */
    /* Enable not required when used with ELC or DMAC. */
    err = R_ICU_ExternalIrqEnable(&g_external_irq10_ctrl);
    assert(FSP_SUCCESS == err);

    timer5_Init();
}


void HC_SR04_Trigger( void )
{
    bl_trigger = true;
    TRIG_H;
    timeDelayUS(10);
    TRIG_L;
    state = 0;
}


void g_timer5_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_irq10_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_timer5_ctrl);
            assert(FSP_SUCCESS == err);
            break;
        case 1:
            err = R_AGT_Disable(&g_timer5_ctrl);
            distance = (float)(tick_cnt_1us/5.8);
            state = 0;
            tick_cnt_1us = 0;
            assert(FSP_SUCCESS == err);
            break;
    }
}

void debug_SR04_LOG( void )
{
    user_get_rtc();
}

float HC_SR04_getDistance( void )
{
    return distance;
}





/* End of this file */

4 测试

4.1 编译代码

系统硬件平台如下:

编译代码下载到板卡中运行:

4.2 验证

改变距离后,在OLED得到当前的距离数据:


原文地址:https://blog.csdn.net/mftang/article/details/142675521

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!