打印

STM32 PWM输出总结

[复制链接]
56607|117
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wzt19910506|  楼主 | 2012-7-25 17:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
       学习后发现stm32的定时器功能确实很强大,小总结一下方便以后使用的时候做参考。Stm32定时器一共分为三种:tim1tim8是高级定时器,67是基本定时器,25是通用定时器。从名字就可以看得出来主要功能上的差异。今天我主要是用定时器做pwm输出,所以总结也主要是针对pwm方面的。
       先大致说下通用和高级定时器的区别。通用的可以输出四路pwm信号互不影响。高级定时器可以输出三对互补pwm信号外加ch4通道,也就是一共七路。
所以这样算下来stm32一共可以生成4*5+7*2=30pwm信号。接下来还有功能上的区别:通用定时器的pwm信号比较简单,就是普通的调节占空比调节频率(别的不常用到的没去深究);高级定时器的还带有互补输出功能,同时互补信号可以插入死区,也可以使能刹车功能,从这些看来高级定时器的pwm天生就是用来控制电机的。

Pwm
输出最基本的调节就是频率和占空比。频率当然又和时钟信号扯上了关系。高级定时器是挂接到APB2上,而通用定时器是挂接到APB1上的。APB1APB2的区别就要在于时钟频率不同。APB2最高频率允许72MH,而APB1最高频率为36MHZ。这样是不是通用定时器只最高36MHZ频率呢,不是的;通用定时器时钟信号完整的路线应该是下面这样的:

AHB72mhz)→APB1分频器(默认2APB1时钟信号(36mhz)→倍频器(*2倍)→通用定时器时钟信号(72mhz)。
APB1和定时器中间的倍频器起到了巨大的作用,假如红色字体的“APB1分频器”假如不为1(默认是2),倍频器会自动将APB1时钟频率扩大2倍后作为定时器信号源,这个它内部自动控制的不用配置。设置这个倍频器的目的很简单就是在APB136mhz的情况下通用定时器的频率同样能达到72mhz。我用的库函数直接调用函数SystemInit(); 这个函数之后时钟配置好了:通用定时器和高级定时器的时钟现在都是72mhz(你也可以自己再配置一下RCC让他的频率更低,但是不能再高了)。定时器接下来还有一个分频寄存器:TIMX_PSC经过他的分频后,才是定时器计数的频率。所以真正的时钟频率应该是72mhz/(TIMX_PSC-1),我们设为tim_frepuency下面还会用到。
stm32的时钟频率弄得确实是很饶人的,所以关键就是先要把思路理清楚。时钟的频率弄好了下面终于可以开说重点PWM了。当然还少不了频率:pwm主要就是控制频率和占空比的:这两个因素分别通过两个寄存器控制:TIMX_ARRTIMX_CCRXARR寄存器就是自动重装寄存器,也就是计数器记到这个数以后清零再开始计,这样pwm的频率就是tim_frequency/TIMX_ARR-1)。在计数时会不停的和CCRX寄存器中的数据进行比较,如果小于的话是高电平或者低电平,计数值大于CCRX值的话电平极性反相。所以这也就控制了占空比。
评分
参与人数 1威望 +6 收起 理由
icecut + 6
沙发
wzt19910506|  楼主 | 2012-7-25 17:23 | 只看该作者
下面是定时器1的配置代码:
        GPIO_InitTypeDef GPIO_InitStructure2;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        TIM_OCInitTypeDef TIM_OCInitStructure;
        TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
        //第一步:配置时钟       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|
                                                   RCC_APB2Periph_GPIOB|RCC_APB2Periph_TIM1,ENABLE);
        //第二步,配置goio口
/********TIM1_CH1 引脚配置*********/       
        GPIO_InitStructure2.GPIO_Pin=GPIO_Pin_8;
        GPIO_InitStructure2.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure2.GPIO_Mode=GPIO_Mode_AF_PP;                 //设置为复用浮空输出
        GPIO_Init(GPIOA,&GPIO_InitStructure2);
        /*********TIM1_CH1N 引脚配置********/
        GPIO_InitStructure2.GPIO_Pin=GPIO_Pin_13;
        GPIO_InitStructure2.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure2.GPIO_Mode=GPIO_Mode_AF_PP;                 //设置为复用浮空输出
        GPIO_Init(GPIOB,&GPIO_InitStructure2);

        //第三步,定时器基本配置       
TIM_TimeBaseStructure.TIM_Period=1000-1;             // 自动重装载寄存器的值
        TIM_TimeBaseStructure.TIM_Prescaler=72-1;            // 时钟预分频数
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;    // 采样分频
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;//重复寄存器,用于自动更新pwm占空比                        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
       
