STM32 通用定时输出PWM

目录

  • PWM的工作原理
  • 通用定时器输出PWM
  • PWM的工作原理
  • PWM的内部运作机制
  • PWM的模式
    • 模式一 边沿对齐模式
    • 模式二 中央对齐模式
  • 自动加载的预加载寄存器
  • 定时器输出PWM 结构体讲解
  • 定时器输出PWM 库函数讲解
  • 定时器输出PWM 库函数讲解
  • 案例驱动SG90电机动起来
  • 代码
    • motor.h
    • motot.c
    • main.c

PWM的工作原理

STM32 通用定时输出PWM_第1张图片

通用定时器输出PWM

STM32 通用定时输出PWM_第2张图片
以TIM3为例,STM32的通用定时器氛围TIM2,TIM3,TIM4,TIM5,每个定时器都有独立的四个通道可以用来作为: 输入捕获,输出比较,PWM输出,单脉冲模式输出等。

STM32的定时器除了TIM6和TIM7(基本定时器)之外,其他的定时器都可以产生PWM波输出,高级定时器TIM1,TIM8可以同时产生7路PWM输出,而通用定时器可以同时产生4路PWM输出,这样STM32可以最多同时输出30路PWM输出!

PWM的工作原理

向上计数为例,讲述PWM原理:

①在PWM输出模式下除了CNT(计数器当前值),ARR(自动重装载值),CCRx(捕获/比较寄存器值)。

②当CNT小于CCRx时,TIMx_CHx通道输出低电平

③当CNT等于或大于CCRx时,TIMx_CHx通道输出高电平

所谓脉宽调制信号(PWM波),就是一个TIMx_ARR自动重装载寄存器确定频率(由它决定PWM周期),TIM_CCRx寄存器确定占空比信号。

假设ARR = 100,CCRx = 80,那么CNT小于80(CCRx)的时低电平,大于80(CCRx)的时高电平,占空比为20%,CNT到达100代表一个周期结束。

如果想要调节占空比,只需要调节CCRx就行了
STM32 通用定时输出PWM_第3张图片

PWM的内部运作机制

STM32 通用定时输出PWM_第4张图片
CCR1:设置捕获比较寄存器,设置比较值。
CCMR1寄存区:设置PWM模式1 或者PWM模式2。
CCER: P位:输出/捕获 :设置极性: 0 高电平有效,1 低电平有效
E位:输出/捕获 : 使能端口

PWM的模式

模式一 边沿对齐模式

向上计数时: 当TIMx_CNT 向下计数时: 一旦TIMx_CNT>TIMx_CCRx,CCR1通道1为无效电平,否则为有效电平。

有效电平是高电平还是低电平由PWM的内部运作机制图中CCER决定
STM32 通用定时输出PWM_第5张图片

模式二 中央对齐模式

向上计数时: 当TIMx_CNT 向下计数时: 一旦TIMx_CNT>TIMx_CCRx,CCR1通道1为有效电平,否则为无效电平。
STM32 通用定时输出PWM_第6张图片

自动加载的预加载寄存器

STM32 通用定时输出PWM_第7张图片
STM32 通用定时输出PWM_第8张图片
简单的说:
APER =1 ,ARR立即生效
APER =0,ARR下个周期生效
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);

定时器输出PWM 结构体讲解

typedef struct
{
uint16_t TIM_OCMode; //配置PWM模式1还是模式2
uint16_t TIM_OutputState; //配置输出使能/ OR失能
uint16_t TIM_OutputNState;
uint16_t TIM_Pulse; //配置比较值,CCRx
uint16_t TIM_OCPolarity; //比较输出极性
uint16_t TIM_OCNPolarity;
uint16_t TIM_OCIdleState;
uint16_t TIM_OCNIdleState;
} TIM_OCInitTypeDef;

一般只需要配置字体加粗的三个就行了。

定时器输出PWM 库函数讲解

