目录
1、PWM
- PWM信号:PWM信号通过改变高电平和低电平的持续时间比(占空比)来调节输出功率。
- 定时器:STM32的PWM功能是通过定时器模块实现的。每个定时器都有多个通道,可以生成多个PWM信号。
2、芯片手册
在芯片手册中我们并不能直接找到PWM;因为PWM实际上,是由定时器实现的;所以我们要找到PWM需要在TIM章节中去找到他
但是我们可以看见,定时器又有两个章节高级定时器和通用定时器;怎么选择呢:
通用定时器(TIM1/TIM8)
- 功能:通用定时器适用于大多数PWM应用,支持基本的PWM模式(如PWM1、PWM2)。
- 应用:常用于简单的PWM控制,例如调光LED、电机控制等。
- 优点:配置简单、易于使用。
高级定时器(TIMx)
- 功能:高级定时器具有更多的功能,如死区时间生成、刹车输入等,适合复杂的应用。
- 应用:常用于电机控制、逆变器、伺服控制等需要精确控制和保护的场合。
- 优点:提供更高级的特性,适合高性能和高可靠性的应用。
3、如何配置生成一个PWM波形
说起来很简单:
- GPIO配置:
- 使能GPIOA的时钟,配置PA5为复用模式,选择TIM2的通道1作为输出引脚。
- 定时器配置:
- 使能TIM2的时钟。
- 配置预分频器(PSC)和自动重载值(ARR),确定PWM频率。
- 配置比较寄存器(CCR1),设置占空比。
- 设置PWM模式,并使能输出。
- 启动定时器:
- 启动定时器以生成PWM信号。
4、示例
PWM.h
#ifndef _PWM_H_
#define _PWM_H_
//引脚,定时器
#define PWM_PING GPIO_Pin_1
#define PWM_PING_PORT GPIOB
#define PWM_TIM TIM3
#define PWM_TIM_FUN_INIT TIM_OC4Init
#define PWM_TIM_FUN_SETCCR TIM_SetCompare4
//时钟
#define RCC_TIM_PORT RCC_APB1Periph_TIM3
#define RCC_GPIO_PORT RCC_APB2Periph_GPIOB
void Pwm_Init(void);
void Pwm_SetARR(int ARR);//修改频率
void Pwm_SetCCR(int CCR);//修改占空比
#endif
PWM.c
#include "stm32f10x.h"
#include "pwm.h"
void Pwm_Init(void)
{
//打开时钟
RCC_APB1PeriphClockCmd(RCC_TIM_PORT,ENABLE);
RCC_APB2PeriphClockCmd(RCC_GPIO_PORT,ENABLE);
GPIO_InitTypeDef GPIOB_Struct;
GPIOB_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIOB_Struct.GPIO_Pin = PWM_PING;
GPIOB_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PWM_PING_PORT,&GPIOB_Struct);
TIM_TimeBaseInitTypeDef Tim_Struct;
//Tim_Struct.TIM_ClockDivision时钟分割,输入捕获滤波器的频率
Tim_Struct.TIM_CounterMode = TIM_CounterMode_Up;
Tim_Struct.TIM_Period = 0;//自动装载ARR
Tim_Struct.TIM_Prescaler = 71;//PSC预分频系数
//Tim_Struct.TIM_RepetitionCounter高级定时器才有的
TIM_TimeBaseInit(PWM_TIM,&Tim_Struct);
//设置输出比较模式
TIM_OCInitTypeDef Tim_OC_Struct;
//Tim_OC_Struct.TIM_OCIdleState
Tim_OC_Struct.TIM_OCMode = TIM_OCMode_PWM1;
//Tim_OC_Struct.TIM_OCNIdleState
//Tim_OC_Struct.TIM_OCNPolarity
Tim_OC_Struct.TIM_OCPolarity = TIM_OCPolarity_High;
//Tim_OC_Struct.TIM_OutputNState
Tim_OC_Struct.TIM_OutputState = TIM_OutputState_Enable;
Tim_OC_Struct.TIM_Pulse = 0;//比较值
PWM_TIM_FUN_INIT(PWM_TIM,&Tim_OC_Struct);
//定时器使能
TIM_Cmd(PWM_TIM,ENABLE);
}
void Pwm_SetARR(int ARR)//修改频率
{
TIM_SetAutoreload(PWM_TIM,(uint16_t)ARR);
}
void Pwm_SetCCR(int CCR)//修改占空比
{
PWM_TIM_FUN_SETCCR(PWM_TIM,(uint16_t)CCR);
}
如果只是需要一个配置好的PWM的同学;copy走就可以了 ;修改一下头文件的宏,改成自己需要的引脚就可以直接运行了
5、如何配置出来的
首先我们使用的是TIM3通用定时器
请看图
TIM3;输出控制;首先看见最上面的RCC时钟;之后到了触发器;之后是PSC;之后计数器比较之后就是输出控制了;ok咱们一步一步来
5.1、RCC
首先先看芯片手册;PWM频率的PSC不就是预分频出来的吗??那么分的频率又是多少呢??
咱们来到RCC的结构图
首先请看芯片手册原话:
定时器时钟频率分配由硬件按以下2种情况自动设置:
1. 如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致。
2. 否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。
那怎么理解呢??难道所有的定时器都是APB1总线下面吗??不不不;他仅仅告诉我们定时器的频率与APB2的预分频系数有关;APB2的预分频系数默认为1;所有TIM的时钟频率默认72Mhz;那么这个时钟是在APB1下面还是APB2下面呢??
请看图:我们可以看见TIM2-TIM7通用定时器实在APB1下面的;所以开启定时器的时钟仅仅需要调用函数
RCC_APB1PeriphClockCmd(RCC_TIM_PORT,ENABLE);
5.2、时基单元
首先上代码
TIM_TimeBaseInitTypeDef Tim_Struct;
//Tim_Struct.TIM_ClockDivision时钟分割,输入捕获滤波器的频率
Tim_Struct.TIM_CounterMode = TIM_CounterMode_Up;
Tim_Struct.TIM_Period = 0;//自动装载ARR
Tim_Struct.TIM_Prescaler = 71;//PSC预分频系数
//Tim_Struct.TIM_RepetitionCounter高级定时器才有的
TIM_TimeBaseInit(PWM_TIM,&Tim_Struct);
知道了RCC为72Mhz;下面咱们来到了PSC;在芯片手册中有这么一段介绍
总得来说呢;就是这三个寄存器控制了“时基单元”;这也是定时器做什么需要配置的寄存器了;所以他这里的讲解呢太官方了;也很难看明白;咱们就挑着咱们需要的去看;
首先介绍一下,每个寄存器代表着什么
就是ARR有一个值,计数器呢如果是向上计数模式;每次就从0加一;到了ARR的值呢就归0;之后继续一直加一;
5.3、PWM输出
//设置输出比较模式
TIM_OCInitTypeDef Tim_OC_Struct;
//Tim_OC_Struct.TIM_OCIdleState
Tim_OC_Struct.TIM_OCMode = TIM_OCMode_PWM1;
//Tim_OC_Struct.TIM_OCNIdleState
//Tim_OC_Struct.TIM_OCNPolarity
Tim_OC_Struct.TIM_OCPolarity = TIM_OCPolarity_High;
//Tim_OC_Struct.TIM_OutputNState
Tim_OC_Struct.TIM_OutputState = TIM_OutputState_Enable;
Tim_OC_Struct.TIM_Pulse = 0;//比较值
PWM_TIM_FUN_INIT(PWM_TIM,&Tim_OC_Struct);
首先呢在上面的图中;上办部分我们已经知道了TIM定时器在做什么,那么怎么产生PWM波形呢??
我们看到下半部分
在中间有一个Pulse;在计数器的值小于pulse的时候,在我们的PWM1模式下,输出高电平;当计数器的值大于pulse的情况下,输出低电平(不严谨,应该是有效电平和无效电平;大家看得懂就行)于是我们需要配置的寄存器就明了了
5.4、具体配置
首先我们RCC给一个72Mhz的时钟,通过PSC寄存器分频;配置ARR以及CRR(pulse的);就可以产生PWM波形了;计算公式
-
时钟频率 (F_TIMER):定时器的时钟频率,默认为72 MHz。(再次强调:由APB2的预分频系数决定但是通用定时器是在APB1总线下面)
-
预分频器 (PSC):预分频器值,用于将时钟频率降低。其公式为:
其中,FAPBF_{APB}FAPB 是APB总线的频率,假设为72 MHz,如果未做任何分频,PSC通常为0。
-
自动重装载寄存器 (ARR):定义计数器的最大计数值,PWM频率的计算如下:
-
捕获/比较寄存器 (CCR):定义PWM信号的占空比。占空比计算为: