赞
踩
PWM(Pulse Width Modulation)简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在测量、通信、工控等方面。
常用的PWM输出模式有两种,即PWM1和PWM2,这两种模式的用法是差不多的,只是输出电平上有所差异,如下图:
再来结合波形图看比较好理解
上图的纵坐标即为我们的CNT,横坐标为时间。从这幅图中可以看出一个PWM波的周期是由ARR决定的,而其占空比则是由CCRx决定的。
打开软件,选择好自己的板子型号,然后开始配置,我使用的板子PB5接口接着LED,查看数据手册可以定时器3的通道二可以重映射到该口,所以就使用该口进行配置:
打开TIM3定时器界面后,将通道2设置为PWM输出,然后开始配置相关配置,首先需要确定PWM波的周期,这里所用到的公式为
Tout= ((arr+1)*(psc+1))/Tclk
Tout为溢出一次的时间,那么频率则为溢出时间的倒数,即
f=Tclk/((arr+1)*(psc+1))
这里以2KHz为例,首先Tclk为输入时钟频率72MHz,我们首先带入psc = 72-1方便计算,则算出arr = 500-1。
接下来配置模式为PWM模式1,这里的pause即为我们CNT,将其设置为499/2,即控制我们的占空比为50%,因为我们的CNT恰好为ARR的一半,最后是设置输出比较极性为低电平有效,因为板子上的LED灯需要接通低电平才亮,用户使用根据自身需要设置即可。
生成工程后我们可以看到左边已经有了相关代码
在使用通用定时器配置PWM波有以下几个比较重要的函数:
void MX_TIM3_Init(void); //通用定时器3初始化函数
HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); //HAL库定时器初始化函数
/*PWM配置函数*/
HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim,
const TIM_OC_InitTypeDef *sConfig,
uint32_t Channel);
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle); //相关时钟配置函数
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle); //重映射功能配置函数
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); //PWM使能函数
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, ledRpwmval); //这是一个宏定义,用于修改CCRx改变占空比
打开tim.c文件,STM32CubeMx已经一键生成了刚刚配置的代码:
在void MX_TIM3_Init(void)函数中可以看到,里面已经初始化好了定时器3的相关成员以及配置了对应的PWM输出参数为了使用PWM输出功能,我们需要在用户代码区添加使能函数,即:
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
在void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)以及void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)这两个函数中开启了对应的时钟以及重映射功能,其中__HAL_AFIO_REMAP_TIM3_PARTIAL()这个宏定义便是将TIM3CH2重映射到我们的GPIOB5端口上。
int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM3_Init(); /* USER CODE BEGIN 2 */ uint16_t ledRpwmval = 0; //控制LED的pwm重装载设定值 /*控制LED的pwm重装载设定值的递增或递减 dir = 1时为递增,dir = 0时为递减 */ uint8_t dir = 1; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(10); if(dir) ledRpwmval++; else ledRpwmval--; if(ledRpwmval > 300) dir = 0; if(0 == ledRpwmval) dir = 1; //修改比较值控制占空比 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, ledRpwmval); } /* USER CODE END 3 */ }
为了实现呼吸灯的功能,则是通过修改PWM波的占空比进行实现,这里设定两个参数:
ledRpwmval,dir
通过这两个参数以及__HAL_TIM_SET_COMPARE()这个宏定义实现占空比的改变,可以看到这里设定的比较值的范围为0 ~ 299,即占空比为40% ~ 100%(占空比为PWM波一个周期中高电平所占的时间)。至此,使用PWM实现呼吸灯的功能就实现了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。