1. 开发板stm32f429(f4系列应该都可以)
2. 超声传感器型号为HC-SR04
HC-SR04 | stm32f4 |
---|---|
VCC | VCC(5V) |
GND | GND |
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); us触发,触发超声波模块工作 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超声波测距)