STM32のPWM

STM32 中用定时器产生脉冲宽度调制(PWM)输出

 STM32 中的定时器除了 TIM6 和 TIM7,其它的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1、TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4 路的 PWM 输出

STM32 中占空比寄存器
 STM32 的 PWM 是 TIMx_ARR 寄存器确定频率(周期)、由能 TIMx_CCRx寄存器确认占空比的信号。在 TIM1_CCMRx 寄存器中的 OCxM 位写入“110”(PWM 模式 1)或“111”(PWM 模式 2),能够独立地设置每个通道工作在PWM 模式,每个 OCx 输出一路 PWM。必须通过设置 TIM1_CCMRx 寄存器 OCxPE位使能相应的预装载寄存器, 最后还要设置 TIM1_CR1 寄存器的 ARPE 位使能自动重装载的预处理计数器

STM32 PWM 边沿对齐模式
 向上计数的配置

当 TIM1_CR1 寄存器中的 DIR 位为低的时候执行向上计数。
在 PWM 模式 1,TIM1_CNT<TIM1_CCRx 时 PWM 参考信号,OCxREF 为高,否则为低。如果,TIM1_CCRx 中的比较值大于自动重装载值(TIM1_ARR),则 TIM1_OCxREF 保持为“1”,如果比较值为“0”,则 TIM1_OCxREF 保持为
“0”

向下计数的配置
当 TIM1_CR1 寄存器中的 DIR 位为高的时候执行向下计数
在 PWM 模式 1,TIM1_CNT>TIM1_CCRx 时 PWM 参考信号,OCxREF 为低, 否则为高。 如果, TIM1_CCRx 中的比较值大于自动重装载值 (TIM1_ARR) ,则 TIM1_OCxREF 保持为“1”,该模式下不产生 0%的 PWM 波形.


从上图可以清晰的看出,在 PWM 模式 1,TIM1_CNT>TIM1_CCRx 时 PWM 参考信号,OCxREF 为高,否则为低。如果,TIM1_CCRx 中的比较值大于自动重装载值(TIM1_ARR),则 TIM1_OCxREF 保持为“1”,IM1_CCRx 中的比较值为“0”时,则 TIM1_OCxREF 保持为“0”

GPIO 引脚时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//设置定时器 3 时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//功能复用 IO 时钟函数

本节实验用到了 PB 端口, 所以要把 PB 端口的时钟打开; 定时器 3 (TIM3)时钟源是通过 APB1 预分频器得到的,时器 3 时钟初始化;因为要产生 PWM波形,所以要打开功能复用时钟。



PB5对应TIM3_CH2所以可以用于PWM输出。


工程结构

#ifndef _pbdata_H
#define _pbdata_H

#include "stm32f10x.h"
#include "misc.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_tim.h"

//¶¨Òå±äÁ¿

extern u8 dt;

//¶¨Ò庯Êý

void RCC_HSE_Configuration(void);
void delay(u32 nCount);
void delay_us(u32 nus);
void delay_ms(u16 nms);

#endif
引入头文件

#include "pbdata.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);
void TIM3_Configuration(void);

int main(void)
{
	   u8 led_fx=1;
   u16 led_dt=0;

   RCC_Configuration();	//ϵͳʱÖÓ³õʼ»¯
   GPIO_Configuration();//¶Ë¿Ú³õʼ»¯
   TIM3_Configuration();//¶¨Ê±Æ÷ºÍpwmÅäÖà 
   while(1)
   {
   	 delay_ms(10);
	 if(led_fx==1)
	 {
	 	led_dt++;
	 }
	 else
	 {
	   led_dt--;
	 }

	 if(led_dt>910)  led_fx=0;
   	 if(led_dt==0)	 led_fx=1;

	 TIM_SetCompare2(TIM3,led_dt);
   }	
}

//ÅäÖÃʱÖÓ
void RCC_Configuration(void)
{
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//ÒòΪÓõ½PWMÊä³öËùÒÔ¿ªÆô¸´ÓÃʱÖÓ
}

//GPIOÅäÖÃ
void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	//LED
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

void TIM3_Configuration(void)
{
		TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
	TIM_OCInitTypeDef TIM_OCInitStructure;

	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);

	//¶¨Ê±Æ÷³õʼ»¯
	TIM_TimeBaseStruct.TIM_Period=899;//PMWƵÂÊΪ72000000/900 = 80000,//
	//Õ¼¿Õ±È±ÈÈçÄãÐèÒª°Ù·ÖÖ®50µÄÕ¼¿Õ±ÈÄÇô900*0.5
	TIM_TimeBaseStruct.TIM_Prescaler=0;//Ô¤·ÖƵ
	TIM_TimeBaseStruct.TIM_ClockDivision=0;
	TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;//ÏòÉÏ

	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct);
	

	//pwm ³õʼ»¯
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;

	TIM_OC2Init(TIM3,&TIM_OCInitStructure);

	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);

	TIM_Cmd(TIM3,ENABLE);
}

源代码

//PWM频率为72000000/900 = 80000,//
//占空比假如你需要百分之50的占空比那么900*0.5

PWM频率计算方法 假设现在定时器时钟是48000000 PWM频率是50000 那么占空比的最大值为48000000/50000 = 960。超过9600为直通

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值