微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 超声波测距HC-SR04测得的距离不变,急,求指正!谢谢!

超声波测距HC-SR04测得的距离不变,急,求指正!谢谢!

时间:10-02 整理:3721RD 点击:
定时器配置:
#include "timer.h"
#include "led.h"
#include "stm32f10x.h"
//通用定时器中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3
void Timerx_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_div1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM3,TIM_IT_Update  |TIM_IT_Trigger,ENABLE);
        TIM_ARRPreloadConfig(TIM3,ENABLE);
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//        TIM_Cmd(TIM2, ENABLE);  //使能TIMx外设
                                                         
}
void TIM3_IRQHandler(void)   //TIM2中断
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
                {
                   TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
                }
}

超声波模块配置:
#include "UltrasonicWave.h"
#include "usart.h"
#include "delay.h"

#define        TRIG_PORT      GPIOC                //TRIG      
#define        ECHO_PORT      GPIOA                //ECHO
#define        TRIG_PIN       GPIO_Pin_8   //TRIG      
#define        ECHO_PIN       GPIO_Pin_7        //ECHO   
float UltrasonicWave_Distance;      //计算出的距离   

/*
* 函数名:UltrasonicWave_Configuration
* 描述  :超声波模块的初始化
* 输入  :无
* 输出  :无       
*/
void UltrasonicWave_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;       
          EXTI_InitTypeDef EXTI_InitStructure;
           NVIC_InitTypeDef NVIC_InitStructure;
       
//          GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);        //关闭jtag
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = TRIG_PIN;                                         //PC8接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_IN_FLOATING;                 //设为输入
    GPIO_Init(ECHO_PORT,&GPIO_InitStructure);                                                 //初始化GPIOA
       
          //GPIOC.7          中断线以及中断初始化配置
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource7);
          EXTI_InitStructure.EXTI_Line=EXTI_Line7;
          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 = EXTI9_5_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寄存器
}

void EXTI9_5_IRQHandler(void)
{     
          delay_us(60);                                      //延时10us
     if(EXTI_GetITStatus(EXTI_Line7) != RESET)
        {
                        TIM_SetCounter(TIM3,0);
                        TIM_Cmd(TIM3, ENABLE);                                             //开启时钟
               
                        while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN));                         //等待低电平
                        TIM_Cmd(TIM3, DISABLE);                        //定时器2失能
                    delay_ms(60);
                    
                        UltrasonicWave_Distance=TIM_GetCounter(TIM3)*5*34/200.0;                //计算距离&&UltrasonicWave_Distance<150       
//                    TIM_Cmd(TIM3, DISABLE);       
             if(UltrasonicWave_Distance>0)
                         {                                 
                                printf("distance:%f cm\t\n",UltrasonicWave_Distance);
                         }
       
           EXTI_ClearITPendingBit(EXTI_Line7);  //清除EXTI7线路挂起位
  }
        else while(EXTI_GetITStatus(EXTI_Line7) == RESET);
}
/*
* 函数名:UltrasonicWave_StartMeasure
* 描述  :开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间
* 输入  :无
* 输出  :无       
*/
void UltrasonicWave_StartMeasure(void)
{
  GPIO_SetBits(TRIG_PORT,TRIG_PIN);                   //送>10US的高电平RIG_PORT,TRIG_PIN这两个在define中有?
  delay_us(20);                                      //延时20US
  GPIO_ResetBits(TRIG_PORT,TRIG_PIN);
       
}
主函数:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "exti.h"
#include "timer.h"
#include "UltrasonicWave.h"

