stm32f103输入捕获中断hal库
时间: 2025-01-04 13:36:06 浏览: 8
### STM32F103 HAL库 输入捕获 中断 示例代码 使用教程
#### 初始化定时器并配置输入捕获功能
为了实现STM32F103的输入捕获中断,首先需要初始化定时器,并设置其工作于输入捕获模式。这可以通过CubeMX工具自动生成大部分初始化代码来简化开发过程。
```c
// 定义全局变量用于存储捕获到的时间戳
uint32_t CaptureValue;
TIM_HandleTypeDef htim2;
void MX_TIM2_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_IC_InitTypeDef sConfigIC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 71; // 设置预分频值为72-1=71, 即APB1频率除以72
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 65535; // 自动重装载值设为最大
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.RepetitionCounter = 0;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; // 上升沿触发
sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
sConfigIC.ICFilter = 0;
if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
```
上述代码完成了对`TIM2`定时器的基础配置以及通道1作为输入捕获的功能设定[^1]。
#### 配置NVIC使能定时器中断请求
为了让处理器响应来自定时器的事件,还需要开启相应的中断线:
```c
__HAL_RCC_GPIOA_CLK_ENABLE(); // 启用GPIO端口时钟
__HAL_AFIO_REMAP_SWJ_NOJTAG(); // 如果使用SWD调试接口,则禁用JTAG减少冲突可能性
/* GPIO Initialization */
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 使能TIM2全球中断和DMA请求
__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_CC1);
// NVIC Configuration for TIM2 Global Interrupt
HAL_NVIC_SetPriority(TIM2_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(TIM2_IRQn);
```
这段代码设置了外设引脚复用至定时器功能,并启用了特定的中断源以便后续处理捕获的数据[^2]。
#### 编写中断服务例程ISR
当发生指定类型的事件(如上升沿到达),就会触发对应的中断向量表项执行下面定义的服务程序:
```c
extern uint32_t CaptureValue;
void TIM2_IRQHandler(void)
{
/* USER CODE BEGIN TIM2_IRQn 0 */
/* USER CODE END TIM2_IRQn 0 */
HAL_TIM_IRQHandler(&htim2);
/* USER CODE BEGIN TIM2_IRQn 1 */
if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_CC1) && __HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_CC1))
{
CaptureValue = HAL_TIM_ReadCapturedValue(&htim2, TIM_CHANNEL_1);
// 清除标志位防止重复进入此分支逻辑
__HAL_TIM_CLEAR_IT(&htim2, TIM_IT_CC1);
// 用户可以在此处添加额外的应用层业务逻辑...
}
/* USER CODE END TIM2_IRQn 1 */
}
// 在主循环或其他地方调用该函数获取最新一次捕获的结果
uint32_t GetCaptureResult()
{
return CaptureValue;
}
```
这里实现了简单的中断回调机制,在每次检测到有效边沿变化后更新全局变量中的计数值供应用程序查询[^4]。
阅读全文