1:通用PWM原理
PWM, 英文名Pulse width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%。PWM的功能有很多种,比如控制呼吸灯、控制直流电机或者舵机等驱动原件等等,是单片机的一个十分重要的功能。
PWM模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx CCRx寄存器确定占空比的信号。其框图如下图所示:
横坐标是时间变量,纵坐标是CNT计数值,CNT计数值随着时间的推进会不断经历从0到ARR,清零复位再到ARR的这一过程。这之中还有一个数值是CCRX即比较值,通过比较值和输出配置可以使之输出高低电平逻辑,.这样就产生了PWM波形。通过调节ARR的值可以调节PWM的周期,调节CCRX的值大小可以调节PWM占空比。
自我理解(ARR用来控制周期和频率,CCRx(寄存器值也是比较值)用来确定占空比)
2:PWM的功能要使用通用定时器或者高级定时器
3:PWM模式
PWM模式一 (TIM_OCMode_PWM1)
工作特性:
向上计数模式:
CNT < CCRx:通道输出有效电平
CNT ≥ CCRx:通道输出无效电平
向下计数模式:
CNT > CCRx:通道输出无效电平
CNT ≤ CCRx:通道输出有效电平
PWM模式二 (TIM_OCMode_PWM2)
工作特性:
向上计数模式:
CNT < CCRx:通道输出无效电平
CNT ≥ CCRx:通道输出有效电平
向下计数模式:
CNT > CCRx:通道输出有效电平
CNT ≤ CCRx:通道输出无效电平
关键区别对比
在向上计数模式中:PWM模式1和模式2的定义和区别,可以简单理解为:PWM模式1的情况下,当前值小于比较值为有效电平;PWM模式2的情况下,当前值大于比较值为有效电平。有效电平为高为低需要配置
4:定时器PWM库函数的配置
这是 STM32 定时器输出比较(Output Compare)功能的配置结构体,用于设置 PWM 输出特性。下面逐项解释每个成员:
1. TIM_OCMode (输出比较模式)
uint16_t TIM_OCMode;
功能:设置定时器的输出比较工作模式
可选值:
TIM_OCMode_Timing:定时模式(仅触发中断/DMA)
TIM_OCMode_Active:匹配时设置有效电平
TIM_OCMode_Inactive:匹配时设置无效电平
TIM_OCMode_Toggle:匹配时电平翻转
TIM_OCMode_PWM1:PWM 模式 1(常用)
TIM_OCMode_PWM2:PWM 模式 2
示例:TIM_OCMode_PWM1
2. TIM_OutputState (主通道输出状态)
uint16_t TIM_OutputState;
功能:使能/禁用主输出通道(如 TIMx_CH1)
可选值:
TIM_OutputState_Enable:使能输出
TIM_OutputState_Disable:禁用输出
示例:TIM_OutputState_Enable
3. TIM_OutputNState (互补通道输出状态)
uint16_t TIM_OutputNState;
功能:使能/禁用互补输出通道(如 TIMx_CH1N)
特殊说明:仅高级定时器 TIM1/TIM8 有效
可选值:
TIM_OutputNState_Enable:使能互补输出
TIM_OutputNState_Disable:禁用互补输出
示例:TIM_OutputNState_Disable
4. TIM_Pulse (脉冲宽度值)
uint16_t TIM_Pulse;
功能:设置捕获/比较寄存器的值(CCRx)
范围:0x0000 - 0xFFFF(0-65535)
作用:决定 PWM 占空比
计算:占空比 = TIM_Pulse / (TIM_Period + 1)
示例:1500(1.5ms 脉宽)
5. TIM_OCPolarity (主通道输出极性)
uint16_t TIM_OCPolarity;
功能:设置主通道输出极性
可选值:
TIM_OCPolarity_High:高电平有效
TIM_OCPolarity_Low:低电平有效
示例:TIM_OCPolarity_High(舵机常用)
6. TIM_OCNPolarity (互补通道输出极性)
uint16_t TIM_OCNPolarity;
功能:设置互补通道输出极性
特殊说明:仅高级定时器 TIM1/TIM8 有效
可选值:
TIM_OCNPolarity_High:高电平有效
TIM_OCNPolarity_Low:低电平有效
示例:TIM_OCNPolarity_Low
7. TIM_OCIdleState (主通道空闲状态)
uint16_t TIM_OCIdleState;
功能:定时器空闲时(未启动)主通道的输出电平
特殊说明:仅高级定时器 TIM1/TIM8 有效
可选值:
TIM_OCIdleState_Set:输出高电平
TIM_OCIdleState_Reset:输出低电平
示例:TIM_OCIdleState_Reset
8. TIM_OCNIdleState (互补通道空闲状态)
uint16_t TIM_OCNIdleState;
功能:定时器空闲时互补通道的输出电平
特殊说明:仅高级定时器 TIM1/TIM8 有效
可选值:
TIM_OCNIdleState_Set:输出高电平
TIM_OCNIdleState_Reset:输出低电平
示例:TIM_OCNIdleState_Set
相关函数说明
1. 设置比较值函数
void TIM_SetCompareX(TIM_TypeDef* TIMx, uint16_t Compare2);
功能:动态改变 PWM 占空比
参数:
TIMx:定时器名称(如 TIM3)
Compare2:写入 CCR2 寄存器的值
使用场景:舵机角度控制、LED 调光
示例:TIM_SetCompare2(TIM3, 1500);
2. 使能输出比较预装载
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
功能:启用/禁用 CCR2 寄存器的预装载
参数:
TIM_OCPreload_Enable:启用预装载(推荐)
TIM_OCPreload_Disable:禁用预装载
作用:避免 PWM 波形出现毛刺
示例:TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
3. 使能自动重装载预装载
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
功能:启用/禁用 ARR 寄存器的预装载
作用:同步更新周期和占空比
示例:TIM_ARRPreloadConfig(TIM3, ENABLE);
配置示例(舵机控制)
c
TIM_OCInitTypeDef oc;
oc.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1
oc.TIM_OutputState = TIM_OutputState_Enable; // 使能主通道
oc.TIM_Pulse = 1500; // 1.5ms脉宽
oc.TIM_OCPolarity = TIM_OCPolarity_High; // 高电平有效
TIM_OC2Init(TIM3, &oc); // 初始化通道2
TIM_OC2PreloadConfig(TIM3, ENABLE); // 使能预装载
TIM_ARRPreloadConfig(TIM3, ENABLE); // 使能ARR预装载
TIM_Cmd(TIM3, ENABLE); // 启动定时器
(
PWM周期固定不变,不需要ARR预装载
如果您需要动态改变PWM周期(不仅仅是占空比),就需要启用ARR预装载:
)
关键提示:通用定时器(TIM2-TIM5)只需关注 TIM_OCMode, TIM_OutputState, TIM_Pulse, TIM_OCPolarity 四个成员。高级定时器(TIM1/TIM8)才需要配置互补通道相关参数。
一般我们在写舵机函数我们会设置比较值函数用来动态改变 PWM 占空比所以 TIM_Pulse可以先不配置。
SG90舵机
一、SG90舵机工作原理核心
PWM信号控制:舵机通过20ms周期(50Hz)的PWM脉冲宽度确定角度
脉冲宽度与角度关系:
0.5ms脉冲 → 0°
1.5ms脉冲 → 90°
2.5ms脉冲 → 180°
闭环控制系统:内部电位器实时反馈位置,电机驱动系统自动修正角度误差
脉冲宽度计算(极性为低时的反向逻辑):
注意:代码使用TIM_OCPolarity_Low(低有效),实际脉冲宽度 = 周期时间 - (比较值 × 计数时间)
三、舵机引脚连接
四、控制方法详解
硬件连接要求:
必须使用外部5V电源(STM32的5V引脚电流不足)
外部电源GND必须与STM32共地
信号线直接连接PB5(已配置为TIM3_CH2输出)
角度控制调用:
SG90_Run(90); // 转动到90°位置
脉冲精度调整:
修改TIM_SetCompare2()参数可微调角度
公式:比较值 = 200 - (期望脉冲宽度 / 0.1ms)
例:1.5ms脉冲 → 200 - 15 = 185
控制舵机配置步骤
·使能定时器和相关IO时钟
初始化IO为复用模式
· 初始化定时器
· 初始化输出比较参数
·使能预装载寄存器
·使能定时器
·改变比较值CCRx,达到不同的占空比效果
sg90.c
#include "stm32f10x.h"
#include "sg90.h"
void SG90_Init(void)
{
GPIO_InitTypeDef GPIO_Initstruct;
TIM_TimeBaseInitTypeDef TIM_Initstruct;
TIM_OCInitTypeDef TIM_OCInitstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//部分重映射
GPIO_Initstruct.GPIO_Pin=GPIO_Pin_5;
GPIO_Initstruct.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_Initstruct.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&GPIO_Initstruct);
TIM_Initstruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_Initstruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_Initstruct.TIM_Period=200-1;
TIM_Initstruct.TIM_Prescaler=7200-1;
TIM_Initstruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit( TIM3, &TIM_Initstruct);
// TIM_Cmd( TIM3, ENABLE);//放早了
TIM_OCInitstruct.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitstruct.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OCInitstruct.TIM_OutputState=TIM_OutputState_Enable;//关注N
TIM_OC2Init(TIM3,&TIM_OCInitstruct);
TIM_OC2PreloadConfig( TIM3, TIM_OCPreload_Enable);//
TIM_Cmd( TIM3, ENABLE);
}
void SG90_Run(uint16_t angle)
{
switch(angle)
{
case 180: TIM_SetCompare2( TIM3, 175);break;
case 135: TIM_SetCompare2( TIM3, 180);break;
case 90 : TIM_SetCompare2( TIM3, 185);break;
case 45 : TIM_SetCompare2( TIM3, 190);break;
case 0 : TIM_SetCompare2( TIM3, 195);break;
}
}
sg90.h
#ifndef SG90_H_
#define SG90_H_
void SG90_Init(void);
void SG90_Run(uint16_t angle);
#endif
main.c
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "Bear.h"
#include "key.h"
#include "relay.h"
#include "shake.h"
#include "wireless.h"
#include "exti_key.h"
#include "usart.h"
#include "stdio.h"
#include "Tim.h"
#include "sg90.h"
void delay(uint16_t time)//延时1ms 软件延时粗延时
{
uint16_t i=0;
while(time --)
{
i=12000;
while(i --);
}
}
int main()
{
SG90_Init();
while(1)
{
SG90_Run(135);
delay (1000);
SG90_Run(0);
delay (1000);
}
}
关键区别总结
————————————————
版权声明:本文为CSDN博主「Do vis824」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2402_88972815/article/details/149549448
|
|