千家信息网

STM32F429如何使用定时器多路HC-SR04超声波输入捕获

发表于:2024-11-26 作者:千家信息网编辑
千家信息网最后更新 2024年11月26日,这篇文章主要介绍了STM32F429如何使用定时器多路HC-SR04超声波输入捕获,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。介绍S
千家信息网最后更新 2024年11月26日STM32F429如何使用定时器多路HC-SR04超声波输入捕获

这篇文章主要介绍了STM32F429如何使用定时器多路HC-SR04超声波输入捕获,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

介绍

STMF429IGT开发板,通过定时器2接入2路超声波模块。使用Timer2的输入捕获功能来实现。超声波模块使用HC-SR04模组。

关于hc-sr04的工作原理这里不再介绍,请自行百度。废话不多说,直接上代码:

Timer2 GPIO配置代码:

TIM_HandleTypeDef TIM2_Handler;  //定时器2句柄//timer2 gpio配置void Timer2_Cap_Init(u32 arr,u16 psc){          //GPIO³õʼ»¯        GPIO_InitTypeDef GPIO_InitStruct = {0};        __HAL_RCC_TIM2_CLK_ENABLE();          __HAL_RCC_GPIOA_CLK_ENABLE();        __HAL_RCC_GPIOB_CLK_ENABLE();        /**TIM2 GPIO Configuration            PA5     ------> TIM2_CH1        PB3     ------> TIM2_CH2        */        GPIO_InitStruct.Pin = GPIO_PIN_5;        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;        GPIO_InitStruct.Pull = GPIO_PULLDOWN;        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);                GPIO_InitStruct.Pin = GPIO_PIN_3;        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;        GPIO_InitStruct.Pull = GPIO_PULLDOWN;        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;        GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);        /* TIM2 interrupt Init */        HAL_NVIC_SetPriority(TIM2_IRQn, 2, 0);        HAL_NVIC_EnableIRQ(TIM2_IRQn);                //TIM_ClockConfigTypeDef sClockSourceConfig = {0};        TIM_MasterConfigTypeDef sMasterConfig = {0};        TIM_IC_InitTypeDef sConfigIC = {0};        TIM2_Handler.Instance = TIM2;        TIM2_Handler.Init.Prescaler = psc;        TIM2_Handler.Init.CounterMode = TIM_COUNTERMODE_UP;        TIM2_Handler.Init.Period = arr;        TIM2_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;                //下面几句不能开启,开启后输入捕获异常        //HAL_TIM_Base_Init(&TIM2_Handler);        //sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;        //HAL_TIM_ConfigClockSource(&TIM2_Handler, &sClockSourceConfig);        if (HAL_TIM_IC_Init(&TIM2_Handler) != HAL_OK)        {        //Error_Handler();        }        sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;        sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;        if (HAL_TIMEx_MasterConfigSynchronization(&TIM2_Handler, &sMasterConfig) != HAL_OK)        {        //Error_Handler();        }        sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;  //配置为上升沿检测        sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;        sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;        sConfigIC.ICFilter = 0;       //配置ch2        if (HAL_TIM_IC_ConfigChannel(&TIM2_Handler, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)        {        //Error_Handler();        }    //配置ch3        if (HAL_TIM_IC_ConfigChannel(&TIM2_Handler, &sConfigIC, TIM_CHANNEL_2) != HAL_OK)        {        //Error_Handler();        }                HAL_TIM_IC_Start_IT(&TIM2_Handler,TIM_CHANNEL_2);   //开启ch3输入捕获    HAL_TIM_IC_Start_IT(&TIM2_Handler,TIM_CHANNEL_1);   //开启ch2输入捕获        __HAL_TIM_ENABLE_IT(&TIM2_Handler,TIM_IT_UPDATE);   //使能更新中断}

输入捕获数值的获取:

