基于STM32F103和Cube的输入捕获例程
- 2019 年 10 月 30 日
- 筆記
1.开发环境
(1)Cube5.24
(2)Keil5
(3)STM32F103
2.Cube配置
Cube配置很简单,只要打开TIM4通道1的引脚,设置为输入捕获模式,在配置是高或低电平沿触发
TIM的定时器时钟可根据自己的需要来配置,触发模式为上升沿触发
最后把中断给打开
Cube生成的代码如下:
void MX_TIM4_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; htim4.Instance = TIM4; htim4.Init.Prescaler = 2; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 0xffff; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_IC_Init(&htim4) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &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(&htim4, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } } void HAL_TIM_IC_MspInit(TIM_HandleTypeDef* tim_icHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(tim_icHandle->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspInit 0 */ /* USER CODE END TIM4_MspInit 0 */ /* TIM4 clock enable */ __HAL_RCC_TIM4_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /**TIM4 GPIO Configuration PD12 ------> TIM4_CH1 */ GPIO_InitStruct.Pin = GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); __HAL_AFIO_REMAP_TIM4_ENABLE(); /* TIM4 interrupt Init */ HAL_NVIC_SetPriority(TIM4_IRQn, 0, 0); HAL_NVIC_EnableIRQ(TIM4_IRQn); /* USER CODE BEGIN TIM4_MspInit 1 */ /* USER CODE END TIM4_MspInit 1 */ } } void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef* tim_icHandle) { if(tim_icHandle->Instance==TIM4) { /* USER CODE BEGIN TIM4_MspDeInit 0 */ /* USER CODE END TIM4_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_TIM4_CLK_DISABLE(); /**TIM4 GPIO Configuration PD12 ------> TIM4_CH1 */ HAL_GPIO_DeInit(GPIOD, GPIO_PIN_12); /* TIM4 interrupt Deinit */ HAL_NVIC_DisableIRQ(TIM4_IRQn); /* USER CODE BEGIN TIM4_MspDeInit 1 */ /* USER CODE END TIM4_MspDeInit 1 */ } }
3.主程序
在写自己的代码之前要说一下HAL库的stm32f1xx_hal_tim.c里有一个BUG,他们这个宏定义——#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__)要改一下
原本如下:
#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP))) : ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) : ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P)) : ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P)))
改了如下:
#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) : ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) : ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P)) : ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P)))
两者唯一的区别就是原本的第一行后面多了一个括号!!!
输入捕获的功能就是当输入捕获引脚检测到上升沿或下降沿时进入中断服务函数,处理事务,该中断服务函数为void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
主函数:
while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(capture_Cnt==0) { __HAL_TIM_SET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING); //设置为上升沿捕获 HAL_TIM_IC_Start_IT(&htim4, TIM_CHANNEL_1); capture_Cnt++; } }
中断函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { uint32_t a; if(TIM4 == htim->Instance) { if(capture_Cnt==1) { //capture_Buf[0] =HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1); //获取当前的捕获值 HAL_TIM_IC_Stop_IT(&htim4,TIM_CHANNEL_1); //停止捕获 capture_Cnt=0; Number++; printf("n%d",Number); // printf("n捕捉上升沿:%d",capture_Buf[0] ); } } }
我这里只是计算一下进入了多少次中断,你们可以根据自己的需求来写处理的程序。