int main(void)
{
         
// SystemInit();
        delay_init();                  //延时初始化
//        NVIC_Configuration();
         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
        uart_init(115200);         //串口初始化
        LED_Init();                            //LED端口初始化
        Timerx_Init(4999,7199);   //10Khz的计数频率,计数到5000为500ms
        UltrasonicWave_Configuration();               //对超声波模块初始化
                        

        while(1)
        {
                        UltrasonicWave_StartMeasure();
               
        //开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间
//                LED0=!LED0;
//                delay_ms(1000);       
       
               
        }

我也是在准备中,不是很清楚,只是感觉这发送一个脉冲波形,就想测出距离,是不是有问题?
IO/中断这个得自己检查了,我只是好奇,声波1ms走0.3米,你中断里面有做延时60ms,也就是至少障碍物要距离>1.8米才行,而1.8米的话,超声波探测会不会有问题?你可以根据这个检查一下你的测试环境,再看看代码里面是否与之匹配。

60ms的延时是采样周期,是防止回响信号的影响(网上看的),其实我有把60ms去掉试过,但没用,一直都是0.85,就是在串口显示的速度快点,这程序是在网上找的然后我改了下TIM,我用过普通IO写,用过输入捕获,但都失败了!输入捕获的话会在11~21cm间跳,但我都没碰过模块,数值都会变,不知道怎么回事?已经调试3天了,要是你写出来了希望可以指点下

仔细看了一下你贴出来的代码,好像不全。Distance不知道咋算出来的,所以爱莫能助了。
按照我的理解,你应该是在发射的时候记录下一个时间a,然后等待接收中断后记录一个时间b,两者相减乘以声波速度再除以2,就是距离了。
可我并未看见你在发射的时候有任何记录时间的操作。不行就先用示波器排查有无问题吧。示波器的波形时差已经能够估算出距离了。

Distance是个公式,用了340m/s换成cm算了的,其实主要问题是打印出来数据不变,至于时间的话我用TIM计时了,公式中用了个函数就是读取TIM时间的函数,我在TIM输出为高时开启定时器,为低时关闭定时器,就是把这段时间给读取出来了,这就是算距离的公式吧!

感觉距离的计算公式不对,为何要*5?推理出来的应该是1.7倍的计数值,单位是cm

是模块没用了,程序没问提的!

模块坏了,测的距离就会一直不变是吗?

我的是这样的,换了个模块就没事了,其它情况不理解,程序错误也会这样,可以用示波器观察下!

代码看起来没有问题啊,但是计算距离的公式有点不明白,贴上我的试试看
/**
  ******************************************************************************
  * @file    Ultrasound.c
  * @author  xjg
  * @version V1.0
  * @date    2017-4-26
  * @brief   超声波模块控制函数接口
  ******************************************************************************
  * @attention
  *
  * 实验平台:STM32F103CB
  *
  ******************************************************************************
  */
  
#include "Ultrasound.h"
extern u8 overcnt;
float RespondTime = 0;
float SubTimeCnt = 0,Distance = 0,Predistance = 0;
u8 js;
static void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* 嵌套向量中断控制器组选择 */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置USART为中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = ULTRISOUND_ECHO_EXTI_IRQ;
  /* 抢断优先级*/
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  /* 子优先级 */
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  /* 使能中断 */
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  /* 初始化配置NVIC */
  NVIC_Init(&NVIC_InitStructure);
}

static void ULTRISOUND_TRIG_ECHO_GPIO_INIT(void)
{
                /*定义一个GPIO_InitTypeDef类型的结构体*/
                GPIO_InitTypeDef GPIO_InitStructure;
                /*开启LED相关的GPIO外设时钟*/
                RCC_APB2PeriphClockCmd( ULTRISOUND_TRIG_GPIO_CLK|ULTRISOUND_ECHO_GPIO_CLK , ENABLE);
         
                /*设置引脚速率为50MHz */   
                GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
                /*设置引脚模式为推挽输出*/
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
                /*选择要控制的GPIO引脚*/
                GPIO_InitStructure.GPIO_Pin = ULTRISOUND_TRIG_GPIO_PIN;
                /*调用库函数,初始化TRIG*/
                GPIO_Init(ULTRISOUND_TRIG_GPIO_PORT, &GPIO_InitStructure);
       
       
                        /*设置引脚模式为浮空输入*/
                GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
                /*选择要控制的GPIO引脚*/
                GPIO_InitStructure.GPIO_Pin = ULTRISOUND_ECHO_GPIO_PIN;
                /*调用库函数,初始化ECHO*/
                GPIO_Init(ULTRISOUND_ECHO_GPIO_PORT, &GPIO_InitStructure);
               
                GPIO_EXTILineConfig(ULTRISOUND_ECHO_EXTI_PORTSOURCE,ULTRISOUND_ECHO_EXTI_PINSOURCE);
       
}
static void ULTRISOUND_TECHO_EXTI_INIT(void)
{
//                EXTI_InitTypeDef EXTI_InitSturct;
//       
//                RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO , ENABLE);
//       
//                EXTI_InitSturct.EXTI_Line = ULTRISOUND_ECHO_EXTI_Line;
//       
//                EXTI_InitSturct.EXTI_LineCmd = ENABLE;
//               
//                EXTI_InitSturct.EXTI_Mode = EXTI_Mode_Interrupt;
//       
//                EXTI_InitSturct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//EXTI_Trigger_Rising_Falling;
//       
//                EXTI_Init(&EXTI_InitSturct);
//       
//                EXTI_ClearITPendingBit(ULTRISOUND_ECHO_EXTI_Line);
//       
//               
//       
//                GPIO_InitTypeDef GPIO_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
  EXTI_InitStructure.EXTI_Line = ULTRISOUND_ECHO_EXTI_LINE;
       
        /* EXTI为中断模式 */
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        /* 上升沿中断 */
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  /* 使能中断 */       
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
       
  EXTI_Init(&EXTI_InitStructure);
}
static void ULTRISOUND_TIM_INIT()
{
        //定义基本定时器,比较输出定时器结构体
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSturct;
       
        //初始化定时器的时钟
        RCC_APB1PeriphClockCmd(ULTRISOUND_TIM_CLK,ENABLE);
       
       
        TIM_DeInit(ULTRISOUND_TIM);
        //配置基本定时器
        TIM_TimeBaseInitSturct.TIM_ClockDivision = TIM_CKD_div1;
       
        TIM_TimeBaseInitSturct.TIM_CounterMode = TIM_CounterMode_Up;
       
        TIM_TimeBaseInitSturct.TIM_Period = 0xffff;
       
        TIM_TimeBaseInitSturct.TIM_Prescaler = 72-1;
       
        TIM_TimeBaseInit(ULTRISOUND_TIM,&TIM_TimeBaseInitSturct);
       
        TIM_SetCounter(ULTRISOUND_TIM,0);
       
       
}

