前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【STM32】PWM 输出 (标准库)

【STM32】PWM 输出 (标准库)

作者头像
AXYZdong
发布2020-10-29 14:12:23
2.3K0
发布2020-10-29 14:12:23
举报
文章被收录于专栏:想到什么就分享

一、PWM简介

PWM:脉冲宽度调制(Pulse width modulation,PWM)

脉冲宽度调制是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或MOS管导通时间的改变,从而实现开关稳压电源输出的改变。这种方式能使电源的输出电压在工作条件变化时保持恒定,是利用微处理器的数字信号对模拟电路进行控制的一种非常有效的技术。脉冲宽度调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。——百度百科

二、PWM输出模式

PWM 输出就是对外输出脉宽(即占空比)可调的方波信号,信号频率由自动重装 寄存器 ARR 的值决定,占空比由 比较寄存器 CCR 的值决定。

PWM 模式分为两种,PWM1和 PWM2。区别如下:

模式

计数器 CNT 计算方式

说明

PWM1

递增

CNT < CCR,通道CH为有效,否则为无效

递减

CNT > CCR,通道 CH为无效,否则为有效

PWM2

递增

CNT < CCR,通道CH为有效,否则为无效

递减

CNT < CCR,通道CH为有效,否则为无效

三、初始化结构体

1. TIM_TimeBaseInitTypeDef

代码语言:javascript
复制
 typedef struct {   
 	 uint16_t TIM_Prescaler;          // 预分频器   
	 uint16_t TIM_CounterMode;        // 计数模式   
	 uint32_t TIM_Period;             // 定时器周期   
 	 uint16_t TIM_ClockDivision;      // 时钟分频  
	 uint8_t TIM_RepetitionCounter;   // 重复计算器  
 } 	TIM_TimeBaseInitTypeDef; 

结构体具体介绍参见:【STM32】TIM—基本定时器

2. TIM_OCInitTypeDef

代码语言:javascript
复制
/** 
  * @brief  TIM Output Compare Init structure definition  
  */

typedef struct
{
  uint16_t TIM_OCMode;        /*!< Specifies the TIM mode.
                                   This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */

  uint16_t TIM_OutputState;   /*!< Specifies the TIM Output Compare state.
                                   This parameter can be a value of @ref TIM_Output_Compare_State */

  uint16_t TIM_OutputNState;  /*!< Specifies the TIM complementary Output Compare state.
                                   This parameter can be a value of @ref TIM_Output_Compare_N_State
                                   @note This parameter is valid only for TIM1 and TIM8. */

  uint32_t TIM_Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register. 
                                   This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_OCPolarity;    /*!< Specifies the output polarity.
                                   This parameter can be a value of @ref TIM_Output_Compare_Polarity */

  uint16_t TIM_OCNPolarity;   /*!< Specifies the complementary output polarity.
                                   This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
                                   @note This parameter is valid only for TIM1 and TIM8. */

  uint16_t TIM_OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
                                   This parameter can be a value of @ref TIM_Output_Compare_Idle_State
                                   @note This parameter is valid only for TIM1 and TIM8. */

  uint16_t TIM_OCNIdleState;  /*!< Specifies the TIM Output Compare pin state during Idle state.
                                   This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
                                   @note This parameter is valid only for TIM1 and TIM8. */
} TIM_OCInitTypeDef;
  • (1) TIM_OCMode:比较输出模式选择,总共有八种,常用的为 PWM1/PWM2。它设定 CCMRx寄存器 OCxM[2:0]位的值。
  • (2) TIM_OutputState:比较输出使能,决定最终的输出比较信号 OCx是否通过外部引脚输出。它设定 TIMx_CCER寄存器 CCxE/CCxNE 位的值。
  • (3) TIM_OutputNState:比较互补输出使能,决定 OCx的互补信号 OCxN是否通过外部引脚输出。它设定 CCER寄存器 CCxNE 位的值。
  • (4) TIM_Pulse:比较输出脉冲宽度,实际设定比较寄存器 CCR的值,决定脉冲宽度。可设置范围为 0至 65535。
  • (5) TIM_OCPolarity:比较输出极性,可选 OCx为高电平有效或低电平有效。它决定着定时器通道有效电平。它设定 CCER寄存器的 CCxP位的值。
  • (6) TIM_OCNPolarity:比较互补输出极性,可选 OCxN 为高电平有效或低电平有效。它设定 TIMx_CCER寄存器的 CCxNP位的值。
  • (7) TIM_OCIdleState:空闲状态时通道输出电平设置,可选输出 1或输出 0,即在空闲状态(BDTR_MOE 位为 0)时,经过死区时间后定时器通道输出高电平或低电平。它设定 CR2寄存器的 OISx位的值。
  • (8) TIM_OCNIdleState:空闲状态时互补通道输出电平设置,可选输出 1 或输出 0,即在空闲状态(BDTR_MOE 位为 0)时,经过死区时间后定时器互补通道输出高电平或低电 平,设定值必须与 TIM_OCIdleState 相反。它设定是 CR2 寄存器的 OISxN 位的值。