void TIM_OCxInit //结构体初始化
(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_SetCompare1 //设置比较值函数
(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_OC1PreloadConfig //使能输入比较预装载
(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
void TIM_Cmd == //开启定时器==
(TIM_TypeDef* TIMx, FunctionalState NewState)
void TIM_ARRPreloadConfig //使能自动重装载的预装载寄存器允许位
(TIM_TypeDef* TIMx, FunctionalState NewState);
void TIM_OC1PolarityConfig //配置修改极性
(TIM_TypeDef* TIMx, uint16_t TIM_OCPolarity);

定时器输出PWM 库函数讲解

TIM3 PWM输出 驱动SG90电机 配置过程:

1.GPIO结构体
2.配置通用定时器结构体
3.配置定时去输出PWM结构体
4.打开时钟 —> GPIO时钟,TIM定时器时钟,部分重映射时钟
5.配置PWM比较值

案例驱动SG90电机动起来

STM32 通用定时输出PWM_第9张图片
STM32 通用定时输出PWM_第10张图片
我使用的是PB_5引脚,并重映射为TIM3通道2

代码

motor.h

#include "stm32f10x.h"
void motor_Init(void);

motot.c

#include "stm32f10x.h"
#include "motor.h"
/*
    1.GPIO½á¹¹Ìå
		2.ͨÓö¨Ê±Æ÷½á¹¹Ìå
		3.PWM½á¹¹Ìå
		4.´ò¿ªÊ±ÖÓ
*/

//ʹÓõÄÊÇPB_5Òý½Å,ÖØÓ³ÉäTIM3£¬Í¨µÀ2

void motor_Init(void)
{
     
		GPIO_InitTypeDef 					Motor_GPIOStruct;
		TIM_TimeBaseInitTypeDef   Motor_TIMStruct;
		TIM_OCInitTypeDef         Motor_TIMPWMStruct; 
	
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//Òý½ÅµÄʱÖÓ
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //¶¨Ê±Æ÷ʱÖÓ
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //ÖØÓ³ÉäÐèÒªµÄʱÖÓ

		GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//¿ªÆôÖØÓ³Éä
																											 //PartialRemap²¿·ÖÖØÓ³Éä
																											 //FullRemapÍêÈ«ÖØÓ³Éä
	
		Motor_GPIOStruct.GPIO_Mode         = GPIO_Mode_AF_PP;  //ÍÆÍ츴ÓÃÊä³ö(ÖØÓ³Éä)
		Motor_GPIOStruct.GPIO_Pin          = GPIO_Pin_5;       //Òý½Å 5
		Motor_GPIOStruct.GPIO_Speed        = GPIO_Speed_10MHz; 
	  GPIO_Init(GPIOB,&Motor_GPIOStruct);

		Motor_TIMStruct.TIM_ClockDivision  = TIM_CKD_DIV1;      //ÉèÖÃʱÖӷָTIM_CKD_DIV1ÊDz»·Ö¸î
	  Motor_TIMStruct.TIM_CounterMode    = TIM_CounterMode_Up;//TIMÏòÉϼÆÊýģʽ
	  Motor_TIMStruct.TIM_Period         = 200  - 1;					//ÉèÖÃÔÚϸö¸üÐÂʼþ×°Èë»î¶¯µÄ×Ô¶¯ÖØ×°ÔØÖµ
	  Motor_TIMStruct.TIM_Prescaler      = 7200 - 1;					//TIMxʱÖÓƵÂÊÔ¤·ÖƵֵ
		TIM_TimeBaseInit(TIM3,&Motor_TIMStruct);

		Motor_TIMPWMStruct.TIM_OCMode      = TIM_OCMode_PWM1;       //Ñ¡Ôñ¶¨Ê±Æ÷ģʽΪ±ßÑضÔÆëģʽ
		Motor_TIMPWMStruct.TIM_OutputState = TIM_OutputState_Enable;//±È½ÏÊä³öʹÄÜ
	  Motor_TIMPWMStruct.TIM_OCPolarity  = TIM_OCPolarity_Low;    //Ñ¡ÔñÓÐЧÊä³ö¼«ÐÔ
		TIM_OC2Init(TIM3,&Motor_TIMPWMStruct);//OC2´ú±íͨµÀ2  TIM3ͨµÀ2
		TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//ʹÄÜԤװÔؼĴæÆ÷
	  TIM_Cmd(TIM3,ENABLE);

}

main.c

#include "stm32f10x.h"
#include "led.h"
#include "relay.h"
#include "shake.h"
#include "exti.h"
#include "usart.h"
#include "stdio.h"
#include "tim.h"
#include "motor.h"

void delay(uint16_t time)
{
     
	uint16_t i =0;
	while(time--){
     
		i=12000;
		while(i--);
	}
}

int main()
{
     
	uint16_t pwmval = 155;
	motor_Init();
	
	while(1)
	{
     
		for(pwmval = 195 ; pwmval >= 175 ; pwmval -= 5)
		{
     
			TIM_SetCompare2(TIM3,pwmval);
			delay(500);
		}
		
	}

}

STM32 通用定时输出PWM_第11张图片

你可能感兴趣的:(单片机,stm32,嵌入式)