void ULTRISOUND_INIT(void)
{
        ULTRISOUND_TRIG_ECHO_GPIO_INIT();
       
        ULTRISOUND_TECHO_EXTI_INIT();
       
        NVIC_Configuration();
       
        ULTRISOUND_TIM_INIT();
}
void Get_Distance(void)
{
        u16 subcnt;
       
        subcnt = TIM_GetCounter(ULTRISOUND_TIM);
       
       
       
        printf("subcnt=%d\n",subcnt);
       
        TIM_SetCounter(ULTRISOUND_TIM,0);
       
        RespondTime = (overcnt*0xffff+subcnt)*0.000001;
//        RespondTime = SubTimeCnt*0.000001;
       
        Distance = (RespondTime*314)/2*100;
       
        if(js < 1)
        {
                        Predistance = Distance;
                       
                        js++;
               
                        return;
       
        }
        else
        {
                        if(Predistance > Distance)
                        {
                                Distance = Predistance;
                        }
                       
                        js = 0;
       
        }
//        Distance = subcnt/58;
        overcnt = 0;
       
        printf("Distance=%2.f\n",Distance);
       
//        SubTimeCnt = 0;
}



void ULTRISOUND_ECHO_IRQHandler(void)
{
//        if(EXTI_GetITStatus(ULTRISOUND_ECHO_EXTI_Line) == SET)
//        {
//                printf("\r\n*********ccccccccccccccc***********\r\n");
        OSIntEnter();
                if((ULTRISOUND_ECHO_GPIO_PORT->IDR & ULTRISOUND_ECHO_GPIO_PIN) == 0)
                {
                       
                        TIM_Cmd(ULTRISOUND_TIM,DISABLE);
//                        printf("停止计数\n");
//                        EHO_START_CNT_FLAG = 0;
                       
                        Get_Distance();
                }
                else
                {
                       
                        TIM_Cmd(ULTRISOUND_TIM,ENABLE);//开始计数
//                        printf("开始计数\n");
//                        EHO_START_CNT_FLAG = 1;
                       
                }
       
//        }
        EXTI_ClearITPendingBit(ULTRISOUND_ECHO_EXTI_LINE);
                OSIntExit();
       
}
void ULTRISOUND_TIM_IRQHandl(void)
{
        OSIntEnter();
        if(TIM_GetITStatus(ULTRISOUND_TIM,TIM_IT_Update)!=RESET)
  {
                TIM_ClearITPendingBit(ULTRISOUND_TIM,TIM_IT_Update);
                //清除中断标志
                overcnt++;
  }
        OSIntExit();
}

HENHAO

把VCC换成5v就好了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top