原创 [转帖]STM32定时器应用之PWM输出

2014-8-14 10:29 2475 15 16 分类: MCU/ 嵌入式
1.1 TIM1_CH1N 与 TIM1_CH1 的区别
 
在刚准备使用定时器的时候,我看了下原理图,发现对于定时器1,它的每一个输出通道都是成对的,即TIM1_CH1N与TIM1_CH1两个一组,通过网络查询后,明白了芯片这样设计的原因。
 
TIM1是一个完整的电机控制用定时器外设,TIM1_CH1和TIM1_CH1N,用于驱动上下两个功率管。如果Deadtime为0,则 TIM1_CH1N是TIM1_CH1的反相,如果Deadtime不为0,则在TIM1_CH1N上插入了Deadtime,防止上下功率管同时导通。
 
另外的两类管脚定义:
 
TIM1_ETR是外部触发输入管脚;
 
TIM1_BKIN是故障信号,用来关闭TIM1的输出。
 
1.2 定时器的配置及 PWM 的设置 1.2.1 定时器相关结构体
 
从固件库里的教程CHM获取到的定时器相关的结构体。
 
TIM_BDTRInitTypeDef
 
BDTR structure definition
 
TIM_ICInitTypeDef
 
TIM Input Capture Init structure definition
 
TIM_OCInitTypeDef
 
TIM Output Compare Init structure definition
 
TIM_TimeBaseInitTypeDef
 
TIM Time Base Init structure definition
 
TIM_TypeDef
 
TIM
 
其中与PWM输出有关的结构体主要为:
 
TIM_TimeBaseInitTypeDef:定时器初始化配置结构体
 
TIM_OCInitTypeDef:定时器输出比较结构体
 
1.2.2 定时器的三个速度
 
在刚开始学习定时器的时候,我对定时器的速度、技术速度都很迷糊,通过前面对STM32时钟系统的学习,以及RCC库里面几个函数的学习,总算明白了,定时器的这三个速度。
 
TIMxCLK(定时器的工作频率):这个频率是我们在RCC里面配置APB1或APB2总线时的频率。
 
TIMx Counter Clock(定时器的计数频率):这个频率是定时器对ARR寄存器内的值进行加数或是减数的速度。
 
以前在做51单片机编程的时候,这两个频率往往是一致的。所以,刚开始对这两个频率的理解上还是有点疑惑的。
 
TIMx Running @(定时器的作用频率):这个频率表示定时器在这一次ARR寄存器开始累加或递减到下一次ARR寄存器重装所用的时间,这个频率可以理解为在以前的51单片机内我们定时器的定时周期。
 
对以上三个频率理解清楚后,再对定时器进行初始化的配置就很清晰了。
 
1.2.3 定时器的配置
 
定时器的配置代码      
 
// Compute the prescaler value /
 
       //TIM3CLK is 72 MHz
 
       //TIM3 Counter Clock is 24 MHz
 
       //TIM3 is running at 1 KHz
 
       PrescalerValue = (unsigned int) (72000000 / 36000000) - 1;
 
       PeriodValue = (unsigned int)( 36000000 / 1000 ) - 1;
 
三个频率的设置:定时器工作频率为72MHz,定时器计数频率36MHz,定时周期1KHz,通过这三个值,计算PrescalerValue 及PeriodValue的值。为后面的结构体配置做准备。
 
关于定时器的工作频率为72MHz,这是我在网上查到的一个小经验,我在DATASHEET中没有找到相关的说明,最后的PWM频率说明这个小经验是正确的。网上提到分给APB1的频率,即提供给TIM3的定时器的工作频率会自动倍频。
 
RCC_PCLK1Config(RCC_HCLK_Div2);//设置APB1时钟
 
我在前面配置给APB1的时钟是系统时钟二分频,即36MHz,而网上提到的倍频,即提供定时器的工作频率其实还是72MHz,最后证明TIM3工作频率的确是倍频了,对其他的定时器没有验证,我猜测挂载在APB1上的定时器都具有倍频的功能,即同样定时器的工作频率都经过了倍频。
 
