1、实验目的
使用定时器 4 通道 3 生成 PWM 波控制 LED1 ,实现呼吸灯效果。
频率:2kHz,PSC=71,ARR=499
利用定时器溢出公式
周期等于频率的倒数。故Tout = 1/2KHZ;Ft = 72MHZ
PSC=71(喜欢设置成Ft的倍数),ARR=499
其实PSC与ARR的组合有很多种,上面只是一种
2、实现实验
复制03-流水灯的项目文件夹,重命名为18-呼吸灯
新建文件夹pwm。pwm.c和pwm.h文件
加载文件
编译
加载定时器的.c文件
代码:
main.c
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "pwm.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
led_init();//初始化led灯
pwm_init(72 - 1,500 - 1);
uint16_t i = 0;
while(1)
{
//亮度在300ms前使用呼吸灯方式
for(i = 0;i<300;i++)
{
pwm_compare_set(i);
delay_ms(10);
}
for(i = 0;i<300;i++)
{
pwm_compare_set(300 - i);
delay_ms(10);
}
}
}
pwm.c
#include "pwm.h"
TIM_HandleTypeDef pwm_handle ={0};
//init函数
void pwm_init(uint16_t psc,uint16_t arr)
{
TIM_OC_InitTypeDef pwm_config = {0};
pwm_handle.Instance = TIM4; //寄存器时基地址
pwm_handle.Init.Prescaler = psc; //psc
pwm_handle.Init.Period = arr; //arr
pwm_handle.Init.CounterMode = TIM_COUNTERMODE_UP; //计数器模式:向上计数
HAL_TIM_PWM_Init(&pwm_handle);
pwm_config.OCMode = TIM_OCMODE_PWM1; //定时模式:模式1
pwm_config.Pulse = arr/2;//CCR(比较寄存器)的值 :随意指定,因为值还要改
pwm_config.OCPolarity = TIM_OCPOLARITY_LOW;//有效电平:高电平
HAL_TIM_PWM_ConfigChannel(&pwm_handle,&pwm_config,TIM_CHANNEL_3);//句柄,pwm配置,通道3
HAL_TIM_PWM_Start(&pwm_handle,TIM_CHANNEL_3);
}
//msp函数
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM4)
{
GPIO_InitTypeDef gpio_initstruct;//定义一个结构体gpio_initstruct
//打开时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_TIM4_CLK_ENABLE();
//调用GPIO初始化函数
gpio_initstruct.Mode = GPIO_MODE_AF_PP;//复式推挽输出
gpio_initstruct.Pin = GPIO_PIN_8;//LED1对应的引脚
gpio_initstruct.Pull = GPIO_PULLUP;//上拉
gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;//速度:高速
HAL_GPIO_Init(GPIOB,&gpio_initstruct);
//使用中断的时候才使用NVIC
// HAL_NVIC_SetPendingIRQ(TIM4_IRQn);
// HAL_NVIC_EnableIRQ(TIM4_IRQn);
}
}
//修改CCR值的函数
void pwm_compare_set(uint16_t val)
{
__HAL_TIM_SET_COMPARE(&pwm_handle,TIM_CHANNEL_3,val);//句柄,通道,值
}
pwm.h
#ifndef __PWM_H__
#define __PWM_H__
#include "sys.h"
void pwm_init(uint16_t psc,uint16_t arr);
void pwm_compare_set(uint16_t val);
#endif