参考:
简介
框图
重复计数器特性
输出指定个数PWM实验
实验原理
配置步骤
相关HAL库函数
关键结构体介绍
编程实战
示例
tim1 ch1 (PA8)输出指定数量pwm信号控制led闪烁
宏定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
#define ATIM_TIMX_NPWM_CHY_GPIO_PORT GPIOA #define ATIM_TIMX_NPWM_CHY_GPIO_PIN GPIO_PIN_8 #define ATIM_TIMX_NPWM_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_NPWM TIM1 #define ATIM_TIMX_NPWM_IRQn TIM1_UP_IRQn #define ATIM_TIMX_NPWM_IRQHandler TIM1_UP_IRQHandler #define ATIM_TIMX_NPWM_CHY TIM_CHANNEL_1 #define ATIM_TIMX_NPWM_CHY_CCRX TIM1->CCR1 #define ATIM_TIMX_NPWM_CHY_CLK_ENABLE() do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)
|
全局变量
1 2 3 4
|
static uint32_t g_npwm_remain = 0;
|
初始化函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc) { GPIO_InitTypeDef gpio_init_struct; TIM_OC_InitTypeDef timx_oc_npwm_chy; ATIM_TIMX_NPWM_CHY_GPIO_CLK_ENABLE(); ATIM_TIMX_NPWM_CHY_CLK_ENABLE();
g_timx_npwm_chy_handle.Instance = ATIM_TIMX_NPWM; g_timx_npwm_chy_handle.Init.Prescaler = psc; g_timx_npwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; g_timx_npwm_chy_handle.Init.Period = arr; g_timx_npwm_chy_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; g_timx_npwm_chy_handle.Init.RepetitionCounter = 0; HAL_TIM_PWM_Init(&g_timx_npwm_chy_handle);
gpio_init_struct.Pin = ATIM_TIMX_NPWM_CHY_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_PP; gpio_init_struct.Pull = GPIO_PULLUP; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(ATIM_TIMX_NPWM_CHY_GPIO_PORT, &gpio_init_struct);
timx_oc_npwm_chy.OCMode = TIM_OCMODE_PWM1; timx_oc_npwm_chy.Pulse = arr / 2; timx_oc_npwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(&g_timx_npwm_chy_handle, &timx_oc_npwm_chy, ATIM_TIMX_NPWM_CHY);
HAL_NVIC_SetPriority(ATIM_TIMX_NPWM_IRQn, 1, 3); HAL_NVIC_EnableIRQ(ATIM_TIMX_NPWM_IRQn);
__HAL_TIM_ENABLE_IT(&g_timx_npwm_chy_handle, TIM_IT_UPDATE); HAL_TIM_PWM_Start(&g_timx_npwm_chy_handle, ATIM_TIMX_NPWM_CHY); }
|
中断函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
void ATIM_TIMX_NPWM_IRQHandler(void) { uint16_t npwm = 0;
if(__HAL_TIM_GET_FLAG(&g_timx_npwm_chy_handle, TIM_FLAG_UPDATE) != RESET) { if (g_npwm_remain >= 256) { g_npwm_remain = g_npwm_remain - 256; npwm = 256; } else if (g_npwm_remain % 256) { npwm = g_npwm_remain % 256; g_npwm_remain = 0; }
if (npwm) { ATIM_TIMX_NPWM->RCR = npwm - 1; HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE); __HAL_TIM_ENABLE(&g_timx_npwm_chy_handle); } else { ATIM_TIMX_NPWM->CR1 &= ~(1 << 0); }
__HAL_TIM_CLEAR_IT(&g_timx_npwm_chy_handle, TIM_IT_UPDATE); } }
|
其他函数
1 2 3 4 5 6 7 8 9 10 11 12 13
|
void atim_timx_npwm_chy_set(uint32_t npwm) { if (npwm == 0) return;
g_npwm_remain = npwm; HAL_TIM_GenerateEvent(&g_timx_npwm_chy_handle, TIM_EVENTSOURCE_UPDATE); __HAL_TIM_ENABLE(&g_timx_npwm_chy_handle); }
|
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| int main(void) { uint8_t key = 0; uint8_t t = 0;
HAL_Init(); sys_stm32_clock_init(RCC_PLL_MUL9); delay_init(72); usart_init(115200); led_init(); key_init(); atim_timx_npwm_chy_init(5000 - 1, 7200 - 1); ATIM_TIMX_NPWM_CHY_CCRX = 2500;
atim_timx_npwm_chy_set(5);
while (1) { key = key_scan(0);
if (key == KEY0_PRES) { atim_timx_npwm_chy_set(5); }
t++; delay_ms(10);
if (t > 50) { t = 0; LED0_TOGGLE(); } } }
|
输出比较模式实验
输出比较模式实验
配置步骤
相关HAL库函数介绍
关键结构体介绍
编程实战
此处用tim1的四个通道实验,实验结果用逻辑分析仪观察
宏定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
#define ATIM_TIMX_COMP_CH1_GPIO_PORT GPIOA #define ATIM_TIMX_COMP_CH1_GPIO_PIN GPIO_PIN_8 #define ATIM_TIMX_COMP_CH1_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_COMP_CH2_GPIO_PORT GPIOA #define ATIM_TIMX_COMP_CH2_GPIO_PIN GPIO_PIN_9 #define ATIM_TIMX_COMP_CH2_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_COMP_CH3_GPIO_PORT GPIOA #define ATIM_TIMX_COMP_CH3_GPIO_PIN GPIO_PIN_10 #define ATIM_TIMX_COMP_CH3_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_COMP_CH4_GPIO_PORT GPIOA #define ATIM_TIMX_COMP_CH4_GPIO_PIN GPIO_PIN_11 #define ATIM_TIMX_COMP_CH4_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_COMP TIM1 #define ATIM_TIMX_COMP_CH1_CCRX ATIM_TIMX_COMP->CCR1 #define ATIM_TIMX_COMP_CH2_CCRX ATIM_TIMX_COMP->CCR2 #define ATIM_TIMX_COMP_CH3_CCRX ATIM_TIMX_COMP->CCR3 #define ATIM_TIMX_COMP_CH4_CCRX ATIM_TIMX_COMP->CCR4 #define ATIM_TIMX_COMP_CLK_ENABLE() do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)
|
全局变量
1
| TIM_HandleTypeDef g_timx_comp_pwm_handle;
|
初始化函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
void atim_timx_comp_pwm_init(uint16_t arr, uint16_t psc) { TIM_OC_InitTypeDef timx_oc_comp_pwm = {0};
g_timx_comp_pwm_handle.Instance = ATIM_TIMX_COMP; g_timx_comp_pwm_handle.Init.Prescaler = psc ; g_timx_comp_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP; g_timx_comp_pwm_handle.Init.Period = arr; g_timx_comp_pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_OC_Init(&g_timx_comp_pwm_handle);
timx_oc_comp_pwm.OCMode = TIM_OCMODE_TOGGLE; timx_oc_comp_pwm.Pulse = 250 - 1; timx_oc_comp_pwm.OCPolarity = TIM_OCPOLARITY_HIGH; HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_1); __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_1);
timx_oc_comp_pwm.Pulse = 500 - 1; HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_2); __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_2);
timx_oc_comp_pwm.Pulse = 750 - 1; HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_3); __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_3);
timx_oc_comp_pwm.Pulse = 1000 - 1; timx_oc_comp_pwm.OCIdleState = TIM_OCIDLESTATE_RESET; HAL_TIM_OC_ConfigChannel(&g_timx_comp_pwm_handle, &timx_oc_comp_pwm, TIM_CHANNEL_4); __HAL_TIM_ENABLE_OCxPRELOAD(&g_timx_comp_pwm_handle, TIM_CHANNEL_4);
HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_1); HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_2); HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_3); HAL_TIM_OC_Start(&g_timx_comp_pwm_handle, TIM_CHANNEL_4); }
void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) { if (htim->Instance == ATIM_TIMX_COMP) { GPIO_InitTypeDef gpio_init_struct;
ATIM_TIMX_COMP_CLK_ENABLE();
ATIM_TIMX_COMP_CH1_GPIO_CLK_ENABLE(); ATIM_TIMX_COMP_CH2_GPIO_CLK_ENABLE(); ATIM_TIMX_COMP_CH3_GPIO_CLK_ENABLE(); ATIM_TIMX_COMP_CH4_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = ATIM_TIMX_COMP_CH1_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_PP; gpio_init_struct.Pull = GPIO_NOPULL; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(ATIM_TIMX_COMP_CH1_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = ATIM_TIMX_COMP_CH2_GPIO_PIN; HAL_GPIO_Init(ATIM_TIMX_COMP_CH2_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = ATIM_TIMX_COMP_CH3_GPIO_PIN; HAL_GPIO_Init(ATIM_TIMX_COMP_CH3_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = ATIM_TIMX_COMP_CH4_GPIO_PIN; HAL_GPIO_Init(ATIM_TIMX_COMP_CH4_GPIO_PORT, &gpio_init_struct); } }
|
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| int main(void) { uint8_t t = 0;
HAL_Init(); sys_stm32_clock_init(RCC_PLL_MUL9); delay_init(72); led_init(); atim_timx_comp_pwm_init(1000 - 1, 72 - 1); ATIM_TIMX_COMP_CH1_CCRX = 250 - 1; ATIM_TIMX_COMP_CH2_CCRX = 500 - 1; ATIM_TIMX_COMP_CH3_CCRX = 750 - 1; ATIM_TIMX_COMP_CH4_CCRX = 1000 - 1;
while (1) { delay_ms(10); t++;
if (t >= 20) { LED0_TOGGLE(); t = 0; } } }
|
实验现象
互补输出带死区控制实验
参考:正点原子
死区是什么
死区的应用
捕获/比较通道的输出部分(通道1至3)
死区时间计算
刹车(断路)功能
发生刹车后,会怎么样?
实验配置步骤
相关HAL库函数介绍
关键结构体介绍
编程实战
本次实验使用tim1的ch1(A8)、ch1n(B13)、bkin(B12)通道,无重映射
设置CKD=2即fdts四分频,设置DTG=100, 死区时间55.56us
输出有效电平为低电平,频率1KHz,占空比30%
实验结果用逻辑分析仪观察
宏定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
#define ATIM_TIMX_CPLM_CHY_GPIO_PORT GPIOA #define ATIM_TIMX_CPLM_CHY_GPIO_PIN GPIO_PIN_8 #define ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_CPLM_CHYN_GPIO_PORT GPIOB #define ATIM_TIMX_CPLM_CHYN_GPIO_PIN GPIO_PIN_13 #define ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_CPLM_BKIN_GPIO_PORT GPIOB #define ATIM_TIMX_CPLM_BKIN_GPIO_PIN GPIO_PIN_12 #define ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_CPLM_CHYN_GPIO_REMAP() do{__HAL_RCC_AFIO_CLK_ENABLE();\ __HAL_AFIO_REMAP_TIM1_ENABLE();\ }while(0)
#define ATIM_TIMX_CPLM TIM1 #define ATIM_TIMX_CPLM_CHY TIM_CHANNEL_1 #define ATIM_TIMX_CPLM_CHY_CCRY ATIM_TIMX_CPLM->CCR1 #define ATIM_TIMX_CPLM_CLK_ENABLE() do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)
void atim_timx_pwm_chy_init(uint16_t arr, uint16_t psc); void atim_timx_npwm_chy_init(uint16_t arr, uint16_t psc); void atim_timx_npwm_chy_set(uint32_t npwm); void atim_timx_comp_pwm_init(uint16_t arr, uint16_t psc); void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc); void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg);
|
全局变量
1 2
| TIM_HandleTypeDef g_timx_cplm_pwm_handle; TIM_BreakDeadTimeConfigTypeDef g_sbreak_dead_time_config = {0};
|
初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
void atim_timx_cplm_pwm_init(uint16_t arr, uint16_t psc) { GPIO_InitTypeDef gpio_init_struct = {0}; TIM_OC_InitTypeDef tim_oc_cplm_pwm = {0};
ATIM_TIMX_CPLM_CLK_ENABLE(); ATIM_TIMX_CPLM_CHY_GPIO_CLK_ENABLE(); ATIM_TIMX_CPLM_CHYN_GPIO_CLK_ENABLE(); ATIM_TIMX_CPLM_BKIN_GPIO_CLK_ENABLE(); gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHY_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_PP; gpio_init_struct.Pull = GPIO_PULLUP; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH ; HAL_GPIO_Init(ATIM_TIMX_CPLM_CHY_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = ATIM_TIMX_CPLM_CHYN_GPIO_PIN; HAL_GPIO_Init(ATIM_TIMX_CPLM_CHYN_GPIO_PORT, &gpio_init_struct);
gpio_init_struct.Pin = ATIM_TIMX_CPLM_BKIN_GPIO_PIN; HAL_GPIO_Init(ATIM_TIMX_CPLM_BKIN_GPIO_PORT, &gpio_init_struct);
g_timx_cplm_pwm_handle.Instance = ATIM_TIMX_CPLM; g_timx_cplm_pwm_handle.Init.Prescaler = psc; g_timx_cplm_pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP; g_timx_cplm_pwm_handle.Init.Period = arr; g_timx_cplm_pwm_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; g_timx_cplm_pwm_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_PWM_Init(&g_timx_cplm_pwm_handle);
tim_oc_cplm_pwm.OCMode = TIM_OCMODE_PWM1; tim_oc_cplm_pwm.OCPolarity = TIM_OCPOLARITY_LOW; tim_oc_cplm_pwm.OCNPolarity = TIM_OCNPOLARITY_LOW; tim_oc_cplm_pwm.OCIdleState = TIM_OCIDLESTATE_SET; tim_oc_cplm_pwm.OCNIdleState = TIM_OCNIDLESTATE_SET; HAL_TIM_PWM_ConfigChannel(&g_timx_cplm_pwm_handle, &tim_oc_cplm_pwm, ATIM_TIMX_CPLM_CHY);
g_sbreak_dead_time_config.OffStateRunMode = TIM_OSSR_DISABLE; g_sbreak_dead_time_config.OffStateIDLEMode = TIM_OSSI_DISABLE; g_sbreak_dead_time_config.LockLevel = TIM_LOCKLEVEL_OFF; g_sbreak_dead_time_config.BreakState = TIM_BREAK_ENABLE; g_sbreak_dead_time_config.BreakPolarity = TIM_BREAKPOLARITY_HIGH; g_sbreak_dead_time_config.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE; HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config);
HAL_TIM_PWM_Start(&g_timx_cplm_pwm_handle, ATIM_TIMX_CPLM_CHY); HAL_TIMEx_PWMN_Start(&g_timx_cplm_pwm_handle, ATIM_TIMX_CPLM_CHY); }
|
其他函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
void atim_timx_cplm_pwm_set(uint16_t ccr, uint8_t dtg) { g_sbreak_dead_time_config.DeadTime = dtg; HAL_TIMEx_ConfigBreakDeadTime(&g_timx_cplm_pwm_handle, &g_sbreak_dead_time_config); __HAL_TIM_MOE_ENABLE(&g_timx_cplm_pwm_handle); ATIM_TIMX_CPLM_CHY_CCRY = ccr; }
|
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
int main(void) { uint8_t t = 0;
HAL_Init(); sys_stm32_clock_init(RCC_PLL_MUL9); delay_init(72);
led_init(); key_init(); atim_timx_cplm_pwm_init(1000 - 1, 72 - 1); atim_timx_cplm_pwm_set(300, 100);
while (1) { delay_ms(10); t++;
if (t >= 20) { LED0_TOGGLE(); t = 0; } } }
|
实验结果
PWM输入模式实验
工作原理
个人感觉边沿检测那边的信号这样走有些问题
下面是我猜测的实际信号路线
PWM输入模式时序
实验配置步骤
相关HAL库函数介绍
关键结构体介绍
编程实战
本次实验用tim2_ch1(A0)输出pwm信号,频率100khz,占空比40%
用tim1_ch1(PA8)检测pwm信号
宏定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
#define GTIM_TIMX_PWM_CHY_GPIO_PORT GPIOA #define GTIM_TIMX_PWM_CHY_GPIO_PIN GPIO_PIN_0 #define GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define GTIM_TIMX_PWM_CHY_GPIO_REMAP() do{__HAL_RCC_AFIO_CLK_ENABLE();\ __HAL_AFIO_REMAP_TIM3_PARTIAL();\ }while(0)
#define GTIM_TIMX_PWM TIM2 #define GTIM_TIMX_PWM_CHY TIM_CHANNEL_1 #define GTIM_TIMX_PWM_CHY_CCRX TIM2->CCR1 #define GTIM_TIMX_PWM_CHY_CLK_ENABLE() do{ __HAL_RCC_TIM2_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_PWMIN_CHY_GPIO_PORT GPIOA #define ATIM_TIMX_PWMIN_CHY_GPIO_PIN GPIO_PIN_8 #define ATIM_TIMX_PWMIN_CHY_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_PWMIN TIM1 #define ATIM_TIMX_PWMIN_IRQn TIM1_UP_IRQn #define ATIM_TIMX_PWMIN_IRQHandler TIM1_UP_IRQHandler #define ATIM_TIMX_PWMIN_CHY TIM_CHANNEL_1 #define ATIM_TIMX_PWMIN_CHY_CLK_ENABLE() do{ __HAL_RCC_TIM1_CLK_ENABLE(); }while(0)
#define ATIM_TIMX_PWMIN_CC_IRQn TIM1_CC_IRQn #define ATIM_TIMX_PWMIN_CC_IRQHandler TIM1_CC_IRQHandler
|
全局变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| TIM_HandleTypeDef g_timx_pwm_chy_handle;
TIM_HandleTypeDef g_timx_pwmin_chy_handle;
uint8_t g_timxchy_pwmin_sta = 0; uint16_t g_timxchy_pwmin_psc = 0; uint32_t g_timxchy_pwmin_hval = 0; uint32_t g_timxchy_pwmin_cval = 0;
|
初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
void gtim_timx_pwm_chy_init(uint16_t arr, uint16_t psc) { TIM_OC_InitTypeDef timx_oc_pwm_chy = {0};
g_timx_pwm_chy_handle.Instance = GTIM_TIMX_PWM; g_timx_pwm_chy_handle.Init.Prescaler = psc; g_timx_pwm_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; g_timx_pwm_chy_handle.Init.Period = arr; HAL_TIM_PWM_Init(&g_timx_pwm_chy_handle);
timx_oc_pwm_chy.OCMode = TIM_OCMODE_PWM1; timx_oc_pwm_chy.Pulse = arr / 2; timx_oc_pwm_chy.OCPolarity = TIM_OCPOLARITY_HIGH; HAL_TIM_PWM_ConfigChannel(&g_timx_pwm_chy_handle, &timx_oc_pwm_chy, GTIM_TIMX_PWM_CHY); HAL_TIM_PWM_Start(&g_timx_pwm_chy_handle, GTIM_TIMX_PWM_CHY); }
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { if (htim->Instance == GTIM_TIMX_PWM) { GPIO_InitTypeDef gpio_init_struct; GTIM_TIMX_PWM_CHY_GPIO_CLK_ENABLE(); GTIM_TIMX_PWM_CHY_CLK_ENABLE();
gpio_init_struct.Pin = GTIM_TIMX_PWM_CHY_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_PP; gpio_init_struct.Pull = GPIO_PULLUP; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GTIM_TIMX_PWM_CHY_GPIO_PORT, &gpio_init_struct);
} }
void atim_timx_pwmin_chy_init(void) { GPIO_InitTypeDef gpio_init_struct = {0}; TIM_SlaveConfigTypeDef slave_config = {0}; TIM_IC_InitTypeDef tim_ic_pwmin_chy = {0};
ATIM_TIMX_PWMIN_CHY_CLK_ENABLE(); ATIM_TIMX_PWMIN_CHY_GPIO_CLK_ENABLE();
gpio_init_struct.Pin = ATIM_TIMX_PWMIN_CHY_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_INPUT; gpio_init_struct.Pull = GPIO_PULLDOWN; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH ; HAL_GPIO_Init(ATIM_TIMX_PWMIN_CHY_GPIO_PORT, &gpio_init_struct);
g_timx_pwmin_chy_handle.Instance = ATIM_TIMX_PWMIN; g_timx_pwmin_chy_handle.Init.Prescaler = 0; g_timx_pwmin_chy_handle.Init.CounterMode = TIM_COUNTERMODE_UP; g_timx_pwmin_chy_handle.Init.Period = 65535; HAL_TIM_IC_Init(&g_timx_pwmin_chy_handle); slave_config.SlaveMode = TIM_SLAVEMODE_RESET; slave_config.InputTrigger = TIM_TS_TI1FP1; slave_config.TriggerPolarity = TIM_INPUTCHANNELPOLARITY_RISING; slave_config.TriggerFilter = 0; HAL_TIM_SlaveConfigSynchro(&g_timx_pwmin_chy_handle, &slave_config);
tim_ic_pwmin_chy.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_DIRECTTI; tim_ic_pwmin_chy.ICPrescaler = TIM_ICPSC_DIV1; tim_ic_pwmin_chy.ICFilter = 0; HAL_TIM_IC_ConfigChannel( &g_timx_pwmin_chy_handle, &tim_ic_pwmin_chy, TIM_CHANNEL_1 ); tim_ic_pwmin_chy.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING; tim_ic_pwmin_chy.ICSelection = TIM_ICSELECTION_INDIRECTTI; HAL_TIM_IC_ConfigChannel(&g_timx_pwmin_chy_handle,&tim_ic_pwmin_chy,TIM_CHANNEL_2); HAL_NVIC_SetPriority(ATIM_TIMX_PWMIN_IRQn, 1, 3); HAL_NVIC_EnableIRQ( ATIM_TIMX_PWMIN_IRQn ); if ( ATIM_TIMX_PWMIN == TIM1) { HAL_NVIC_SetPriority(ATIM_TIMX_PWMIN_CC_IRQn, 1, 3); HAL_NVIC_EnableIRQ(ATIM_TIMX_PWMIN_CC_IRQn); }
__HAL_TIM_ENABLE_IT(&g_timx_pwmin_chy_handle, TIM_IT_UPDATE); HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handle, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(&g_timx_pwmin_chy_handle, TIM_CHANNEL_2); }
|
中断服务函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
void ATIM_TIMX_PWMIN_IRQHandler(void) { atim_timx_pwmin_chy_process(); }
void ATIM_TIMX_PWMIN_CC_IRQHandler(void) { atim_timx_pwmin_chy_process(); }
|
其他函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
static void atim_timx_pwmin_chy_process(void) { static uint8_t sflag = 0;
if (g_timxchy_pwmin_sta) { g_timxchy_pwmin_psc = 0; ATIM_TIMX_PWMIN->SR = 0; __HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handle, 0); return ; }
if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handle, TIM_FLAG_UPDATE)) { __HAL_TIM_CLEAR_FLAG(&g_timx_pwmin_chy_handle, TIM_FLAG_UPDATE);
if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handle, TIM_FLAG_CC1) == 0) { sflag = 0; if (g_timxchy_pwmin_psc == 0) { g_timxchy_pwmin_psc ++; } else { if (g_timxchy_pwmin_psc == 65535) { g_timxchy_pwmin_psc = 0; } else if (g_timxchy_pwmin_psc > 32767) { g_timxchy_pwmin_psc = 65535; } else { g_timxchy_pwmin_psc += g_timxchy_pwmin_psc; } }
__HAL_TIM_SET_PRESCALER(&g_timx_pwmin_chy_handle, g_timxchy_pwmin_psc); __HAL_TIM_SET_COUNTER(&g_timx_pwmin_chy_handle, 0); ATIM_TIMX_PWMIN->SR = 0; return ; } }
if (sflag == 0) { if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handle, TIM_FLAG_CC1)) { sflag = 1; } ATIM_TIMX_PWMIN->SR = 0; return ; }
if (g_timxchy_pwmin_sta == 0) { if (__HAL_TIM_GET_FLAG(&g_timx_pwmin_chy_handle, TIM_FLAG_CC1)) { g_timxchy_pwmin_hval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handle, TIM_CHANNEL_2) + 1; g_timxchy_pwmin_cval = HAL_TIM_ReadCapturedValue(&g_timx_pwmin_chy_handle, TIM_CHANNEL_1) + 1;
if (g_timxchy_pwmin_hval < g_timxchy_pwmin_cval) { g_timxchy_pwmin_sta = 1;
g_timxchy_pwmin_psc = ATIM_TIMX_PWMIN->PSC; if (g_timxchy_pwmin_psc == 0) { g_timxchy_pwmin_hval++; g_timxchy_pwmin_cval++; }
sflag = 0; ATIM_TIMX_PWMIN->CR1 &= ~(1 << 0); __HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handle, TIM_IT_CC1); __HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handle, TIM_IT_CC2); __HAL_TIM_DISABLE_IT(&g_timx_pwmin_chy_handle, TIM_IT_UPDATE);
ATIM_TIMX_PWMIN->SR = 0; } else { atim_timx_pwmin_chy_restart(); } } } ATIM_TIMX_PWMIN->SR = 0; }
|
主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| extern uint16_t g_timxchy_pwmin_psc; extern uint16_t g_timxchy_pwmin_sta; extern uint32_t g_timxchy_pwmin_hval; extern uint32_t g_timxchy_pwmin_cval;
int main(void) { uint8_t t = 0; double ht, ct, f, tpsc;
HAL_Init(); sys_stm32_clock_init(RCC_PLL_MUL9); delay_init(72); usart_init(115200); led_init(); key_init(); gtim_timx_pwm_chy_init(10 - 1, 72 - 1); GTIM_TIMX_PWM_CHY_CCRX = 4; atim_timx_pwmin_chy_init(); printf("Start:\n"); while (1) { delay_ms(10); t++;
if (t >= 20) { if (g_timxchy_pwmin_sta) { printf("\r\n"); printf("PWM PSC :%d\r\n", g_timxchy_pwmin_psc); printf("PWM Hight:%d\r\n", g_timxchy_pwmin_hval); printf("PWM Cycle:%d\r\n", g_timxchy_pwmin_cval); tpsc = ((double)g_timxchy_pwmin_psc + 1) / 72; ht = g_timxchy_pwmin_hval * tpsc; ct = g_timxchy_pwmin_cval * tpsc; f = (1 / ct) * 1000000; printf("PWM Hight time:%.3fus\r\n", ht); printf("PWM Cycle time:%.3fus\r\n", ct); printf("PWM Frequency :%.3fHz\r\n", f); atim_timx_pwmin_chy_restart(); }
LED0_TOGGLE(); t = 0; } } }
|
实验现象