HC-SR04产品特点
1、典型工作用电压:5V。
2、超小静态工作电流:小于2mA。
3、感应角度:不大于15 度。
4、探测距离:2cm-400cm
5、高精度:可达0.3cm。
6、盲区(2cm)超近。
接口:
Vcc、 Trig(控制端)、 Echo(接收端)、 Gnd
使用方法:
控制口发一个10US 以上的高电平,
就可以在接收口等待高电平输出.
一有输出就可以开定时器计时,
当此口变为低电平时就可以读定时器的值,
此时就为此次测距的时间,方可算出距离.如此不断的周期测,就可以达到你移动测量的值了。
模块工作原理:
(1)采用 IO 触发测距,给至少10us 的高电平信号;
(2)模块自动发送8 个40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间
(4) 测试距离=(高电平时间*声速(340M/S))/2;
代码详解
#include "stm32f10x.h"
#include "delay.h"
#include "motor.h"
#include "keysacn.h"
#include "IRSEARCH.h"
#include "IRAvoid.h"
#include "usart.h"
#include "UltrasonicWave.h"
#include "timer.h"
//extern int U_temp;
/*
void ZYSTM32_run(int speed,int time); //前进函数
void ZYSTM32_brake(int time); //刹车函数
void ZYSTM32_Left(int speed,int time); //左转函数
void ZYSTM32_Spin_Left(int speed,int time); //左旋转函数
void ZYSTM32_Right(int speed,int time); //右转函数
void ZYSTM32_Spin_Right(int speed,int time);//右旋转函数
void ZYSTM32_back(int speed,int time); //后退函数
*/
int main(void)
{
delay_init();
KEY_Init();
IRSearchInit();
IRAvoidInit();
Timerx_Init(5000,7199); //10Khz的计数频率,计数到5000为500ms
UltrasonicWave_Configuration(); //对超声波模块初始化
uart_init(115200);
TIM4_PWM_Init(7199,0); //初始化PWM
ZYSTM32_brake(500);
keysacn();
while(1)
{
//printf("测到的距离值为:%d\n",UltrasonicWave_StartMeasure());
if(UltrasonicWave_StartMeasure()<40)
{
ZYSTM32_brake(500);
ZYSTM32_back(70,1000);
ZYSTM32_brake(500);
ZYSTM32_Right(70,500);
BEEP_SET;
}
else
{
ZYSTM32_run(70,1);
BEEP_RESET;
}
}
}
#include "UltrasonicWave.h"
#include "usart.h"
#include "timer.h"
#include "delay.h"
#define TRIG_PORT GPIOC //TRIG
#define ECHO_PORT GPIOC //ECHO
#define TRIG_PIN GPIO_Pin_0 //TRIG 发出端
#define ECHO_PIN GPIO_Pin_1 //ECHO 接收端
float UltrasonicWave_Distance; //计算出的距离
/*
* 函数名:UltrasonicWave_Configuration
* 描述 :超声波模块的初始化
* 输入 :无
* 输出 :无
*/
void UltrasonicWave_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = TRIG_PIN; //PC0接TRIG
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设为推挽输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(TRIG_PORT, &GPIO_InitStructure); //初始化外设GPIO
GPIO_InitStructure.GPIO_Pin = ECHO_PIN; //PC7接ECH0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设为输入
GPIO_Init(ECHO_PORT,&GPIO_InitStructure); //初始化GPIOA
//GPIOC.1 中断线以及中断初始化配置
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;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; //使能按键所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
//------------------------通道1中断函数---------------------------------------------
void EXTI1_IRQHandler(void)
{
delay_us(10); //延时10us
if(EXTI_GetITStatus(EXTI_Line1) != RESET)
{
TIM_SetCounter(TIM2,0);
TIM_Cmd(TIM2, ENABLE); //开启时钟
while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN)); //等待低电平
TIM_Cmd(TIM2, DISABLE); //定时器2失能
UltrasonicWave_Distance=TIM_GetCounter(TIM2)*5*34/200.0; //计算距离&&UltrasonicWave_Distance<150
// U_temp = UltrasonicWave_Distance*10;
// if(UltrasonicWave_Distance>0)
// {
// printf("distance:%f mm",UltrasonicWave_Distance*10);
// }
EXTI_ClearITPendingBit(EXTI_Line1); //清除EXTI1线路挂起位
}
}
/*
* 函数名:UltrasonicWave_StartMeasure
* 描述 :开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间
* 输入 :无
* 输出 :无
*/
int UltrasonicWave_StartMeasure(void) //测量距离函数,返回值为距离
{
int u_temp;
GPIO_SetBits(TRIG_PORT,TRIG_PIN); //送>10US的高电平RIG_PORT,TRIG_PIN这两个在define中有?
delay_us(20); //延时20US
GPIO_ResetBits(TRIG_PORT,TRIG_PIN); //控制端拉低成低电平,等待高电平的到来,且上升沿引发外部中断触发,计算时间,公式计算出距离
u_temp = UltrasonicWave_Distance*10;
return u_temp;//返回距离值
}