1.器件介紹
1.1.參數(shù)
1.2.測(cè)量范圍
- 最近距離 2cm
- 最遠(yuǎn)距離 4m
- 測(cè)量角度 15度
1.3.計(jì)算公式
測(cè)試距離=(高電平時(shí)間*聲速(340M/S))/2
1.4.優(yōu)點(diǎn)
- 性能穩(wěn)定
- 測(cè)度距離精確
- 模塊高精度
- 盲區(qū)小
- 易于使用
2.使用原理
2.1.原理
使用stm32的定時(shí)器測(cè)量反射波的返回時(shí)間,再根據(jù)計(jì)算公式求出物體的相對(duì)距離,
3.代碼編寫
3.1.接線圖
3.2.代碼
3.2.1.HC_SR04.h
#ifndef __HC_SR04_H
#define __HC_SR04_H
#include "sys.h"
#define SR04_Trlg PBout(12)// PB12
#define SR04_Echo PBin(13)// PB13
void HC_SR04_IO_Init(void);
u16 Get_SR04_Distance(void);
#endif
3.2.2.HC_SR04.c
#include "HC_SR04.h"
#include "timer.h"
#include "delay.h"
//
void HC_SR04_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能PB端口時(shí)鐘
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIOB.12
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //根據(jù)設(shè)定參數(shù)初始化GPIOB.13
}
u16 TIM2_UPDATA = 0;
u32 temp = 0;
u16 Get_SR04_Distance(void)
{
SR04_Trlg=1; //觸發(fā)信號(hào)是高電平脈沖,寬度大于10us
delay_us(20);
SR04_Trlg=0;
while(!SR04_Echo); //等待高電平
TIM_SetCounter(TIM2,0); //重填計(jì)數(shù)器值
TIM2_UPDATA = 0; //溢出次數(shù)清零
while(SR04_Echo); //等待低電平
TIM_Cmd(TIM2,DISABLE); //暫時(shí)關(guān)閉定時(shí)器,保證數(shù)據(jù)正確性
temp = (int)(((double)(TIM_GetCounter(TIM2) + (7200* TIM2_UPDATA)))/72/2); //得到高電平總時(shí)間,單位us(定時(shí)器的計(jì)數(shù)值加上溢出的值才是高電平的時(shí)間),除以2是計(jì)算單程的時(shí)間
//(7200* TIM2_UPDATA這里為溢出的時(shí)間us,可以轉(zhuǎn)換為100* TIM2_UPDATA,因?yàn)樵诠胶竺娉粤?2??勺罱K理解為TIM2_UPDATA個(gè)100us)
TIM_Cmd(TIM2,ENABLE);
return temp;
}
3.2.3.timer.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM2_Init(u16 arr,u16 psc);
#endif
3.2.4.timer.c
#include "timer.h"
#include "delay.h"
#include "sys.h"
void TIM2_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能TIM2時(shí)鐘
//初始化定時(shí)器2
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)定計(jì)數(shù)器自動(dòng)重裝值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //預(yù)分頻器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
//中斷分組初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占優(yōu)先級(jí)2級(jí)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //從優(yōu)先級(jí)0級(jí)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//允許更新中斷 ,
TIM_Cmd(TIM2,ENABLE ); //使能定時(shí)器2
}
//定時(shí)器2中斷服務(wù)程序 主要記錄溢出次數(shù)
extern u16 TIM2_UPDATA;
extern u8 state_machine;
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //檢查指定的TIM中斷發(fā)生與否:TIM 中斷源
{
TIM2_UPDATA++;//當(dāng)回響信號(hào)很長(zhǎng)時(shí),記錄溢出次數(shù),每加一次代表加100us
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除中斷標(biāo)志位
}
}
?3.2.5.main.c
int main(void)
{
u16 time=0;
delay_init(); //延時(shí)函數(shù)初始化
uart_init(115200);
HC_SR04_IO_Init(); //超聲波模塊GPIO初始化
delay_ms(500); //上電瞬間加入一定延時(shí)在初始化
TIM2_Init(7199,0); //以10KHz計(jì)數(shù),定時(shí)100us
HC05_Role_Show();
delay_ms(100);
while(1)
{
time++ ;
Distance = (Get_SR04_Distance() * 331) * 1.0/1000; //Get_SR04_Distance()返回單程聲波傳輸時(shí)間 us,轉(zhuǎn)換為秒=時(shí)間*10^(-6);331m/s等于331000mm/s,
//最終換算為Distance =Get_SR04_Distance()*10^(-6)*331000=(Get_SR04_Distance() * 331) * 1.0/1000;
delay_ms(10);
if(time==300) {
printf("%.1fn",Distance);
HC05_Sta_Show();
time=0;
}
}
}
聯(lián)系方式 微信號(hào):13648103287