• 已解决 73482 个问题
  • 已帮助 5993 位优秀工程师

移植的一个超声波测距程序有问题

Gwvfbukn 2018-10-06 浏览量:964
大概50ms读取一次距离,但输出的值一直在1000上下浮动,明显是有问题的,代码如下:

#include "distance.h"
#include "delay.h"
#include "stdio.h"

/**************************************************************************
函数功能:定时器4通道1输入捕获初始化
入口参数:入口参数:arr:自动重装值  psc:时钟预分频数 
返回  值:无

pb0 控制端口

检测  pb6    timer4 ch1  
**************************************************************************/
u8 TIM4CH1_CAPTURE_STA = 0;        //通道1输入捕获标志,高两位做捕获标志,低6位做溢出标志                

u16 TIM4CH1_CAPTURE_VAL;                //记录捕获值

/**************************************************************************
函数功能:定时器4通道1输入捕获初始化
入口参数:arr:自动重装值  psc:时钟预分频数 
返回  值:无
**************************************************************************/
void TIM4_Cap_Init(u16 arru16 psc)        
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimebaseInitTypeDef  TIM_TimebaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
  TIM_ICInitTypeDef  TIM_ICInitStructure;
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 ENABLE);        //使能TIM4时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ENABLE);  //使能GPIOB时钟
        
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6; 
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PB0 输入  GPIO_Mode_IPD                GPIO_Mode_IN_FLOATING
        GPIO_Init(GPIOB &GPIO_InitStructure);
        
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;     
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     //PB0输出 
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     
        GPIO_Init(GPIOB &GPIO_InitStructure);
        
        TIM_TimebaseStructure.TIM_Period = arr;                                                                 //设定计数器自动重装值                 65535                                        400cm时高电平约为23.529ms
        TIM_TimebaseStructure.TIM_Prescaler =psc;                                                         //预分频器   72 - 1  时钟1Mhz                                                
        TIM_TimebaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimebaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimebaseInit(TIM4 &TIM_TimebaseStructure); //根据TIM_TimebaseInitStruct中指定的参数初始化TIMx的时间基数单位

        TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 
        TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
        TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
        TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频不分频 
        TIM_ICInitStructure.TIM_ICFilter = 0x00;//配置输入滤波器 不滤波
        TIM_ICInit(TIM4 &TIM_ICInitStructure);
        
        NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器         
        TIM_ITConfig(TIM4TIM_IT_Update|TIM_IT_CC1ENABLE);//允许更新中断 允许CC1IE捕获中断        
        TIM_Cmd(TIM4ENABLE );         //使能定时器4                
}

/**************************************************************************
函数功能:超声波接收回波函数
入口参数:无
返回  值:无
**************************************************************************/

void Read_Distane(void)
{   
         PBout(0)=1;
         delay_us(15);  
         PBout(0)=0;        
                if(TIM4CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平
                {
                        Distance=TIM4CH1_CAPTURE_STA&0X3F;
                        Distance*=65536;                                               //溢出时间总和
                        Distance+=TIM4CH1_CAPTURE_VAL;         //得到总的高电平时间
                        Distance=Distance*170/1000;      //单位转换为mm
                        TIM4CH1_CAPTURE_STA=0;                             //开启下一次捕获
                }                                
}
/**************************************************************************
函数功能:超声波回波脉宽读取中断
入口参数:无
返回  值:无
**************************************************************************/
void TIM4_IRQHandler(void)
{                                                                   
        u16 tsr;
        tsr=TIM4->SR;                //状态寄存器
        if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获        
                                {
                                             if(tsr&0X01)//溢出        即更新
                                                                {            
                                                                                if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
                                                                                {
                                                                                        if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                                                                        {
                                                                                                TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
                                                                                                TIM4CH1_CAPTURE_VAL=0XFFFF;
                                                                                        }
                                                                                        else 
                                                                                                TIM4CH1_CAPTURE_STA++;
                                                                                }         
                                                                }
                                                  if(tsr&0x02)//捕获1发生捕获事件        0000 0010
                                            {        
                                                                                if(TIM4CH1_CAPTURE_STA&0X40)                //捕获到一个下降沿                 0100 0000
                                                                                {                                  
                                                                                        TIM4CH1_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽                1100 0000
                                                                                        TIM4CH1_CAPTURE_VAL=TIM4->CCR1;        //获取当前的捕获值.
                                                                                        TIM4->CCER&=~(1<<1);                        //CC1P=0 设置为上升沿捕获
                                                                                }
                                                                                else                                                                  //还未开始第一次捕获上升沿                TIM4CH1_CAPTURE_STA初始为0000 0000
                                                                                {
                                                                                        TIM4CH1_CAPTURE_STA=0;                        //清空
                                                                                        TIM4CH1_CAPTURE_VAL=0;                        
                                                                                        TIM4CH1_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                                                                                        TIM4->CNT=0;                                             //计数器清空
                                                                                        TIM4->CCER|=1<<1;                                 //设置为下降沿捕获
                                                                                }                    
                                                    }                                                                                    
                   }
                         TIM4->SR=0;//清除中断标志位              
}

哪里有问题呢??。。。。。。
0 0 收起

我来回答

上传资料:
选择文件 文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
  • 这个模块我原来也遇到过有问题,主要是电压的问题,首先不能用3.3v,其次你用5v,也得保证你这个5v是真的,意思就是有的板子上虽然标的5v,其实只有3v,测一下。
    • 发布于 2018-10-11
    • 举报
    • 评论 0
    • 1
    • 0

其他答案 数量:9
  • 应该是测量接收的时间超时了 会显示一个很大的数
    • 发布于2018-10-10
    • 举报
    • 评论 0
    • 0
    • 0

  • 太粗心了,是电源接错了,3.3v这个模块不能用,不过奇怪的是定时器依旧可以捕获高电平,并且数值达到明显是错误的。
    • 发布于2018-10-10
    • 举报
    • 评论 0
    • 0
    • 0

  • 这种应该测一下电平的电压,看看是否匹配
    • 发布于2018-10-12
    • 举报
    • 评论 0
    • 0
    • 0

  • 这种要检查你的模块供电是不是正常还有对应的电压是不是正常
    • 发布于2018-10-27
    • 举报
    • 评论 0
    • 0
    • 0

  • 你直接用例程就完了,如果例程不行肯定硬件问题,先排除硬件
    • 发布于2018-10-29
    • 举报
    • 评论 0
    • 0
    • 0

  • 注意看模块的说明,5V模块使用3.3V时工作会异常,所以首先要确保供电电压正确。
    • 发布于2018-10-29
    • 举报
    • 评论 0
    • 0
    • 0

  • 你的模块的电平是不是程序的电平匹配,不然不能通信的
    • 发布于2018-10-30
    • 举报
    • 评论 0
    • 0
    • 0

  • 既然数据不变那就说明程序肯定有问题,可以参考一下stm32使用定时器输入捕获采集hcsr04的程序,网上非常多。
    • 发布于2018-10-31
    • 举报
    • 评论 0
    • 0
    • 0

相关问题

问题达人换一批

移植的一个超声波测距程序有问题