// Time base configuration /
 
       TIM_TimeBaseStructure.TIM_Period = PeriodValue;
 
       TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
 
       TIM_TimeBaseStructure.TIM_ClockDivision = 0;
 
       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
 
       TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
 
       TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);            
 
TIM_Period及 TIM_Prescaler的值通过前面的计算已经确定。其中TIM_Prescaler是确定定时器技术频率,TIM_Period是确定定时周期的。
 
// PWM1 Mode configuration: Channel1 /
 
       CCR_Val =  (unsigned int)  (PeriodValue / 2 ) ;
 
       TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
 
       TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
 
       TIM_OCInitStructure.TIM_Pulse = CCR_Val;
 
       TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 
       //TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
 
       TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);//选择第二个通道输出
 
       TIM_OC2Init(TIM3, &TIM_OCInitStructure); //选择第二个通道输出
 
以上是输出比较结构体的配置,他最后决定了PWM的参数,PWM的频率即前面的定时器定时周期。而占空比是由TIM_Pulse确定的。其中占空比公式为:
 
DUTY  =  CCR寄存器的值  /  ARR寄存器的值
 
DUTY  =  TIM_OCInitStructure.TIM_Pulse  /  TIM_TimeBaseStructure.TIM_Prescaler-1
 
       //TIM3->CCER &= 0xEEEF;
 
       // TIM3 enable counter
 
       TIM_ARRPreloadConfig(TIM3, ENABLE);
 
       TIM_Cmd(TIM3, ENABLE);
 
       TIM_CtrlPWMOutputs(TIM3,ENABLE);
 
定时器的最后使能配置。至此,有关定时器相关的结构体的配置就结束了。在配置完GPIO后就可以输出PWM波了。实际上,程序流程上是先配置GPIO的,但我在学习PWM时,在GPIO上花费了大量的时间,也对GPIO理解更加深刻了。
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户402158 2014-8-14 17:51

谢谢分享
相关推荐阅读
小可歌 2016-05-31 13:54
【转帖】模拟电路的四重境界
无意中看到这个文章,虽然自己也搞了4 年模电了,但后看完之后发现自己原来根本就没有入门阿!现发上来和大家共享!·············   复旦攻读微电子专业模拟芯片设计方向研究生开始到...
小可歌 2016-05-28 07:14
发帖庆祝用app inventor的录音机保存MP3格式录音成功!
看似简单的功能,可是把我难够呛,刚学APP INVENTOR没几天,手里的两本书翻来掉去的看了N遍。APP INVENTOR的录音机默认是保存录音文件为3GP格式,我想保存成MP3文件就没有地方找...
小可歌 2016-02-22 08:56
C语言Printf格式,调试最好的助手!
    C中格式字符串的一般形式为: %[标志][输出最小宽度][.精度][长度]类型, 其中方括号[]中的项为...
小可歌 2016-02-19 15:19
对于SRAM的地址线和数据线是可以打乱顺序用的!!!!
因为SRAM的地址具有唯一性,其实数据线也有唯一性。 也就是A0~A18,D0~D15,都是唯一的。 正常是:A0~A18,接FSMC的A0~A18。 D0~D15,接FSMC的D0~D15. 假...
小可歌 2016-02-02 11:29
Linux系统下基本命令
Linux系统下基本命令: 要区分大小写  uname 显示版本信息(同win2K的 ver)  dir 显示当前目录文件,ls -al 显示包括隐藏文件(同win2K的 dir)  pwd...
小可歌 2016-02-02 11:28
DOS命令大全
对于一般的网民来说,dos命令是什么真的不知道,dos命令有些什么作用也不知道。但是黑客们却精通dos命令,经常利用dos命令进行各种任务,以达到自己的目的。下面笔者为大家汇总出dos命令大全,希...
我要评论
1
15
关闭 站长推荐上一条 /3 下一条