STM32CubeMX

您所在的位置:网站首页 脉冲宽度怎么测 STM32CubeMX

STM32CubeMX

2024-07-12 14:07| 来源: 网络整理| 查看: 265

STM32CubeMX | STM32使用HAL库进行脉冲宽度和周期测量

使用芯片:STM32F103RCT6

思路:定时器设置为1MHZ的计数频率,定时计数器增加一就是增加1us

① 首先设置为上升沿捕获,捕获上升沿记录此刻的时间计数值; ② 然后切换为下降沿捕获,捕获下降沿记录此刻的时间计数值; ③ 最后设置为上升沿捕获,捕获上升沿记录此刻的时间计数值;**

对于16bit定时器,最大可计数0xFFFF,也就是65535us,那么:高电平持续的时间 = 定时器溢出计数 * 0xFFFF + 当前计数值

对于32bit定时器,最大可计数0xFFFFFFFF,也就是4294.967295s,这个时间足够测量脉冲宽度的了,那么:高电平持续的时间 = 当前计数值

高电平持续的时间 = ② - ①

周期 = ③ - ①

定时器配置

设置定时器2的计数频率为1MHz,输入捕获使用通道一,也就是PA0引脚,将PA0引脚设置为下拉模式,目的是为了在空闲时间保持信号稳定:

在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

中断分组设置

在这里插入图片描述

代码配置

tim.c中添加如下代码:

__IO uint32_t TIM2_TIMEOUT_COUNT = 0; ///< 定时器2定时溢出计数 uint32_t TIM2_CAPTURE_BUF[3] = {0, 0, 0}; ///< 分别存储上升沿计数、下降沿计数、下个上升沿计数 __IO uint8_t TIM2_CAPTURE_STA = 0xFF; ///< 状态标记 /** * 设置TIM2输入捕获极性 * @param TIM_ICPolarity: * TIM_INPUTCHANNELPOLARITY_RISING :上升沿捕获 * TIM_INPUTCHANNELPOLARITY_FALLING :下降沿捕获 * TIM_INPUTCHANNELPOLARITY_BOTHEDGE:上升沿和下降沿都捕获 */ inline void TIM2_SetCapturePolarity(uint32_t TIM_ICPolarity) { htim2.Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); htim2.Instance->CCER |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP)); } /// 定时器2时间溢出回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == htim2.Instance) { TIM2_TIMEOUT_COUNT++; // 溢出次数计数 } } ///< 输入捕获回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == htim2.Instance) { switch (TIM2_CAPTURE_STA) { case 1: { printf("准备捕获下降沿...\r\n"); TIM2_CAPTURE_BUF[0] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) + TIM2_TIMEOUT_COUNT * 0xFFFF; TIM2_SetCapturePolarity(TIM_INPUTCHANNELPOLARITY_FALLING); // 设置为下降沿触发 TIM2_CAPTURE_STA++; break; } case 2: { printf("准备捕获下个上升沿...\r\n"); TIM2_CAPTURE_BUF[1] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) + TIM2_TIMEOUT_COUNT * 0xFFFF; TIM2_SetCapturePolarity(TIM_INPUTCHANNELPOLARITY_RISING); // 设置为上升沿触发 TIM2_CAPTURE_STA++; break; } case 3: { printf("捕获结束...\r\n"); printf("# end ----------------------------------------------------\r\n"); TIM2_CAPTURE_BUF[2] = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1) + TIM2_TIMEOUT_COUNT * 0xFFFF; HAL_TIM_IC_Stop_IT(htim, TIM_CHANNEL_1); // 停止捕获 HAL_TIM_Base_Stop_IT(&htim2); // 停止定时器更新中断 TIM2_CAPTURE_STA++; break; } default: break; } } } ///< TIM2轮训状态切换 inline void TIM2_Poll(void) { switch (TIM2_CAPTURE_STA) { case 0: { printf("# start ----------------------------------------------------\r\n"); printf("准备捕获上升沿...\r\n"); TIM2_TIMEOUT_COUNT = 0; __HAL_TIM_SET_COUNTER(&htim2, 0); // 清除定时器2现有计数 memset(TIM2_CAPTURE_BUF, 0, sizeof(TIM2_CAPTURE_BUF)); // 清除捕获计数 TIM2_SetCapturePolarity(TIM_INPUTCHANNELPOLARITY_RISING); // 设置为上升沿触发 HAL_TIM_Base_Start_IT(&htim2); // 启动定时器更新中断 HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); // 启动捕获中断 TIM2_CAPTURE_STA++; break; } case 4: { uint32_t high = TIM2_CAPTURE_BUF[1] - TIM2_CAPTURE_BUF[0]; uint32_t cycle = TIM2_CAPTURE_BUF[2] - TIM2_CAPTURE_BUF[0]; float frq = 1.0 / (((float)cycle) / 1000000.0); TIM2_CAPTURE_STA++; printf("\r\n\r\n"); printf("################################# START #########################################\r\n"); printf("高电平持续时间:%dms\r\n", high / 1000); printf("周期 :%dms\r\n", cycle / 1000); printf("频率 :%fHz\r\n", frq); printf("################################## END ##########################################\r\n\r\n"); break; } default: break; } }

main.c:

int main() { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); DEBUG_UART_Init(); MX_TIM2_Init(); printf("================================ 系统运行! ================================ \r\n"); while(1) { TIM2_Poll(); DEBUG_UART_RecvHandler(); } }

说明:串口一接串口调试助手,勾选发送新行,向单片机发送任意字符以此来启动输入捕获。

ends…



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3