打印
[应用相关]

stm32超声波

[复制链接]
72|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-3-14 16:15 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本文基于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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1364

主题

13994

帖子

8

粉丝