F429超声波测距始终显示0cm

2019-07-20 02:19发布

新手上路,最近再搞超声波测距。我在输入捕获实验的例程中修改的,我用pa0作为接受,pb6作为发送。具体的一些配置如下。前面是定时器相关的,后面的是主函数。
//定时器5通道1输入捕获配置
//arr:自动重装值(TIM2,TIM5是32位的!!)
//psc:时钟预分频数
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{  
    TIM_IC_InitTypeDef TIM5_CH1Config;  

    TIM5_Handler.Instance=TIM5;                          //通用定时器5
    TIM5_Handler.Init.Prescaler=psc;                     //分频系数
    TIM5_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;    //向上计数器
    TIM5_Handler.Init.Period=arr;                        //自动装载值
    TIM5_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频银子
    HAL_TIM_IC_Init(&TIM5_Handler);//初始化输入捕获时基参数

    TIM5_CH1Config.ICPolarity=TIM_ICPOLARITY_RISING;    //上升沿捕获
    TIM5_CH1Config.ICSelection=TIM_ICSELECTION_DIRECTTI;//映射到TI1上
    TIM5_CH1Config.ICPrescaler=TIM_ICPSC_DIV1;          //配置输入分频,不分频
    TIM5_CH1Config.ICFilter=0;                          //配置输入滤波器,不滤波
    HAL_TIM_IC_ConfigChannel(&TIM5_Handler,&TIM5_CH1Config,TIM_CHANNEL_1);//配置TIM5通道1
       
    HAL_TIM_IC_Start_IT(&TIM5_Handler,TIM_CHANNEL_1);   //开启TIM5的捕获通道1,并且开启捕获中断
    __HAL_TIM_ENABLE_IT(&TIM5_Handler,TIM_IT_UPDATE);   //使能更新中断
}


//定时器5底层驱动,时钟使能,引脚配置
//此函数会被HAL_TIM_IC_Init()调用
//htim:定时器5句柄
void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_TIM5_CLK_ENABLE();            //使能TIM5时钟
    __HAL_RCC_GPIOA_CLK_ENABLE();                        //开启GPIOA时钟
       
    GPIO_Initure.Pin=GPIO_PIN_0;            //PA0
    GPIO_Initure.Mode=GPIO_MODE_INPUT;      //浮空输入
    GPIO_Initure.Pull=GPIO_PULLUP;        //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH;     //高速
    GPIO_Initure.Alternate=GPIO_AF2_TIM5;   //PA0复用为TIM5通道1
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);

    HAL_NVIC_SetPriority(TIM5_IRQn,2,0);    //设置中断优先级,抢占优先级2,子优先级0
    HAL_NVIC_EnableIRQ(TIM5_IRQn);          //开启ITM5中断通道  
}
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
u8  TIM5CH1_CAPTURE_STA=0;        //输入捕获状态                                                   
u32        TIM5CH1_CAPTURE_VAL;        //输入捕获值(TIM2/TIM5是32位)


//定时器5中断服务函数
void TIM5_IRQHandler(void)
{
        HAL_TIM_IRQHandler(&TIM5_Handler);//定时器共用处理函数
}


//定时器更新中断(计数溢出)中断处理回调函数, 该函数在HAL_TIM_IRQHandler中会被调用
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//更新中断(溢出)发生时执行
{
       
        if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
        {
                        if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
                        {
                                if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                {
                                        TIM5CH1_CAPTURE_STA|=0X80;                //标记成功捕获了一次
                                        TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;
                                }else TIM5CH1_CAPTURE_STA++;
                        }         
        }               
}


