STM32学习之路——使用通用定时器产生想要频率和占空比的PWM

前言

STM32学习之路——通用定时器库函数分析(为产生PWM)
前面我学习了使用通用定时器产生PWM,对相关库函数进行分析理解后,就产生了想要产生我所期望的PWM的想法,下面是我的对程序的一些更改,若有不对的地方,还请大家批评指正。

原理

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
     IMPORT  __main
     IMPORT  SystemInit
                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

这段代码是启动文件里的一部分,从这段代码可以看出,程序在进行编译的时候,首先执行SystemInit函数,然后在执行main函数,进过对SystemInit函数进行分析,这段代码实际上就是对系统的时钟进行了重配置。也就是说APB1以36MHz,APB2以72MHz时钟进行运行。通过时钟树进行分析,TIM2定时器的时钟频率需要再乘2,也就是72MHz。
在这里插入图片描述
所以输入定时器的时钟频率为72MHz。

产生PWM的原理是:计数器达到我在自动重装载寄存器中设定值后,恢复为零,在重新计数,而这一个过程就构成了输出PWM的一个周期。在捕获/比较寄存器1(CCR1)中我们设定了一个值,当计数器小于该值时,输出为低电平,反之为高电平,而这一过程就构成了PWM的占空比,按照这种思路将程序进行更改,达到想要的输出。

还有一种方法就是更改计数器的频率,进而实现PWM的周期。
在这里插入图片描述
从这个图中,我们可以看出,可以通过更改PSC预分频器的值来更改计数器的计数频率。

程序实现

首先需要进行一个小计算。
计数器的计数模式可以为1分频,2分频,4分频,我把他设置为1分频,所以计数频率也就是72MHz。
现在就有一个公式:
PWM周期=计数器周期x自动重装载寄存器设定值=(1/72000000)*自动重装载寄存器设定值
PWM占空比=捕获/比较寄存器1设定值/自动重装载寄存器设定值
变形后得:
自动重装载寄存器设定值=72000000/PWM频率
捕获/比较寄存器1设定值=PWM占空比x72000000/PWM频率

在程序中定义一个函数

void TIM2_CH1_PWMOut(uint32_t freq,float Duty_Ratio)//2000<=freq<=9000000,Duty_Ratio<1
{
    uint16_t psc=0, x=0;
	GPIO_InitTypeDef GPIO_Structure;
	TIM_TimeBaseInitTypeDef TimeBaseStructure;
	TIM_OCInitTypeDef Tim_OCInitypeStructure;
    psc=72000000/freq;
    x=	(1-Duty_Ratio)*((72000000/freq));
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Perip    h_AFIO,DISABLE);
	//GPIO³õʼ»¯
	GPIO_Structure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Structure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Structure.GPIO_Pin=GPIO_Pin_0;
	GPIO_Init(GPIOA,&GPIO_Structure);
	//TIM2³õʼ»¯
	TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TimeBaseStructure.TIM_Period=psc;
	TimeBaseStructure.TIM_Prescaler=0;
	TIM_TimeBaseInit(TIM2,&TimeBaseStructure);
	//
	Tim_OCInitypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
	Tim_OCInitypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
	Tim_OCInitypeStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC1Init(TIM2,&Tim_OCInitypeStructure);
	
	TIM_Cmd(TIM2,ENABLE);
	
    TIM_SetCompare1(TIM2,x);	
	
}

调试验证

一、在主函数中输入以以代码,设置的PWM周期为2000Hz,占空比为0.4。调试结果如下:

int main(void)
{

	TIM2_CH1_PWMOut(2000,0.4);
	while(1);
}

在主函数中输入以上代码,设置的PWM周期为2000Hz,占空比为0.4。调试结果如下:
在这里插入图片描述
在这里插入图片描述
从调试图中取得十个周期时间间隔为3.333424ms,所以一个周期也就是0.3333424ms,所以PWM的频率为2999Hz。占空比可以从波形中看出,大致相同。

二、设置的PWM周期为1MHz,占空比为0.4。调试结果如下:
在这里插入图片描述
在这里插入图片描述
从调试图中取得十个周期时间间隔为0.00676ms,所以一个周期也就是0.000676ms,所以PWM的频率为1.4MHz。占空比可以从波形中看出,大致相同。

二、设置的PWM周期为9MHz,占空比为0.4。调试结果如下:
在这里插入图片描述
在这里插入图片描述
从调试图中取得十个周期时间间隔为0.000833ms,所以一个周期也就是0.0000833ms,所以PWM的频率为12MHz。占空比可以从波形中看出,已经有些误差了。

总结

1、随着频率的增高,占空比的选取越来越不准。
这是由于捕获/比较寄存器1设定值=PWM占空比x72000000/PWM频率,而寄存器内的设定值只能为正数,随着PWM频率的升高,72000000/PWM频率就越来越小,而寄存器内的设定值只能为整数,所以导致了占空比的变化。
2、随着频率的增高,PWM的频率与设定间的误差在减少。

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值