目录

一、HC-SR04简介

二、工作原理

三、多通道超声波


一、HC-SR04简介

超声波测距原理是在超声波发射装置发出超声波,在发射超声波的同时开始计时,超声波在空气中传播,在传播的时刻碰到障碍物,就会返回一个信号给超声波接收器,超声波接收器接收到信号后立即停止计时,这时候会有一个时间t,而超声波在空气中传播的速度为340m/s,通过公式s=340 x t / 200,即可计算出待测距离是多少。

二、工作原理

Step1:通过IO口给Trig接口周期不小于10us的脉冲信号。
Step2:HC-SR04接收到单片机发来的脉冲信号后自动发送8个频率为40KHz的方波,自动检测是否有信号返回。
Step3:若有信号返回,则通过Echo接口向单片机相连的IO口发送一个高电平,高电平持续时间就是超声波从发射到返回的总时间。
距离计算:假设高电平持续时间为T,声速为V(一般为340m/s),时间T是从发射到返回的时间,超声波测距模块到障碍物时间为T的一半。

距离S=(T*V)/2。

三、多通道超声波

整体流程:

1.使用定时器1定时对全部超声波模块进行轮询工作,定时器2为高电平计时时间,外部中断为高电平开始和结束用来使能或失能定时器2。

2.将HC-SR04引脚对应的Tirg引脚设置为推挽输出,将echo引脚设置为上升下降沿的外部中断,一个外部中断服务函数对应一个超声波模块。

三个超声波对应的Tirg引脚分别为D3、D4、D7;echo引脚分别是C0、C1、C3;

超声波初始化

void sr04_init(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7|GPIO_Pin_14;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_ResetBits(GPIOD,GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_7|GPIO_Pin_14); }

外部中断初始化

void exti_Configure(void){GPIO_InitTypeDef GPIO_InitStructure;EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC, GPIO_Pin_0);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_ResetBits(GPIOC, GPIO_Pin_1);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_ResetBits(GPIOC, GPIO_Pin_2);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_ResetBits(GPIOC, GPIO_Pin_3);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);//中断优先级分组使能EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);EXTI_InitStructure.EXTI_Line = EXTI_Line1;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);EXTI_InitStructure.EXTI_Line = EXTI_Line2;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);EXTI_InitStructure.EXTI_Line = EXTI_Line3;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);EXTI_ClearITPendingBit(EXTI_Line0);EXTI_ClearITPendingBit(EXTI_Line1);EXTI_ClearITPendingBit(EXTI_Line2);}

其中一个中断服务函数

void EXTI0_IRQHandler(void){if (EXTI_GetITStatus(EXTI_Line0) != RESET) {if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_0) != 0) { TIM_Cmd(TIM2, ENABLE);} else {TIM_Cmd(TIM2, DISABLE);measurement[0] = TIM_GetCounter(TIM2);TIM_SetCounter(TIM2, 0); distance[0]= (count*65536+measurement[0])/1.0/10000*340;}}EXTI_ClearITPendingBit(EXTI_Line0);}

定时器的中断服务函数

void TIM2_IRQHandler(void)/{if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET){count++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}}void TIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){sr04_1();sr04_2();sr04_3();TIM_SetCounter(TIM3, 0); TIM_ClearITPendingBit(TIM3,TIM_IT_Update);}}

启动第一个超声波模块测距

#definetri1 PDout(3)void sr04_1(void){ count=0;tri1=1;Delay_us(15);}

distance[i]为测距结果。