//TIM2CHx_CAPTURE_STA记录捕获状态//[7]:0,没有捕获 1,成功捕获//[6]:0,还没捕获到低电平 1.捕获到低电平//[5:0]:捕获低电平溢出次数u8  TIM2CH1_CAPTURE_STA=0;    //输入捕获状态                                                    u32     TIM2CH1_CAPTURE_VAL;    //输入捕获值(TIM2/TIM5是32位)u32 TIM2CH1_count = 0;u8  TIM2CH2_CAPTURE_STA=0;    //输入捕获状态                                                    u32     TIM2CH2_CAPTURE_VAL;    //输入捕获值(TIM2/TIM5是32位)u32 TIM2CH2_count = 0;//timer2中断服务程序void TIM2_IRQHandler(void){        HAL_TIM_IRQHandler(&TIM2_Handler);} //定时器更新中断处理回调函数,该函数在HAL_TIM_IRQHandler()中被调用void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//更新中断发生时执行{        if(htim->Instance ==TIM2)        {                if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)                {                        if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获                        {                                if(TIM2CH1_CAPTURE_STA&0X40)//捕获到一次高电平                                {                                        if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长,导致溢出了                                        {                                                TIM2CH1_CAPTURE_STA|=0X80;              //标记完成一次捕获                                                TIM2CH1_CAPTURE_VAL=0XFFFFFFFF;                                        }                                        else                                         {                                                TIM2CH1_CAPTURE_STA++;                                        }                                }                                }                }                else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)                {                        if((TIM2CH2_CAPTURE_STA&0X80)==0)                        {                                if(TIM2CH2_CAPTURE_STA&0X40)                                {                                        if((TIM2CH2_CAPTURE_STA&0X3F)==0X3F)                                        {                                                TIM2CH2_CAPTURE_STA|=0X80;                                                              TIM2CH2_CAPTURE_VAL=0XFFFFFFFF;                                        }                                        else                                         {                                                TIM2CH2_CAPTURE_STA++;                                        }                                }                                }                }        }}//定时器输入捕获回调函数,会在HAL_TIM_IRQHandler()中被调用void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//捕获中断发生时执行{        if(htim->Instance ==TIM2)        {                if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)                {                        //printf("TIM_CHANNEL_1\n");                        if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获                        {                                if(TIM2CH1_CAPTURE_STA&0X40)                //捕获到一个下降沿                                      {                                                                     TIM2CH1_CAPTURE_STA|=0X80;              //标记成功捕获到一次高电平脉宽                                        TIM2CH1_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_1) - TIM2CH1_count;//获取当前捕获值                                        TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1);   //清除原配置                        //配置上升沿捕获                                                  TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);                                }                                else  //还未开始捕获,第一次捕获到上升沿                                {                                        TIM2CH1_CAPTURE_STA=0;                  //清零                                        TIM2CH1_CAPTURE_VAL=0;                                        TIM2CH1_count = 0;                                        TIM2CH1_CAPTURE_STA|=0X40;              //标记捕获到了上升沿                    //记录第一次捕获值                                         TIM2CH1_count = HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_1);                                        TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1);  //清除原配置                    //设置为下降沿捕获                                        TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);//                                }                        }                }                else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)                {                        //printf("TIM_CHANNEL_2\n");                        if((TIM2CH2_CAPTURE_STA&0X80)==0)                        {                                if(TIM2CH2_CAPTURE_STA&0X40)                                                        {                                                                     TIM2CH2_CAPTURE_STA|=0X80;                                                      TIM2CH2_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_2)- TIM2CH2_count;                                        TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2);                                        TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_RISING);//                                }                                else                                                                                                  {                                        TIM2CH2_CAPTURE_STA=0;                                                          TIM2CH2_CAPTURE_VAL=0;                                        TIM2CH2_count = 0;                                        TIM2CH2_CAPTURE_STA|=0X40;                                                      TIM2CH2_count = HAL_TIM_ReadCapturedValue(&TIM2_Handler,TIM_CHANNEL_2);                                        TIM_RESET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2);                                          TIM_SET_CAPTUREPOLARITY(&TIM2_Handler,TIM_CHANNEL_2,TIM_ICPOLARITY_FALLING);//                                }                        }                }        }}

HC_sr04 trig信号触发,gpio配置,使用PC0来做触发引脚:

//使用PC0触发信号void FFIntell_hcsr04_trig_gpio_init(void){        GPIO_InitTypeDef GPIO_InitStruct = {0};                /* GPIO Ports Clock Enable */        __HAL_RCC_GPIOC_CLK_ENABLE();                /*Configure GPIO pin : PC0 */        GPIO_InitStruct.Pin = GPIO_PIN_0;        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;        GPIO_InitStruct.Pull = GPIO_NOPULL;        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);                /*Configure GPIO pin Output Level */        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_0, GPIO_PIN_RESET);}

调用,在初始化timer2 gpio初始化后,发送trig信号后,直接获取数据即可

//发送trig信号void FFIntell_hcsr04_trig(){        __HAL_TIM_ENABLE(&TIM2_Handler);//使能定时器                PCout(0) = 1;        delay_us(20); //20us延时        PCout(0) = 0;}//获取距离数据int FFIntell_hcsr04_get_data(void){           //ch2获取到了数据        if(TIM2CH1_CAPTURE_STA&0X80)        {                 dist_info.ch2_distance = TIM2CH1_CAPTURE_VAL *0.058; //计算距离                TIM2CH1_CAPTURE_STA=0;                  //清状态        }                if(TIM2CH2_CAPTURE_STA&0X80)        {                dist_info.ch3_distance = TIM2CH2_CAPTURE_VAL*0.058;                TIM2CH2_CAPTURE_STA=0;        }        __HAL_TIM_DISABLE(&TIM2_Handler);        //关闭定时器        __HAL_TIM_SET_COUNTER(&TIM2_Handler, 0); //计数清零                        return 0;}

通过上述配置可以很方便的扩展到4路输入捕获。

感谢你能够认真阅读完这篇文章,希望小编分享的"STM32F429如何使用定时器多路HC-SR04超声波输入捕获"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0