分享一个超声波测距的程序,不过实际测试中还有点问题,不知道是什么原因,大神帮看一下呗

2019-08-22 16:14发布

本帖最后由 arao和xiaomi 于 2017-4-5 08:59 编辑

就是有时候能测试准确,但是有时候会有两厘米的误差,感觉不是很稳定,不知道是什么原因,大神帮看一下呗

#include "ultrasonic.h"
#include "sys.h"
#include "delay.h"

#define TRIG_PORT  GPIOB         //TRIG
#define ECHO_PORT  GPIOB         //ECHO

#define TRIG_PIN   GPIO_Pin_0    //TRIG
#define ECHO_PIN   GPIO_Pin_10    //ECHO


float Ultrasonic_Distance;       //计算出的距离
u8 check_data_state;

void Ultrasonic_Init(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_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
        
        
        GPIO_InitStructure.GPIO_Pin=TRIG_PIN;                  //PB0接TRIG   备注5伏供电
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;      //设置为推挽输出模式
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(TRIG_PORT,&GPIO_InitStructure);
        
        GPIO_InitStructure.GPIO_Pin=ECHO_PIN;                 //PB10接ECHO
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;           //设置为输入
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(ECHO_PORT,&GPIO_InitStructure);
        
        
         //PE8    中断线以及中断初始化配置
         GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource10);

          EXTI_InitStructure.EXTI_Line=EXTI_Line10;
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;               //中断触发
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;     //上升沿
          EXTI_InitStructure.EXTI_LineCmd = ENABLE;
          EXTI_Init(&EXTI_InitStructure);                 
               
                        
        NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;                        
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;         
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;                                         
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                 
          NVIC_Init(&NVIC_InitStructure);            
        
        
}


float EXTI15_10_IRQHandler(void)
{
        
        delay_us(10);        
               
     if(EXTI_GetITStatus(EXTI_Line10) != RESET)
        {
                        TIM_SetCounter(TIM2,0);
                        TIM_Cmd(TIM2, ENABLE);                                             
               
                        while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN));                        

                        TIM_Cmd(TIM2, DISABLE);                                                         
                        Ultrasonic_Distance=TIM_GetCounter(TIM2)*9.8*34/200.0;                                                                        
               
        if(Ultrasonic_Distance>0)
        {
                printf("distance:%f cm",Ultrasonic_Distance);
                LCD_ShowString(30,150,200,16,16,"Ultrasonic TEST is OK");
               
        }else
        LCD_ShowString(30,150,200,16,16,"Ultrasonic TEST is error");
               
        
        EXTI_ClearITPendingBit(EXTI_Line10);   
        
        }
        check_data_state=1;
        return Ultrasonic_Distance;
               
}
/*
*  初始化的时候,需要输出10us以上的TTL电平
*  
*
*  
*/





void Ultrasonic_StartMeasure(void)
{
        
  GPIO_SetBits(TRIG_PORT,TRIG_PIN);                  
  delay_us(20);                                   
  GPIO_ResetBits(TRIG_PORT,TRIG_PIN);
        
}





        



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
arao和xiaomi
1楼-- · 2019-08-23 14:48
lycreturn 发表于 2017-3-25 22:26
如果中断频率较高,而中断服务函数占用时间又比较长,有可能丢失部分中断,所以要求中断服务函数占用时间 ...

你好,我按照你的建议把它改成这样,然后老出问题,不知道哪里错了

float EXTI15_10_IRQHandler(void)
{
       
               
               
     if(EXTI_GetITStatus(EXTI_Line10) != RESET)
        {
                        TIM_SetCounter(TIM2,0);
                        TIM_Cmd(TIM2, ENABLE);                                             
               
                        while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN));                         

                        TIM_Cmd(TIM2, DISABLE);                                                        
                        Ultrasonic_Distance=TIM_GetCounter(TIM2)*9.8*34/200.0;                                                 
                        EXTI_ClearITPendingBit(EXTI_Line10);
                        check_data_state=1;               
       
        }
       
        return Ultrasonic_Distance;
               
}

while(1)
        {                 
                Ultrasonic_StartMeasure();
               
               
               
               
                        POINT_COLOR=BLUE;
                       
                        if(check_data_state)
                        {
                                if(Ultrasonic_Distance>0)
                                {
                                        printf("distance:%f cm",Ultrasonic_Distance);
                                        LCD_ShowString(30,150,200,16,16,"Ultrasonic TEST is OK");
                                       
                                        distance=Ultrasonic_Distance;
                                       
                                       
                                       
                                        LCD_ShowxNum(157,170,distance,3,16,0x80);//显示距离值      显示整数部分
                                        Ultrasonic_Distance-=distance;
                                        Ultrasonic_Distance*=100;                                    // 扩大10倍,显示小数 部分
                                        LCD_ShowxNum(184,170,Ultrasonic_Distance,2,16,0x80);
                                }
                                else  LCD_ShowString(30,150,200,16,16,"Ultrasonic TEST is error");
                               
                                check_data_state=0;
                               
                        }
lycreturn
2楼-- · 2019-08-23 15:34
本帖最后由 lycreturn 于 2017-3-25 22:50 编辑
arao和xiaomi 发表于 2017-3-25 22:32
你好,我按照你的建议把它改成这样,然后老出问题,不知道哪里错了

float EXTI15_10_IRQHandler(vo ...

仔细看了下你的代码,我是不建议用这种方式(中断里面等待引脚被拉低)测量高电平的,同样用了定时器还占用一路中断,中断里还死等;当然不是说这种方式不行,只是你可以用更好的方法:那就是输出捕获,捕获高电平就可以了,例程也有现成的;
好了,说回来,你的这种方式,实际没测试过,不知是不是中断服务函数那儿出问题了,中断服务函数改成void试试吧,我自己肯定是不会 使用这种测量方式的
lycreturn
3楼-- · 2019-08-23 15:50
 精彩回答 2  元偷偷看……
arao和xiaomi
4楼-- · 2019-08-23 16:31
lycreturn 发表于 2017-3-25 23:14
知道你哪里出问题了,你没给我看TIM2的配置,问题就出在TIM2,你配置的定时器计数频率太低了,把它设置成1 ...

我的定时器2设置的是
TIM_TimeBaseStructure.TIM_Period = 5000;  
        TIM_TimeBaseStructure.TIM_Prescaler =(7200-1);  
arao和xiaomi
5楼-- · 2019-08-23 21:34
lycreturn 发表于 2017-3-25 23:14
知道你哪里出问题了,你没给我看TIM2的配置,问题就出在TIM2,你配置的定时器计数频率太低了,把它设置成1 ...

你好,我把显示的部分从中断中取出来放到主函数中去了,果然稳定效果要好一些,但是偶尔的还是会出现浮动,感觉确实可以试一下用输入捕获的方式来做,谢谢你
arao和xiaomi
6楼-- · 2019-08-24 02:54
lycreturn 发表于 2017-3-25 23:14
知道你哪里出问题了,你没给我看TIM2的配置,问题就出在TIM2,你配置的定时器计数频率太低了,把它设置成1 ...

忘了说了找到原因了,就是发现电压没接对,本来是要5伏工作,我错结成3.3伏,所以计数器一直计数不对,哎,郁闷死了

一周热门 更多>