四、PWM输出实验

编程思路

  • 初始化 LED
  • 初始化延时函数
  • 开启定时器时钟
  • 设置定时器周期和预分频器
  • 初始化定时器
  • 主函数中修改比较值和占空比

pwm.h

代码语言:javascript
复制
// =============================================
# @Time    : 2020-10-24
# @Author  : AXYZdong
# @CSDN    : https://blog.csdn.net/qq_43328313
# @FileName: pwm.h
# @Software: keil5 MDK
// =============================================

#ifndef _TIME_H
#define _TIME_H

#include "stm32f4xx.h"
void TIM3_PWM_Init(u32 ARR , u32 PSC);

#endif

pwm.c

代码语言:javascript
复制
// =============================================
# @Time    : 2020-10-24
# @Author  : AXYZdong
# @CSDN    : https://blog.csdn.net/qq_43328313
# @FileName: pwm.c
# @Software: keil5 MDK
// =============================================

#include "pwm.h"
#include "bsp_led.h"

extern void TIM3_PWM_Init(u32 ARR , u32 PSC);

void TIM3_PWM_Init(u32 ARR , u32 PSC)
{		 					 
	//此部分需手动修改IO口设置
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  	//TIM3时钟使能    
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); 	//使能PORTA时钟	
	
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_TIM3); //GPIOA6复用为定时器3
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;           //GPIOFA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOA,&GPIO_InitStructure);              //初始化PA6
	  
	TIM_TimeBaseStructure.TIM_Prescaler=PSC;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
	TIM_TimeBaseStructure.TIM_Period=ARR;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//初始化定时器3
	
	//初始化TIM14 Channel1 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 4OC1

	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR1上的预装载寄存器
 
    TIM_ARRPreloadConfig(TIM3,ENABLE);//ARPE使能 
	
	TIM_Cmd(TIM3, ENABLE);  //使能TIM3										  
} 

main.c

代码语言:javascript
复制
// =============================================
# @Time    : 2020-10-24
# @Author  : AXYZdong
# @CSDN    : https://blog.csdn.net/qq_43328313
# @FileName: main.c
# @Software: keil5 MDK
// =============================================

#include "stm32f4xx.h"
#include "delay.h"
#include "pwm.h"
#include "bsp_led.h"

int main(void)
{
	u16 ledpwmval=0;
	u8 flag=1;
	delay_init(168); 	//初始化延时函数
  LED_GPIO_Config();     //初始化LED
  TIM3_PWM_Init(100-1,84-1); //初始化定时器
	
	while(1)
	{
		delay_ms(10);
		if(flag)ledpwmval++;
		else ledpwmval--;
		if(ledpwmval==0)flag=1;
		if(ledpwmval==40)flag=0;
		
		TIM_SetCompare1(TIM3,ledpwmval);	//修改比较值,修改占空比
 	}
}

五、总结

  • PWM输出,观察到 LED 缓慢变亮又缓慢变暗的状态(呼吸灯)
  • 通过对定时器初始化数据和比较值的修改,可以改变亮暗时间

【参考文献】

[1] 《零死角玩转 STM32—基于野火 F407[霸天虎]开发板 》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、PWM简介
  • 二、PWM输出模式
  • 三、初始化结构体
    • 1. TIM_TimeBaseInitTypeDef
      • 2. TIM_OCInitTypeDef
      • 四、PWM输出实验
        • 编程思路
          • pwm.h
            • pwm.c
              • main.c
              • 五、总结
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档