本文基于GPIO来编程
编程逻辑:超声波时序向Trig引脚一个大于10us高电平,接着Echo会接收一个距离等比高电平
利用定时器TIM3,10us定时中断一次计数值加一,当Echo脚低电平清除计数值,等待高电平结束赋值到变量,那就是时间值,根据V=S/T算出距离,大于38ms则错误返回0
时间T(s)=1/频率(hz)=1/1000000=0.000001s=1us
TIM_TimeBaseInitStructure.TIM_Period = 10 - 1; //设置最大计数值,达到最大值触发更新事件,因为从0开始计数,所以计数10次是10-1,每10微秒触发一次
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //设置时钟预分频,72-1就是每 时钟频率(72Mhz)/72=1000000 个时钟周期计数器加1,每1微秒+1
#include "stm32f10x.h"
#include "delay.h"
#include "stm32f10x_tim.h"
#define Echo GPIO_Pin_6 //HC-SR04模块的Echo脚接GPIOA6
#define Trig GPIO_Pin_0 //HC-SR04模块的Trig脚接GPIOA5
uint64_t time=0; //声明变量,用来计时
uint64_t time_end=0; //声明变量,存储回波信号时间
/*
计算距离函数
*/
void HC_SR04_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启用GPIOA的外设时钟
GPIO_InitTypeDef GPIO_InitStructure; //定义结构体
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置GPIO口为推挽输出
GPIO_InitStructure.GPIO_Pin = Trig; //设置GPIO口5
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置GPIO口速度50Mhz
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIOA
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置GPIO口为下拉输入模式
GPIO_InitStructure.GPIO_Pin = Echo; //设置GPIO口6
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIOA
GPIO_WriteBit(GPIOA,GPIO_Pin_0,0); //输出低电平
delay_us(15); //延时15微秒>10us
}
int16_t sonar_mm(void) //测距并返回单位为毫米的距离结果
{
uint32_t Distance,Distance_mm = 0;
GPIO_WriteBit(GPIOA,Trig,1); //输出高电平
delay_us(15); //延时15微秒
GPIO_WriteBit(GPIOA,Trig,0); //输出低电平
while(GPIO_ReadInputDataBit(GPIOA,Echo)==0); //等待低电平结束
time=0; //计时清零
while(GPIO_ReadInputDataBit(GPIOA,Echo)==1); //等待高电平结束,与距离相等的高电平
time_end=time; //记录结束时的时间
if(time_end/100<38) //判断是否小于38毫秒,大于38毫秒的就是超时,直接调到下面返回0
{
Distance=(time_end*346)/2; //计算距离,25°C空气中的音速为346m/s,一半距离
Distance_mm=Distance/100; //因为上面的time_end的单位是10微秒,所以要得出单位为毫米的距离结果,还得除以100
}
return Distance_mm; //返回测距结果
}
float sonar(void) //测距并返回单位为米的距离结果
{ float Distance_m = 0;
Distance_m=sonar_mm()/10;
return Distance_m;
}
void TIM3_IRQHandler(void) //更新中断函数,用来计时,每10微秒变量time加1
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //获取TIM3定时器的更新中断标志位
{
time++;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除更新中断标志位
}
}
#include "stm32f10x.h" // Device header
#include "delay.h"
#include "oled.h"
#include "IC.h"
#include "pwm.h"
int main(void)
{ delay_init();
OLED_Init(); //初始化OLED屏
Timer_Init(); //初始化定时器
HC_SR04_Init(); //初始化超声波测距模块
OLED_Clear(0);
OLED_ShowString(1, 1, "sensor: mm",16); //OLED屏输出字符串
OLED_ShowString(1, 3, "sensor: cm",16);
while (1)
{
int Distance_mm=sonar_mm(); //获取距离测量结果,单位毫米(mm)
OLED_ShowNum(60,1,Distance_mm,4,16);//mm
OLED_ShowNum(60,3,Distance_mm*0.1,4,16);//cm
delay_ms(30); //延时300毫秒
}
}
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/2301_81993111/article/details/136410580
|