bitm.c
#include "./BSP/TIMER/btim.h"
/* 硬件配置 */
#define TRIG_PORT GPIOB
#define TRIG_PIN GPIO_PIN_5
#define ECHO_PORT GPIOB
#define ECHO_PIN GPIO_PIN_6
/* 全局变量 */
uint32_t g_echo_rising_time = 0; // 上升沿时间戳
uint32_t g_echo_falling_time = 0; // 下降沿时间戳
uint8_t g_measurement_flag = 0; // 测量状态标志
TIM_HandleTypeDef g_timx_handle; // 定时器句柄
/* 定时器时钟配置(示例使用TIM3,72MHz主频) */
void btim_timx_int_init(void)
{
__HAL_RCC_TIM3_CLK_ENABLE(); // 使能TIM3时钟
g_timx_handle.Instance = TIM3;
g_timx_handle.Init.Prescaler = 71; // 72分频,1MHz计数频率(1us计数)
g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
g_timx_handle.Init.Period = 0xFFFF; // 最大计数值
g_timx_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&g_timx_handle);
// 初始化GPIO
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* PB端口时钟使能 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/* TRIG引脚配置 */
GPIO_InitStruct.Pin = TRIG_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(TRIG_PORT, &GPIO_InitStruct);
/* ECHO引脚配置 */
GPIO_InitStruct.Pin = ECHO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; // 双边沿触发
GPIO_InitStruct.Pull = GPIO_PULLUP; // 上拉电阻
HAL_GPIO_Init(ECHO_PORT, &GPIO_InitStruct);
/* 配置外部中断 */
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2, 0); // PB5/PB6共用EXTI9_5中断
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}
/**
* @brief 触发超声波测距
*/
void Trigger_Ultrasound(void)
{
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_SET);
delay_us(12); // 精确12us高电平触发信号
HAL_GPIO_WritePin(TRIG_PORT, TRIG_PIN, GPIO_PIN_RESET);
}
/**
* @brief 外部中断服务函数
*/
void EXTI9_5_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(ECHO_PIN); // 处理PB6引脚中断
}
/**
* @brief 外部中断回调函数
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == ECHO_PIN)
{
if(HAL_GPIO_ReadPin(ECHO_PORT, ECHO_PIN))
{
/* 上升沿:开始计时 */
g_echo_rising_time = __HAL_TIM_GET_COUNTER(&g_timx_handle);
HAL_TIM_Base_Start(&g_timx_handle); // 启动定时器
g_measurement_flag = 1; // 标记测量开始
}
else
{
/* 下降沿:停止计时 */
g_echo_falling_time = __HAL_TIM_GET_COUNTER(&g_timx_handle);
HAL_TIM_Base_Stop(&g_timx_handle); // 停止定时器
g_measurement_flag = 2; // 标记测量完成
}
}
}
/**
* @brief 获取测量结果(单位:厘米)
*/
float get_distance(void)
{
uint32_t timeout = 0;
float distance = 0;
/* 发送触发信号 */
Trigger_Ultrasound();
/* 等待测量开始 */
timeout = HAL_GetTick();
while(g_measurement_flag < 1)
{
if(HAL_GetTick() - timeout > 100) return -1; // 100ms超时
}
/* 等待测量完成 */
timeout = HAL_GetTick();
while(g_measurement_flag != 2)
{
if(HAL_GetTick() - timeout > 60) // 最大测量时间60ms(对应10米)
{
HAL_TIM_Base_Stop(&g_timx_handle);
g_measurement_flag = 0;
return -2; // 信号丢失
}
}
/* 计算时间差(考虑定时器溢出)*/
uint32_t time_diff = (g_echo_falling_time >= g_echo_rising_time) ?
(g_echo_falling_time - g_echo_rising_time) :
(0xFFFF - g_echo_rising_time + g_echo_falling_time);
/* 计算距离:time(us) * 340m/s / 2 = (time * 0.034)/2 cm */
distance = time_diff * 0.017f; // 优化后的计算公式
/* 重置测量标志 */
g_measurement_flag = 0;
/* 有效距离过滤(2cm-500cm)*/
return (distance > 2 && distance < 500) ? distance : -3;
}
bitm.h
#ifndef __BTIM_H
#define __BTIM_H
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
/******************************************************************************************/
/* 基本定时器 定义 */
/* TIMX 中断定义
* 默认是针对TIM6/TIM7
* 注意: 通过修改这4个宏定义,可以支持TIM1~TIM8任意一个定时器.
*/
#define BTIM_TIMX_INT TIM6
#define BTIM_TIMX_INT_IRQn TIM6_DAC_IRQn
#define BTIM_TIMX_INT_IRQHandler TIM6_DAC_IRQHandler
#define BTIM_TIMX_INT_CLK_ENABLE() do{ __HAL_RCC_TIM6_CLK_ENABLE(); }while(0) /* TIM6 时钟使能 */
/******************************************************************************************/
void btim_timx_int_init(void);
float get_distance(void);
#endif
关注我
GitHub
:https://github.com/PastKing
Gitee
:https://gitee.com/past-dust
公众号:
© 版权声明
THE END
暂无评论内容