新闻中心

EEPW首页>嵌入式系统>设计应用> STM32单片机学习---PWM输出

STM32单片机学习---PWM输出

作者: 时间:2016-11-27 来源:网络 收藏
上午花了半天时间熟悉了stm32的PWM模块。中午利用午饭时间把PWM功能调试成功。当然,很简单的东西,也许很多前辈估计都不屑一顾的东西。

今天最大的感叹就是网络资源实在是个巨大的宝库,真的很庆幸,在这个复杂的社会环境里,在一个到处充斥着私心、私利的时代,各个网站,各个论坛上的众多网友都时刻保持着开源的氛围。学习一定要和他人交流,而网络提供了这么一个极好的平台。

本文引用地址://m.amcfsurvey.com/article/201611/322220.htm

废话少说,言归正传。

实现功能:采用定时器2的通道2,使PA1输出频率1K,占空比40的PWM波形,用PA8随意延时取反led灯,指示程序运行。

首先熟悉一下定时器的PWM相关部分。看图最明白

其实PWM就是定时器的一个比较功能而已。

CNT里的值不断++,一旦加到与CCRX寄存器值相等,那么就产生相应的动作。这点和AVR单片机很类似。既然这样,我们要产生需要的PWM信号,就需要设定PWM的频率和PWM的占空比。

首先说频率的确定。由于通用定时器的时钟来源是PCLK1,而我又喜欢用固件库的默认设置,那么定时器的时钟频率就这样来确定了,如下:

AHB(72MHz)→APB1分频器(默认2)→APB1时钟信号(36MHz)→倍频器(*2倍)→通用定时器时钟信号(72MHz)。

这里为什么是这样,在RCC模块学习记录里有详细记载,不多说。

因此图中的CK_PSC就是72MHz了。

下面的资料也是网上一搜一大把,我就罗列了:

STM32的PWM输出有两种模式,模式1(PWM1)和模式2(PWM2),由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下:

110:PWM模式1-在向上计数时,一旦TIMx_CNT=TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

111:PWM模式2-在向上计数时,一旦TIMx_CNT=TIMx_CCR1时通道1为有效电平,否则为无效电平。

由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。我用的是模式一,因此后面的设定都是按照模式一来设定的。

PWM的周期是就是由定时器的自动重装值和CNT计数频率决定的。而CNT的计数时钟是CK_PSC经分频器PSC得到,因此CNT的时钟就是CK_PSC/分频系数。这个分频系数在TIM_TimeBaseStructure.TIM_Prescaler确定。我设置的值是72,因此CNT的计数频率也就是CK_CNT的频率为1MHz。

下一步就是确定定时器自动重装值。因为CNT每自加到ARR寄存器的值时就会自动清零,当然前提是设定为为向上计数模式,而就是根据这个溢出事件来改变PWM的周期。所以PWM信号的频率由ARR的值来确定。我设置的值是1000-1,即TIM_TimeBaseStructure.TIM_Period = 1000-1;因此PWM的周期是1MHz/1000=1KHz。

接下来就要确定PWM的占空比了。因为CNT在自加到ARR值的过程中会不断和CRRX的值相比较,一旦二者相等就产生匹配事件,但要注意CNT不会理会这件事,它会继续++直到等于ARR。而CRRX的值我设定为400-1,那么占空比就随之确定为40%。

好了,下面就是库函数的配置了。

TIMER输出PWM实现步骤

1.设置RCC时钟;

2.设置GPIO;

3.设置TIMx定时器的相关寄存器;

4.设置TIMx定时器的PWM相关寄存器。

首先是main函数和全局变量申明,很简单,不作说明


GPIO_InitTypeDef GPIO_InitStructure;

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_OCInitTypeDef TimOCInitStructure;

int main(void)
{

rcc_cfg();
gpio_cfg();
tim2_cfg();
pwm_cfg();
//
while (1)
{

GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_SET);

delay();


GPIO_WriteBit(GPIOA, GPIO_Pin_8, Bit_RESET);

delay();
}
}

下面是IO口的配置:

void gpio_cfg()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}

此处要注意的是PWM输出口要配置为复用推挽输出,原因我也不知道,反正照搬就是了。


上一页 1 2 下一页

关键词:STM32单片机PWM输

评论


技术专区

关闭