这次实验实现一个呼吸灯的效果,LED在第一秒内渐亮,在第二秒内渐暗,如此反复
控制LED的PWM波形阶梯数为100,即2秒内PWM的占空比从0%到100%范围内先递增后递减且递增/递减的幅度为1%
在设计STM32时,将定时器时钟7200分频后得到的10K时钟作为计数器时钟,并且设置周期为100,这样在一秒的时间可以产生100次中断,然后在中断中改变输出比较寄存器的值
#define USER_TIM_PSC 7200-1 #define USER_TIM_PERIOD 100-1
中断中还需使用到一个方向变量,控制输出比较寄存器在变化到最大和最小时改变增减方向
void USER_TIM_IRQ_HANDLER(void) { if(TIM_GetITStatus(USER_TIM, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(USER_TIM, TIM_IT_Update); if(pulse_width == 0) direction = 0; else if(pulse_width == 100) direction = 1; if(direction == 0) pulse_width++; else pulse_width--; TIM_SetCompare1(USER_TIM, pulse_width); } }
定时器配置时,选择输出比较模式为PWM1,向上计数,该模式下,当计数值小于比较寄存器值时输出有效电平,而如果是向下计数,则是计数值小于等于比较寄存器时为有效电平,有效电平可由寄存器配置
void mini_tim_config(void) { TIM_TimeBaseInitTypeDef tim_timebase_struct; TIM_OCInitTypeDef tim_oc_struct; GPIO_InitTypeDef gpio_struct; NVIC_InitTypeDef nvic_struct; GPIO_RCC_CMD(USER_TIM_GPIO_RCC, ENABLE); USER_TIM_RCC_CMD(USER_TIM_RCC, ENABLE); gpio_struct.GPIO_Mode = GPIO_Mode_AF_PP; gpio_struct.GPIO_Speed = GPIO_Speed_2MHz; gpio_struct.GPIO_Pin = USER_TIM_PIN; GPIO_Init(USER_TIM_GPIO, &gpio_struct); nvic_struct.NVIC_IRQChannel = USER_TIM_IRQ; nvic_struct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic_struct); TIM_TimeBaseStructInit(&tim_timebase_struct); tim_timebase_struct.TIM_CounterMode = TIM_CounterMode_Up; tim_timebase_struct.TIM_Prescaler = USER_TIM_PSC; tim_timebase_struct.TIM_Period = USER_TIM_PERIOD; tim_timebase_struct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(USER_TIM, &tim_timebase_struct); TIM_OCStructInit(&tim_oc_struct); tim_oc_struct.TIM_OCMode = TIM_OCMode_PWM1; tim_oc_struct.TIM_OCPolarity = TIM_OCPolarity_High; tim_oc_struct.TIM_OutputState = TIM_OutputState_Enable; tim_oc_struct.TIM_Pulse = pulse_width; TIM_OC1Init(USER_TIM, &tim_oc_struct); TIM_OC1PreloadConfig(USER_TIM, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(USER_TIM, ENABLE); TIM_Cmd(USER_TIM, ENABLE); TIM_ITConfig(USER_TIM, TIM_IT_Update, ENABLE); }