红外超声波雷达测距

一. 采用stm32F103和HC-SR04超声波模块, 使用标准库或HAL库+ 定时器中断,完成1或2路的超声波障碍物测距功能。

1)测试数据包含噪声,程序需要进行滤波处理;将测距数值通过串口上传到上位机串口助手;
2)根据障碍物距离远近,控制一个蜂鸣器(可以用LED灯代替)发出频率不同的声音(或LED不同闪烁),即输出占空比变化的PWM波形;
3)在没有超声波模块硬件的场景下,先使用Keil中的仿真逻辑分析仪,观察分析对应管脚上的时序波形,判读是否符合协议规范。

1.主要代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"

uint8_t flag=0;				//用于记录中断信号是上升沿还是下降沿
uint32_t number=0;			//记录定时器中断的次数
uint32_t times=0;			//记录回响信号的持续时间

int main(void){
    OLED_Init();
    OLED_ShowString(1,1,"Hello World!!!");
    
    //初始化GPIO口,Trig使用推挽输出,Echo使用浮空输入
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);        //使能GPIOA的外设时钟
    GPIO_InitTypeDef itd;
    itd.GPIO_Mode=GPIO_Mode_Out_PP;                             //选择推挽输出模式
    itd.GPIO_Pin=GPIO_Pin_6;                                    //选择GPIO_Pin_6
    itd.GPIO_Speed=GPIO_Speed_50MHz;                            //默认选择50MHz
    GPIO_Init(GPIOA,&itd);
    
    itd.GPIO_Mode=GPIO_Mode_IN_FLOATING;                        //选择浮空输入模式
    itd.GPIO_Pin=GPIO_Pin_7;                                    //选择GPIO_Pin_7
    GPIO_Init(GPIOA,&itd);
    
    //AFIO映射中断引脚
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);         //使能AFIO的外设时针
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);  //选择外部中断源和中断通道
    
    //EXTI中断配置
    EXTI_InitTypeDef itd1;
    itd1.EXTI_Line=EXTI_Line7;                                  //echo使用的端口7,因此选择7号中断线
    itd1.EXTI_LineCmd=ENABLE;
    itd1.EXTI_Mode=EXTI_Mode_Interrupt;
    itd1.EXTI_Trigger=EXTI_Trigger_Rising_Falling;              //上升沿和下降沿都触发中断
    EXTI_Init(&itd1);
    
    //NVIC分配外部中断的中断优先级
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);             //指定中断分组
    NVIC_InitTypeDef itd2;
    itd2.NVIC_IRQChannel=EXTI9_5_IRQn;                          //使用的端口7,因此选择这个参数
    itd2.NVIC_IRQChannelCmd=ENABLE;
    itd2.NVIC_IRQChannelPreemptionPriority=2;                   //抢占优先级
    itd2.NVIC_IRQChannelSubPriority=2;                          //响应优先级 
    NVIC_Init(&itd2);
    
    //配置定时器
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    TIM_TimeBaseInitTypeDef itd3;
    itd3.TIM_ClockDivision=TIM_CKD_DIV1;                        //使用时钟分频1
    itd3.TIM_CounterMode=TIM_CounterMode_Up;                    //向上计数
    //72MHz/72/100=1000,每秒定时器计数1000个,因此每个计数为100us
    itd3.TIM_Period=72-1;                                       //预分频系数
    itd3.TIM_Prescaler=100-1;                                   //自动重装器
    itd3.TIM_RepetitionCounter=0;                               //该参数仅给高级定时器使用
    TIM_TimeBaseInit(TIM2,&itd3);
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);                    //使能中断输出信号
    TIM_InternalClockConfig(TIM2);                              //选择内部时钟    
    
    //NVIC分配定时器的中断优先级
    NVIC_InitTypeDef itd4;
    itd4.NVIC_IRQChannel=TIM2_IRQn;                             //指定Tim2的中断通道
    itd4.NVIC_IRQChannelCmd=ENABLE;
    itd4.NVIC_IRQChannelPreemptionPriority=1;                   //抢占优先级
    itd4.NVIC_IRQChannelSubPriority=1;                          //响应优先级
    NVIC_Init(&itd4);
    
    uint32_t distance;
    while(1){
        distance=0;
        for(int i=0;i<10;++i){              //每次取10次测距数据,取平均值减少误差
            GPIO_SetBits(GPIOA,GPIO_Pin_6);
            Delay_us(15);                   //根据说明书,需要提供至少10us的高电平
            GPIO_ResetBits(GPIOA,GPIO_Pin_6);
            Delay_ms(65);                   //根据说明书,每个周期至少需要等待60ms
            distance+=(times/5.8);          //根据说明书提供的公式,获取单位为mm的距离
        }
        distance/=10;
        OLED_ShowNum(2,1,distance,4);
    }
}