//定时器输入捕获中断处理回调函数,该函数在HAL_TIM_IRQHandler中会被调用
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行
{
        if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
        {
                if(TIM5CH1_CAPTURE_STA&0X40)                //捕获到一个下降沿                
                        {                                 
                                TIM5CH1_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
                TIM5CH1_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIM5_Handler,TIM_CHANNEL_1);//获取当前的捕获值.
                TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //一定要先清除原来的设置!!
                TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//配置TIM5通道1上升沿捕获
                        }else                                                                  //还未开始,第一次捕获上升沿
                        {
                                TIM5CH1_CAPTURE_STA=0;                        //清空
                                TIM5CH1_CAPTURE_VAL=0;
                                TIM5CH1_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                                __HAL_TIM_DISABLE(&TIM5_Handler);        //关闭定时器5
                                __HAL_TIM_SET_COUNTER(&TIM5_Handler,0);
                                TIM_RESET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1);   //一定要先清除原来的设置!!
                                TIM_SET_CAPTUREPOLARITY(&TIM5_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//定时器5通道1设置为下降沿捕获
                                __HAL_TIM_ENABLE(&TIM5_Handler);//使能定时器5
                        }                    
        }               
       
}


#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "lcd.h"
#include "sdram.h"
#include "pcf8574.h"
#include "timer.h"
/************************************************
ALIENTEK 阿波罗STM32F429开发板实验25
IO扩展实验-HAL库函数版
技术支持:www.openedv.com
淘宝店铺:http://eboard.taobao.com  
关注微信公众平台微信号:"正点原子",免费获取STM32资料。
广州市星翼电子科技有限公司  
作者:正点原子 @ALIENTEK
************************************************/

extern u8  TIM5CH1_CAPTURE_STA;                //输入捕获状态                                                   
extern u32        TIM5CH1_CAPTURE_VAL;        //输入捕获值

GPIO_InitTypeDef GPIO_InitStructure;


int main(void)
{
//    u8 key;
//        u16 i=0;
//        u8 beepsta=1;
         __HAL_RCC_GPIOB_CLK_ENABLE();  //使能PB时钟
          GPIO_InitStructure.Mode=GPIO_MODE_OUTPUT_PP;//推挽输出
          GPIO_InitStructure.Pin= GPIO_PIN_6;
          GPIO_InitStructure.Pull=GPIO_PULLUP;//上拉
          GPIO_InitStructure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;//高速
          HAL_GPIO_Init(GPIOB,&GPIO_InitStructure);
       
        long long  time=0;  
        long long   Distance;
        int  a;
       
    HAL_Init();                     //初始化HAL库   
    Stm32_Clock_Init(360,25,2,8);   //设置时钟,180Mhz
    delay_init(180);                //初始化延时函数
    uart_init(115200);              //初始化USART
    LED_Init();                     //初始化LED
    KEY_Init();                     //初始化按键
    SDRAM_Init();                   //初始化SDRAM
    LCD_Init();                     //初始化LCD
    TIM5_CH1_Cap_Init(0XFFFFFFFF,90-1); //以1MHZ的频率计数
        POINT_COLOR=RED;
        LCD_ShowString(30,40,210,24,24,"The distance:");       
        LCD_ShowString(250,40,210,24,24,"cm");       
       
        while (1)
        {
         HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
        delay_us(20);
        HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET);
          if(TIM5CH1_CAPTURE_STA&0X80)        //成功捕获到了一次高电平
                {
                        time=TIM5CH1_CAPTURE_STA&0X3F;
                        time*=0XFFFFFFFF;                             //溢出时间总和
                        time+=TIM5CH1_CAPTURE_VAL;      //得到总的高电平时间
                        Distance=time*340/20000;
                        TIM5CH1_CAPTURE_STA=0;          //开启下一次捕获
                }
                 a=Distance;
                LCD_ShowNum(200,40,a,4,24);
        }


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
天堂离我最近
1楼-- · 2019-07-20 06:41
 精彩回答 2  元偷偷看……
正点原子
2楼-- · 2019-07-20 07:09
仿真找问题
求大神
3楼-- · 2019-07-20 10:13
怎么解决的呀,我最近也在搞这个
weiwoduxian1987
4楼-- · 2019-07-20 12:15
 精彩回答 2  元偷偷看……
胖胖胖胖啊
5楼-- · 2019-07-20 13:22
试试把显示距离写在if()里面

一周热门 更多>