STM32CubeMX系列教程4:PWM

发布于 2018-05-25  567 次阅读


摘要: 上一章我们讲解了定时器的基本应用,以及定时器中断。这一章我们讲解通过定时器控制管脚输出PWM信号,控制LED1亮度渐变闪烁。

1.PWM简介
       脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调试。是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。广泛应用在从测量、通信到功率控制与变换的许多领域中。

例如上图中,图b)是微处理输出的数字信号,实际上他接到电机等功率设备上时,效果相当于图a)。这就是PWM调制。例如输出占空比为50%,频率为10Hz的脉冲,高电平为3.3V.则其输出的模拟效果相当于输出一个1.65V的高电平。脉冲调制有两个重要的参数,第一个就是输出频率,频率越高,则模拟的效果越好。第二个就是占空比。占空比就是改变输出模拟效果的电压大小。占空比越大则模拟出的电压越大。
2.stm32cube配置和说明
        打开STM32CubeMX新建工程,选择STMF746IGT6芯片,选择外部高速晶振(HSE)。LED1管脚PB6配置为定时器4的通道1输出。同时TIM4的通道1配置为PWM。
脉冲宽度调制模式可以生成一个信号,该信号频率由自动重载寄存器(TIMx_ARR)寄存器值决定,其占空比则由捕获/比较寄存器(TIMx_CCRx) 寄存器值决定。
在 PWM 模式下,计数器寄存器(TIMx_CNT )总是与捕获/比较寄存器(TIMx_CCRx )进行比较,以确定是TIMx_CCRxTIMx_CNT 还是 TIMx_CNTTIMx_CCRx(取决于计数器计数方向)。
下图为PWM边沿对齐模式(递增计数配置)。图中CCRx为捕获/比较寄存器,OCxREF为输出比较信号,CCxIF为中断状态标识位。
当CCRX=4时,当捕获/比较寄存器(TIMx_CCRx)比计数器小时,输出高电平,反之则输出低电平。
 

下图为PWM中心对齐模式。

配置系统时钟为216MHz。由上一章可知,定时挂载到APB1,时钟频率为108MHz。此处设置为1080分频。经过分频后的时钟频率为100000Hz,若要设置PWM周期为20ms,则计数器的值为2000-1。其他参数为默认不用修改。其中Pulse的为设置脉宽,即为捕获/比较寄存器(TIMx_CCRx)。通过修改它的值可以修改占空比。

生成报告,以及生成代码,编译程序。
3.添加应用程序
在tim.c文件中我们找到刚才的定时器初始化函数。
01 /* TIM4 init function */
02 void MX_TIM4_Init(void)
03 {
04   TIM_MasterConfigTypeDef sMasterConfig;
05   TIM_OC_InitTypeDef sConfigOC;
06  
07   htim4.Instance = TIM4;
08   htim4.Init.Prescaler = 1080-1;
09   htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
10   htim4.Init.Period = 2000-1;
11   htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
12   HAL_TIM_PWM_Init(&htim4);
13  
14   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
15   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
16   HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
17  
18   sConfigOC.OCMode = TIM_OCMODE_PWM1;
19   sConfigOC.Pulse = 0;
20   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
21   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
22   HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
23  
24   HAL_TIM_MspPostInit(&htim4);
25  
26 }
 
刚才说到的,设置Pulse的值可以修改脉宽。这里我们在main.c文件中添加一个用户PWM设置函数,函数的参数为修改的值。

01 /* USER CODE BEGIN 4 */
02 void user_pwm_setvalue(uint16_t value)
03 {
04     TIM_OC_InitTypeDef sConfigOC;
05  
06     sConfigOC.OCMode = TIM_OCMODE_PWM1;
07     sConfigOC.Pulse = value;
08     sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
09     sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
10     HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1);
11     HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);  
12 }
13 /* USER CODE END 4 */

 

在把main()函数中添加HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1)开启定时器PWM输出。在while循环中不断修改脉宽,实现LED亮度渐变。Pulse的值最大为2000,从0开始,每100ms增加100,当增加到2000时,又逐渐递减到0。

01 /* USER CODE BEGIN 2 */
02   HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
03 /* USER CODE END 2 */
04
05 /* Infinite loop */
06 /* USER CODE BEGIN WHILE */
07 while (1)
08 {
09 /* USER CODE END WHILE */
10
11 /* USER CODE BEGIN 3 */
12   HAL_Delay(100); 
13   if(pwm_value == 0) step = 100;
14   if(pwm_value == 2000) step = -100;
15   pwm_value += step;
16   user_pwm_setvalue(pwm_value);
17 }
18 /* USER CODE END 3 */
在main.c函数前面声明pwm_value,step变量,user_pwm_setvalue()函数.编译程序下载。按复位后可以看到LED1亮度渐变闪烁。

一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。