//定时器中断函数
void TIM2_IRQHandler(void){
    if(SET==TIM_GetITStatus(TIM2,TIM_FLAG_Update)){
        number++;                                   //每次中断将次数++
        TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
    }
}

//外部中断函数
void EXTI9_5_IRQHandler(void){
    if(SET==EXTI_GetITStatus(EXTI_Line7)){
        if(flag==0){
            //上升沿即回响电平开始,打开计数器
            number=0;flag=1;
            TIM_SetCounter(TIM2,0);
            TIM_Cmd(TIM2,ENABLE);
            
        }else{
            //下降沿即回响电平结束,统计高电平持续时长
            TIM_Cmd(TIM2,DISABLE);
            flag=0;
            times=number*100+TIM_GetCounter(TIM2);  //得到回响的高电平持续的us
        }
        EXTI_ClearITPendingBit(EXTI_Line7);
    }
}

alt

2.接线

HC-SR04需要单独提供5V的供电,因此不能与stm32共用一个VCC(3.3V),而ST-Link有5V的供电接口,因此我将5V电压单独拉出来给HC-SR04供电,GND与stm32用同一个。

HC-SR04的Trig接GPIOA的6号口,Echo接GPIOA的7号口。

接线端口没有硬性要求,只需要修改对应代码即可。需要注意的是修改GPIO口的同时还需要修改为对应的中断通道。

OLED的SCK接GPIOB的8号口,SDA接GPIOB的9号口。

3.实验结果

在这里插入图片描述

二. 当前智能汽车上一般配置有12路超声波雷达,这些专用超声波雷达内置了MCU,直接输出数字化的测距结果,一般硬件接口采用串口RS485,通信协议采用modbus。请思考:

1)RS485与RS232(UART)有什么不同?

RS485和RS232(UART)是两种不同的串行通信标准协议。它们的主要区别在于信号电平、传输距离、速率和多点连接能力等方面。RS232通常使用正负电平进行通信,传输距离相对较短(一般在15米左右),速率一般低于10Mbps,主要适用于点对点连接;而RS485是一种差分信号通信方式,可以实现长距离传输(最高可达1200米),速率在10Mbps左右,支持多点连接,更适合工业环境中的远距离通信。

2)Modbus协议是什么?

Modbus协议是一种通信协议,通常用于工业控制系统中,它基于主从设备的通信模式,支持不同物理层传输介质,包括串口、以太网等。Modbus协议定义了一种数据传输格式,包括各种功能码和数据格式,主要用于实现设备之间的数据通信和控制。

3)如果让你设计一款 12路车载超声波雷达,采用 stm32F103+HC-SR04超声波模块,对外提供RS485和Modbus协议,你的设计方案是什么?

  1. 硬件设计
    1.1 微控制器选择
    STM32F103:选择STM32F103作为主控制器,因为它具有足够的处理能力、丰富的外设接口和较低的成本。
    1.2 超声波传感器模块
    HC-SR04:每个超声波传感器模块包含一个超声波发射器和一个接收器,可以测量距离。
    12个HC-SR04:为实现12路超声波检测,需要12个HC-SR04模块。
    1.3 接口电路
    RS485通信接口:用于与外部系统通信,需要一个RS485转接器或驱动器。
    Modbus协议支持:需要在软件层面实现Modbus协议。
    1.4 电源管理
    确保系统有稳定的电源供应,可能需要电压调节器。
    1.5 PCB布局
    设计PCB以容纳所有组件,并确保信号完整性和电磁兼容性。
  2. 软件设计
    2.1 驱动程序
    为HC-SR04编写驱动程序,实现超声波的发射和接收。
    2.2 任务调度
    使用STM32F103的RTOS(如FreeRTOS)来管理多个传感器的任务调度。
    2.3 数据处理
    实现算法处理超声波数据,如滤波、平均等。
    2.4 RS485和Modbus协议实现
    实现RS485通信协议,确保数据的可靠传输。
    实现Modbus协议,包括功能码的解析和执行。
  3. 通信协议
    RS485:使用标准的RS485通信协议进行数据传输。
    Modbus:实现Modbus RTU模式,提供标准的通信接口。
  4. 系统集成
    将所有硬件组件集成到一个系统中,并进行测试。
    确保软件能够与所有硬件组件协同工作。
  5. 测试与验证
    对系统进行单元测试、集成测试和系统测试。
    验证超声波传感器的准确性和响应时间。
    测试RS485和Modbus协议的通信稳定性。
  6. 用户界面
    如果需要,设计一个简单的用户界面,用于配置和监控系统状态。
  7. 安全与可靠性
    确保系统设计符合车辆安全标准。
    实现错误检测和处理机制,提高系统的可靠性。
  8. 文档与支持
    提供详细的设计文档、用户手册和技术支持。
  • 25
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值