stm32f429+超声波传感器HC-SR04 -- 测距

工具

1. 开发板stm32f429(f4系列的应该都可以)

2. 超声波传感器,型号为HC-SR04

HC-SR04接线
HC-SR04stm32f4
VCCVCC(5V)
GNDGND
Trig推挽普通输出模式
Echo上拉输入,需开启外部中断

代码实现逻辑:

1. 配置定时器TIM4用于计算Echo高电平信号的时长

void TIM4_Init(u16 arr,u16 psc) // TIM4 rewrite
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure; //定时器参数初始化
	
	//初始化定时器
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);  	//TIM4时钟使能 
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //输入捕获会用到
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);//初始化定时器4
}

2. 配置两个IO给Trig和Echo
1)使能 IO 口时钟,包括使能 SYSCFG 时钟用于外部中断
2)初始化Echo的 IO 口为上拉输入,初始化Trig的 IO 口为上拉推挽普通输出
3)设置 Echo的 IO 口与中断线的映射关系,设置中断线上升沿触发中断模式
4)配置中断优先级分组(NVIC),并使能中断
5)编写中断服务函数

void HCSR04_GPIO_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	EXTI_InitTypeDef  EXTI_InitStructure;
	NVIC_InitTypeDef  NVIC_InitStructure; 
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 	//使能PORTD时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能 SYSCFG 时钟,外部中断
	
	// GPIO PD1 输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;// PD1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //输入功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOD,&GPIO_InitStructure);  //初始化IO口
	
	// GPIO PD0 推挽普通输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出功能
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
	GPIO_Init(GPIOD,&GPIO_InitStructure);  //初始化IO口
	
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource1); // 配置 GPIO 与中断线的映射关系: 将中断线 1 与 GPIOD 映射起来,即GPIOD.1 与 EXTI1 中断线连接
	
	//外部中断配置
	EXTI_InitStructure.EXTI_Line=EXTI_Line1;
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //中断
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising; //上升沿触发
	EXTI_Init(&EXTI_InitStructure);
	
	//配置中断分组(NVIC),并使能中断
	NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn; //使能外部中断通道 
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能外部中断通道
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级 2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02; //响应优先级 2
	NVIC_Init(&NVIC_InitStructure);
}

void EXTI1_IRQHandler(void)
{
	delay_us(10);
	if(EXTI_GetITStatus(EXTI_Line1)!=RESET) //判断中断线1上的中断是否发生(标志位是否置位)
	{
		TIM_SetCounter(TIM4,0); 
		TIM_Cmd(TIM4,ENABLE);
		while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_1));  //等待PD1低电平	
		TIM_Cmd(TIM4,DISABLE);
		
		Distance=(TIM_GetCounter(TIM4)*340)/200.0;
		printf("Distance:%f cm\r\n",Distance); 
		
		EXTI_ClearITPendingBit(EXTI_Line1); // 清除中断线1的中断标志位
	}
}

3. 编写函数:使能超声波传感器,测算距离一次

void HCSR04_Start(void)
{
	GPIO_SetBits(GPIOD,GPIO_Pin_0);   //将Trig设置为高电平
	delay_us(12);               //持续大于10us触发,触发超声波模块工作
	GPIO_ResetBits(GPIOD,GPIO_Pin_0); 
}

4. 如何在main中调用

#include "sys.h"
#include "delay.h"  
#include "usart.h"
#include "timer.h"
#include "hc_sr04.h"

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    delay_init(180);  //初始化延时函数 
    USART1_init(9600);//初始化串口波特率为9600
	
    TIM4_Init(9998,7199); //定时器初始化
    HCSR04_GPIO_Init(); //超声波传感器初始化
	
    while(1)
    {
			u8 i=0;
			while(i<10){
				delay_ms(100); // 超声波工作周期建议在60ms以上,以防止发射信号对回响信号的影响
				i++;
			}
			
        HCSR04_Start(); // 使能超声波传感器,测算距离一次
    }
}

声明:

1. 代码不完全,基于正点原子F4的项目文件编写

2. 此文参照他人的分享(STM32学习笔记——HC—SR04(超声波模块)_精神小火君-CSDN博客_正点原子超声波)/如若侵犯请联系删除

3. 以上代码已在传感器上经过验证没有问题

4. 项目文件上传到github(GitHub - Liqing-Ye/stm32f4-HC-SR04: stm32f4+HC-SR04超声波测距

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值