STM32捕获模式连续测量脉冲周期/频率,使用类似中断的方式,使用STM32内部的硬件滤波器,脉冲周期量程很大(固定时间脉冲计数的方式,量程有限)。
硬件: STM32F103R8T6 TIM2 CH1通道
程序配置如下:
/*TIM2初始化*/
void MX_TIM2_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; /*1us per tick*/
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 0xffff;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV2;
htim2.Init.RepetitionCounter = 0;
HAL_TIM_Base_Init(&htim2);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; /*上升沿*/
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 7; /*硬件滤波器值*/
HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1);
HAL_TIM_Base_Start_IT(&htim2); /*启动TIM2定时器 */
HAL_TIM_IC_Start_IT (&htim2, TIM_CHANNEL_1); /*开启捕获 */
}
/*配置端口*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(htim_base->Instance==TIM2) /*改用捕获模式测量频率*/
{
/* USER CODE BEGIN TIM2_MspInit 0 */
/* USER CODE END TIM2_MspInit 0 */
/* Peripheral clock enable */
__TIM2_CLK_ENABLE();
/**TIM2 GPIO Configuration
PA0-WKUP ------> TIM2_CH1
*/
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN TIM2_MspInit 1 */
HAL_NVIC_SetPriority(TIM2_IRQn, 1, 0); /*中断优先级*/
HAL_NVIC_EnableIRQ(TIM2_IRQn); /*使能中断*/
/* USER CODE END TIM2_MspInit 1 */
}
}
/*中断处理调用*/
void TIM2_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim2);
}
typedef struct //测量周期的脉宽
{
uint8_t ucFinishFlag;
uint16_t usCtr;
uint16_t usPeriod;
uint32_t usCycle; /*捕捉的周期*/
}STRUCT_CAPTURE;
STRUCT_CAPTURE strCapture1 = { 0, 0, 0 };
/*输入捕获回调*/
/**
* 函数功能: 定时器输入捕获中断回调函数
* 输入参数: htim:定时器句柄
* 返 回 值: 无
* 说 明: 无
*/
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
if(htim == &htim2) /*使用通道1,实际是间隔1个周期测量*/
{
strCapture1 .usCtr = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);
/*计算脉冲的周期*/
strCapture1.usCycle = strCapture1.usPeriod * 0xFFFF + strCapture1 .usCtr; /*直
接把周期计算出来了*/
strCapture1 .ucFinishFlag = 1;
htim->Instance->CNT = 0; /*提前设置好,测量整个周期的时钟,单位
1us*/
strCapture1.usCtr = 0;
strCapture1.usPeriod = 0;
}
}
/*定时器计数溢出处理 可处理周期 0 - 0xffffffff us 的周期*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM2)
{
strCapture1.usPeriod++; /*溢出*/
}
}
strCapture1.usCycle 即所求的脉冲周期,时间除以周期即可得到所求脉冲的频率。