找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1784|回复: 1
收起左侧

stm32驱动HCRS04超声波测距模块,分享一下我的驱动程序

[复制链接]
ID:405345 发表于 2019-4-17 21:01 | 显示全部楼层 |阅读模式
#include "RCWL.h"
   
#define RCWL1601_PORT GPIOB  
#define RCWL16014_CLK RCC_APB2Periph_GPIOB  
#define RCWL1601_TRIG GPIO_Pin_5  
#define RCWL1601_ECHO GPIO_Pin_6  
#define RCC_APB1Periph_TIM  RCC_APB1Periph_TIM2
#define RCTW_TIM TIM2
#define RCTW_IRQn  TIM2_IRQn
#define TRIG_Send PBout(5)   
#define ECHO_Reci PBin(6)  

  
u16 msRcCount = 0; //毫秒计数  
void RCWL1601_NVIC(void);  
  
void  RCWL1601_Init()  
{   
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure_RCWL;     //生成用于定时器设置的结构体  
    GPIO_InitTypeDef GPIO_InitStructure_RCWL;  
    RCC_APB2PeriphClockCmd(RCWL16014_CLK,ENABLE);  
      
        // IO初始化  
    GPIO_InitStructure_RCWL.GPIO_Pin = RCWL1601_TRIG;       //发送电平引脚  
    GPIO_InitStructure_RCWL.GPIO_Speed = GPIO_Speed_50MHz;  
    GPIO_InitStructure_RCWL.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出  
    GPIO_Init(RCWL1601_PORT,&GPIO_InitStructure_RCWL);  
    GPIO_ResetBits(RCWL1601_PORT,RCWL1601_TRIG);  
      
    GPIO_InitStructure_RCWL.GPIO_Pin = RCWL1601_ECHO;     //返回电平引脚  
    GPIO_InitStructure_RCWL.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入  
    GPIO_Init(RCWL1601_PORT,&GPIO_InitStructure_RCWL);   
    GPIO_ResetBits(RCWL1601_PORT,RCWL1601_ECHO);      
      
            //定时器初始化使用基本定时器TIM6  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM,ENABLE);   //使能对应RCC时钟  
        //配置定时器基础结构体  
    TIM_DeInit(RCTW_TIM);  
    TIM_TimeBaseStructure_RCWL.TIM_Period =(1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的计数到1000为1ms  
    TIM_TimeBaseStructure_RCWL.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值1M的计数频率1US计数  
    TIM_TimeBaseStructure_RCWL.TIM_ClockDivision = TIM_CKD_DIV1; //不分频  
    TIM_TimeBaseStructure_RCWL.TIM_CounterMode = TIM_CounterMode_Up;  // TIM向上计数模式  
    TIM_TimeBaseInit(RCTW_TIM,&TIM_TimeBaseStructure_RCWL); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMX的时间基数单位         
         
    TIM_ClearFlag(RCTW_TIM,TIM_FLAG_Update);   //清除更新中断,免得一打开中断立即产生中断  
    TIM_ITConfig(RCTW_TIM,TIM_IT_Update,ENABLE);    //打开定时器更新中断  
    RCWL1601_NVIC();  
    TIM_Cmd(RCTW_TIM,DISABLE);      
}  
  
  
//提示:静态函数的作用域仅限于定义它的源文件内,所以不需要在头文件里声明  
static void  OpenTimerForHc()         //打开定时器   
{  
        TIM_SetCounter(RCTW_TIM,0); //清除计数  
        msRcCount = 0;  
        TIM_Cmd(RCTW_TIM,ENABLE);  //使能TIMX外设  
}  
   
static void  CloseTimerForHc()        //关闭定时器   
{  
     TIM_Cmd(RCTW_TIM,DISABLE);  //使能TIMX外设  
}  
   
   
// NVIC配置  
void RCWL1601_NVIC()  
{  
    NVIC_InitTypeDef NVIC_InitStructure;  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  
      
    NVIC_InitStructure.NVIC_IRQChannel = RCTW_IRQn;             //选择串口1个中断  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占式中断优先级设置为1  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         //响应式中断优先级设置为1  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能中断  
    NVIC_Init(&NVIC_InitStructure);  
}  
  
  
//定时器6中断服务程序  
void  TIM2_IRQHandler(void)    // TIM3中断  
{  
        if(TIM_GetITStatus(RCTW_TIM,TIM_IT_Update)!= RESET)   //检查TIM3更新中断发生与否  
        {  
                TIM_ClearITPendingBit(RCTW_TIM,TIM_IT_Update);  //清除TIMX更新中断标志   
                msRcCount++;  
        }  
}  
   
  
//获取定时器时间  
u32 GetEchoTimer(void)  
{  
        u32 t = 0;  
        t= msRcCount*1000; //得到MS  
        t+= TIM_GetCounter(RCTW_TIM); //得到us
        RCTW_TIM-> CNT = 0;  //将TIM2计数寄存器的计数值清零  
        Delay_Ms(50);  
        return t;  
}  
   
  
//一次获取超声波测距数据两次测距之间需要相隔一段时间,隔断回响信号  
//为了消除余震的影响,取五次数据的平均值进行加权滤波。  
float   RCWL1601GetLength(void)  
{  
        u32 t = 0;  
        int  i = 0;  
        float  lengthTemp = 0;  
        float  sum = 0;  
        while(i!=5)  
        {  
        TRIG_Send = 1;      //发送口高电平输出  
        Delay_Us(20);  
        TRIG_Send = 0;  
        while (ECHO_Reci==0);      //等待接收口高电平输出  
            OpenTimerForHc();        //打开定时器  
        i = i + 1;  
        while (ECHO_Reci==1);  
            CloseTimerForHc();        //关闭定时器  
        t = GetEchoTimer();        //获取时间,分辨率为1US  
        lengthTemp =((float )t /58.0); //厘米  
        sum = lengthTemp + sum;  
         
    }  
        lengthTemp = sum / 5.0;  
        return lengthTemp;  
}  
  
  
/*
函数名称:Delay_Ms_Ms
**功能描述:延时1MS(可通过仿真来判断他的准确度)           
**参数描述:time(ms)注意时间<65535
*/  
void  Delay_Ms(uint16_t time)   //延时函数  
{   
    uint16_t i,j;  
    for (i = 0; i <time; i ++)  
        for (j = 0; j <10260; j ++);  
}  
/* :::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::
**函数名称:Delay_Ms_Us
**功能描述:延时1us(可通过仿真来判断他的准确度)
**参数描述:time(us)注意时间<65535                 
:::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::: */  
void  Delay_Us(uint16_t time)   //延时函数  
{   
    uint16_t i,j;  
    for (i = 0; i <time; i ++)  
        for (j = 0; j <9; j ++);  
}
回复

使用道具 举报

ID:1 发表于 2019-4-17 21:26 | 显示全部楼层
本帖需要重新编辑补全电路原理图,源码,详细说明与图片即可获得100+黑币(帖子下方有编辑按钮)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表