//第四步pwm输出配置
        TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;                    //设置为pwm1输出模式
        TIM_OCInitStructure.TIM_Pulse=500;                                            //设置占空比时间
        TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;                 //设置输出极性
        TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;        //使能该通道输出
        //下面几个参数是高级定时器才会用到,通用定时器不用配置
        TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High;        //设置互补端输出极性
        TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable;//使能互补端输出
        TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;        //死区后输出状态
        TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Reset;//死区后互补端输出状态
        TIM_OC1Init(TIM1,&TIM_OCInitStructure);                                            //按照指定参数初始化


        //第五步,死区和刹车功能配置,高级定时器才有的,通用定时器不用配置
        TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable;//运行模式下输出选择
        TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;//空闲模式下输出选择
        TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;         //锁定设置
        TIM_BDTRInitStructure.TIM_DeadTime = 0x90;                                         //死区时间设置
        TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;                 //刹车功能使能
        TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;//刹车输入极性
        TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自动输出使能
        TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);       


//第六步,使能端的打开
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能TIMx在CCR1上的预装载寄存器
        TIM_ARRPreloadConfig(TIM1, ENABLE);                //使能TIMx在ARR上的预装载寄存器
        TIM_Cmd(TIM1,ENABLE);                                                           //打开TIM2
        //下面这句是高级定时器才有的,输出pwm必须打开
        TIM_CtrlPWMOutputs(TIM1, ENABLE);                                   //pwm输出使能,一定要记得打开

TIM_OC1PreloadConfig(),TIM_ARRPreloadConfig();这两个函数控制的是ccr1和arr的预装在使能,使能和失能的区别就是:使能的时候这两个局存期的读写需要等待有更新事件发生时才能被改变(比如计数溢出就是更新时间)。失能的时候可以直接进行读写而没有延迟。
另外在运行当中想要改变pwm的频率和占空比调用:TIM_SetAutoreload()
TIM_SetCompare1()这两个函数就可以了。

使用特权

评论回复
板凳
dabi| | 2012-7-26 16:12 | 只看该作者
不错的总结

使用特权

评论回复
地板
logokfu| | 2012-7-27 07:40 | 只看该作者
哎吆,不错吆

使用特权

评论回复
5
onlyrcy| | 2012-7-27 09:08 | 只看该作者
确实不错

使用特权

评论回复
6
wzt19910506|  楼主 | 2012-7-27 11:44 | 只看该作者
就是自己打字水平不行,出现很多错别字,纠正一下(红色部分):
TIM_OC1PreloadConfig(),TIM_ARRPreloadConfig();这两个函数控制的是ccr1和arr的预装在使能,使能和失能的区别就是:使能的时候这两个寄存器的读写需要等待有更新事件发生时才能被改变(比如计数溢出就是更新事件)。失能的时候可以直接进行读写而没有延迟。
另外在运行当中想要改变pwm的频率和占空比调用:TIM_SetAutoreload()
TIM_SetCompare1()这两个函数就可以了。

使用特权

评论回复
7
wgsxsm| | 2012-7-28 16:59 | 只看该作者
mark一下

使用特权

评论回复
8
qiurenguo| | 2012-7-29 21:30 | 只看该作者
学习了,谢谢

使用特权

评论回复
9
baidudz| | 2012-7-29 21:32 | 只看该作者
总结的条理性有点欠缺,不过还是鼓励共享

使用特权

评论回复
10
秋天落叶| | 2012-7-29 21:40 | 只看该作者
就是自己打字水平不行,出现很多错别字,纠正一下(红色部分):
TIM_OC1PreloadConfig(),TIM_ARRPreloadConfig();这两个函数控制的是ccr1和arr的预装在使能,使能和失能的区别就是:使能的时候这两个寄存器的读写需 ...
wzt19910506 发表于 2012-7-27 11:44

小结写的已经很不错了,值得鼓励

使用特权

评论回复
11
pkat| | 2012-7-29 21:49 | 只看该作者
总结的排版好像有问题,间隔太小,看的眼睛好累

使用特权

评论回复
12
逆序排列| | 2012-9-24 14:41 | 只看该作者
有验证过吗?怎么不行?TIM1_CH1N没有输出;

使用特权

评论回复
13
逆序排列| | 2012-9-24 14:42 | 只看该作者
我现在也在弄TIM1的PWM,TIM1_CH1已经有输出了,TIM1_CH1N始终没有输出;

使用特权

评论回复
14
ETjason| | 2012-9-24 22:54 | 只看该作者
总结的不错,很受益,谢谢!

使用特权

评论回复
15
秋天落叶| | 2012-9-24 23:07 | 只看该作者
提倡多写小结,方便自己整理思路,大家学习

使用特权

评论回复
16
无冕之王| | 2012-9-24 23:19 | 只看该作者
总结的还不错

使用特权

评论回复
17
gxgclg| | 2012-9-24 23:29 | 只看该作者
写的还不错,需要再整理一下

使用特权

评论回复
18
riptell| | 2012-9-25 07:58 | 只看该作者
good,学习了!!

使用特权

评论回复
19
leijiayou| | 2012-9-25 08:43 | 只看该作者
:)不错。。。  谢谢LZ

使用特权

评论回复
20
HEYsir| | 2012-10-13 12:40 | 只看该作者
刚刚开始学习定时器,学习了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

134

帖子

8

粉丝