您的位置:首页 > 其它

STM32神舟III号 驱动直流电机学习(二)

2014-11-06 16:49 281 查看
看到一篇讲pwm讲得比较详细的STM32的PWM精讲http://wenku.baidu.com/view/edcde519227916888486d710.html

原文地址:http://cache.baiducontent.com/c?m=9d78d513d98207f059edc07d0f179f310

实验内容:利用STM32的一个通用定时器(TIM2)产生4路频率相同(1KHz)占空比不同的PWM。Ch1占空比75%,Ch2占空比50%,Ch3占空比25%,Ch4占空比10%。四路输出分别对应PA端口的PA0,PA1,PA2,PA3。

实验目的:掌握通用定时器的基本应用。(PWM的频率和占空比的计算)

STM32的定时器是个强大的模块,定时器使用的频率也是很高的,定时器可以做一些基本的定时,还可以做PWM输出或者输入捕获功能。

补充一个前期时钟源问题:

名为TIMx的定时器有8个,其中TIM1和TIM8挂在APB2总线上,而TIM2-TIM7则挂在APB1总线上。其中TIM1&TIM8称为高级控制定时器. APB2可以工作在72MHz下,而APB1最大是36MHz。

定时器的时钟不是直接来自APB1或APB2,而是来自于输入为APB1或APB2的一个倍频器。(这个问题纳闷了好久才找到的,主要是没有在意时钟树,唉!)



下面以定时器2~7的时钟说明这个倍频器的作用:当APB1的预分频系数为1时,这个倍频器不起作用,定时器的时钟频率等于APB1的频率;当APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起作用,定时器的时钟频率等于APB1的频率两倍。

假定AHB=36MHz,因为APB1允许的最大频率为36MHz,所以APB1的预分频系数可以取任意数值;当预分频系数=1时,APB1=36MHz,TIM2~7的时钟频率=36MHz(倍频器不起作用);当预分频系数=2时,APB1=18MHz,在倍频器的作用下,TIM2~7的时钟频率=36MHz。

有人会问,既然需要TIM2~7的时钟频率=36MHz,为什么不直接取APB1的预分频系数=1?答案是:APB1不但要为TIM2~7提供时钟,而且还要为其它外设提供时钟;设置这个倍频器可以在保证其它外设使用较低时钟频率时,TIM2~7仍能得到较高的时钟频率。

再举个例子:当AHB=72MHz时,APB1的预分频系数必须大于2,因为APB1的最大频率只能为36MHz。如果APB1的预分频系数=2,则因为这个倍频器,TIM2~7仍然能够得到72MHz的时钟频率。能够使用更高的时钟频率,无疑提高了定时器的分辨率,这也正是设计这个倍频器的初衷。

一下是定时器的配置代码:

/*使用一个定时器产生4路不同占空比的PWM波型
*/

void Timer_Init(void)

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //打开定时器时钟

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

//定时器2 设置 360分频 1KHz 向上计数

TIM_TimeBaseStructure.TIM_Period =199; //1KHz,16位的值,最大65536

TIM_TimeBaseStructure.TIM_Prescaler =359; //360分频 即为200KHz,16位的值,最大65536

TIM_TimeBaseStructure.TIM_ClockDivision =0x00; //时钟分频系数,不分频

TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器

TIM_OCInitTypeDef TIM_OCInitStructure;

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
//主定时器TIM2为PWM1模式

TIM_OCInitStructure.TIM_OutputState =TIM_OutputState_Enable;//使能输出比较状态

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

//ch1 配置项

TIM_OCInitStructure.TIM_Pulse = 150;

TIM_OC1Init(TIM2, & TIM_OCInitStructure); //ch1占空比75%

TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能的预装载寄存器

//ch2 配置项

TIM_OCInitStructure.TIM_Pulse = 100;

TIM_OC2Init(TIM2, & TIM_OCInitStructure); //ch2占空比50%

TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能的预装载寄存器

//ch3 配置项

TIM_OCInitStructure.TIM_Pulse = 25;

TIM_OC3Init(TIM2, & TIM_OCInitStructure); //ch3占空比25%

TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能的预装载寄存器

//ch4 配置项

TIM_OCInitStructure.TIM_Pulse = 10;

TIM_OC4Init(TIM2, & TIM_OCInitStructure); //ch4占空比10%

TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能的预装载寄存器

TIM_ARRPreloadConfig(TIM2,ENABLE); //使能TIM2在ARR上的预装载寄存器

TIM_ITConfig(TIM2,TIM_IT_CC1,ENABLE); //开定时器中断

TIM_CtrlPWMOutputs(TIM2,ENABLE); //使能TIM2的外设的主输出

TIM_Cmd(TIM2,ENABLE); //使能定时器2

}

一下说一下PWM频率的计算问题:

分频值=TIM_TimeBaseStructure.TIM_Prescaler +1,所以如果要分360分频,只要将TIM_Prescaler=359即可。

//定时器2 设置 360分频 1KHz 向上计数

TIM_TimeBaseStructure.TIM_Period =199; //1KHz,16位的值,最大65536

TIM_TimeBaseStructure.TIM_Prescaler =359; //360分频 即为200KHz,16位的值,最大65536

PWM频率(1KHz)=TIM2时钟/(
TIM_Prescaler+1)*(TIM_Period+1);所以:TIM2时钟=72M;TIM_Period =199; TIM_Prescaler =359。

效果图:

通道1、2



通道3、4



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