1.硬件
2.软件
定时器HAL驱动层文件添加 ic驱动文件添加 GPIO常用函数 定时器输入捕获实验配置步骤 main.c程序
# include "sys.h"
# include "delay.h"
# include "led.h"
# include "uart1.h"
# include "ic.h" int main ( void )
{ HAL_Init ( ) ; stm32_clock_init ( RCC_PLL_MUL9) ; led_init ( ) ; uart1_init ( 115200 ) ; printf ( "hello world!\r\n" ) ; ic_init ( 65536 - 1 , 72 - 1 ) ; while ( 1 ) { pressed_time_get ( ) ; delay_ms ( 10 ) ;
}
}
**ic_init(65536 - 1, 72 - 1);//计时1us
**语句定时参考
# include "ic.h"
# include "stdio.h"
# include "string.h" struct
{ uint8_t succeed_flag; uint8_t rising_flag; uint8_t falling_flag; uint16_t timout_cnt;
} capture_status = { 0 } ; uint16_t last_cnt = 0 ; TIM_HandleTypeDef ic_handle = { 0 } ;
void ic_init ( uint16_t arr, uint16_t psc)
{ TIM_IC_InitTypeDef ic_config = { 0 } ; ic_handle. Instance = TIM2; ic_handle. Init. Prescaler = psc; ic_handle. Init. Period = arr; ic_handle. Init. CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_IC_Init ( & ic_handle) ; ic_config. ICPolarity = TIM_ICPOLARITY_FALLING; ic_config. ICSelection = TIM_ICSELECTION_DIRECTTI; ic_config. ICPrescaler = TIM_ICPSC_DIV1; ic_config. ICFilter = 0 ; HAL_TIM_IC_ConfigChannel ( & ic_handle, & ic_config, TIM_CHANNEL_2) ; __HAL_TIM_ENABLE_IT ( & ic_handle, TIM_IT_UPDATE) ; HAL_TIM_IC_Start_IT ( & ic_handle, TIM_CHANNEL_2) ;
} void HAL_TIM_IC_MspInit ( TIM_HandleTypeDef * htim)
{ if ( htim-> Instance == TIM2) { GPIO_InitTypeDef gpio_initstruct; __HAL_RCC_GPIOA_CLK_ENABLE ( ) ; __HAL_RCC_TIM2_CLK_ENABLE ( ) ; gpio_initstruct. Pin = GPIO_PIN_0; gpio_initstruct. Mode = GPIO_MODE_AF_PP; gpio_initstruct. Pull = GPIO_PULLUP; gpio_initstruct. Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init ( GPIOB, & gpio_initstruct) ; HAL_NVIC_SetPriority ( TIM2_IRQn, 2 , 2 ) ; HAL_NVIC_EnableIRQ ( TIM2_IRQn) ; }
} void TIM2_IRQHandler ( void )
{ HAL_TIM_IRQHandler ( & ic_handle) ;
} void HAL_TIM_IC_CaptureCallback ( TIM_HandleTypeDef * htim)
{ if ( htim-> Instance == TIM2) { if ( capture_status. succeed_flag == 0 ) { if ( capture_status. falling_flag == 1 ) { printf ( "捕获到上升沿\r\n" ) ; capture_status. succeed_flag = 1 ; last_cnt = HAL_TIM_ReadCapturedValue ( & ic_handle, TIM_CHANNEL_2) ; TIM_RESET_CAPTUREPOLARITY ( & ic_handle, TIM_CHANNEL_2) ; TIM_SET_CAPTUREPOLARITY ( & ic_handle, TIM_CHANNEL_2, TIM_ICPOLARITY_FALLING) ; } else { printf ( "捕获到下降沿\r\n" ) ; memset ( & capture_status, 0 , sizeof ( capture_status) ) ; capture_status. falling_flag = 1 ; __HAL_TIM_DISABLE ( & ic_handle) ; __HAL_TIM_SET_COUNTER ( & ic_handle, 0 ) ; TIM_RESET_CAPTUREPOLARITY ( & ic_handle, TIM_CHANNEL_2) ; TIM_SET_CAPTUREPOLARITY ( & ic_handle, TIM_CHANNEL_2, TIM_ICPOLARITY_RISING) ; __HAL_TIM_ENABLE ( & ic_handle) ; } } }
} void HAL_TIM_PeriodElapsedCallback ( TIM_HandleTypeDef * htim)
{ if ( htim-> Instance == TIM2) { if ( capture_status. succeed_flag == 0 ) { if ( capture_status. falling_flag == 1 ) capture_status. timout_cnt++ ; } }
} void pressed_time_get ( void )
{ if ( capture_status. succeed_flag == 1 ) { printf ( "按下时间:%d us\r\n" , capture_status. timout_cnt * 65536 + last_cnt) ; memset ( & capture_status, 0 , sizeof ( capture_status) ) ; }
}
# ifndef __IC_H__
# define __IC_H__ # include "sys.h"
void ic_init ( uint16_t arr, uint16_t psc) ;
void pressed_time_get ( void ) ; # endif
3.实物效果
硬件模块接线 KEY一端—>PA0 KEY另一端—>GND ST-Link下载方式 打开串口软件,当按键按下时,串口打印输出“捕获到下降沿”;当按键松开时,串口打印输出“捕获到上升沿”;并打印“按下时间:”