九九的STM32笔记(二)TIM模块产生PWM |
回复数:10,点击数:2765 |
【楼主位】 jjldc 九九
 积分:1251 派别: 等级:------ 来自:宁波-武汉-深圳
|
这个是STM32的PWM输出模式,STM32的TIM1模块是增强型的定时器模块,天生就是为电机控制而生,可以产生3组6路PWM,同时每组2路PWM为互补,并可以带有死区,可以用来驱动H桥。 下面的代码,是利用TIM1模块的1、2通道产生一共4路PWM的代码例子,类似代码也可以参考ST的固件库中相应example C语言: TIM1模块产生PWM,带死区 //Step1.开启TIM和相应端口时钟 //启动GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | \ RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,\ ENABLE); //启动AFIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //启动TIM1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
//Step2. GPIO做相应设置,为AF输出 //PA.8/9口设置为TIM1的OC1输出口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);
//PB.13/14口设置为TIM1_CH1N和TIM1_CH2N输出口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure);
//Step3. TIM模块初始化 void TIM_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
//TIM1基本计数器设置(设置PWM频率) //频率=TIM1_CLK/(ARR+1) TIM_BaseInitStructure.TIM_Period = 1000-1; TIM_BaseInitStructure.TIM_Prescaler = 72-1; TIM_BaseInitStructure.TIM_ClockDivision = 0; TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_BaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure); //启用ARR的影子寄存器(直到产生更新事件才更改设置) TIM_ARRPreloadConfig(TIM1, ENABLE);
//TIM1_OC1模块设置(设置1通道占空比) TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_Pulse = 120; TIM_OC1Init(TIM1, &TIM_OCInitStructure); //启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置) TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
//TIM2_OC2模块设置(设置2通道占空比) TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 680; TIM_OC2Init(TIM1, &TIM_OCInitStructure); //启用CCR2寄存器的影子寄存器(直到产生更新事件才更改设置) TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //死区设置 TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF; TIM_BDTRInitStructure.TIM_DeadTime = 0x90; //这里调整死区大小0-0xff 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); //TIM1开启 TIM_Cmd(TIM1, ENABLE); //TIM1_OC通道输出PWM(一定要加) TIM_CtrlPWMOutputs(TIM1, ENABLE);
} 其实,PWM模块还可以有很多花样可以玩,比方在异常时(如CPU时钟有问题),可以紧急关闭输出,以免发生电路烧毁等严重事故。
我的博客中本文的地址,内有语法高亮的代码,方便阅读 |
|
2009-02-18,19:25:19 |
|
【1楼】 panxiaoku 积分:277 派别: 等级:------ 来自:
|
帮了大忙了,谢! |
|
2009-05-18,13:24:55 |
|
【2楼】 wendyfox 积分:95 派别: 等级:------ 来自:
|
可不可以搞个TIM3 4 的PWM啊?我搞了很久都没PWM出来。 |
|
2009-07-07,11:52:37 |
|
【3楼】 joyko 积分:175 派别: 等级:------ 来自:
|
我最近也在研究TIM这一块,你的刹车设置那里有点看不懂,TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; 这不是失能了刹车输入吗? |
|
2009-07-08,15:23:40 |
|
【4楼】 e_boys 积分:2 派别: 等级:------ 来自:
|
在吗???我试着用这你这个配置怎么没PWM输出呢?? |
|
2009-08-12,13:55:29 |
|
【5楼】 e_boys 积分:2 派别: 等级:------ 来自:
|
大侠们帮帮忙呀??? |
|
2009-08-12,13:55:54 |
|
【6楼】 zhikai_wu 积分:4 派别: 等级:------ 来自:
|
老大...你有没有测试过你的程序再放出来...很害人的啊... |
|
2009-08-15,00:39:22 |
|
【7楼】 zhikai_wu 积分:4 派别: 等级:------ 来自:
|
在V2.03里的原形: /* TIM Output Compare Init structure definition */ typedef struct { u16 TIM_OCMode; u16 TIM_OutputState; u16 TIM_OutputNState; u16 TIM_Pulse; u16 TIM_OCPolarity; u16 TIM_OCNPolarity; u16 TIM_OCIdleState; // 这个没设 u16 TIM_OCNIdleState; // 这个没设 } TIM_OCInitTypeDef;
加上
TIM_OCInitStructure.TIM1_OCIdleState = ?; // TIM_OCInitStructure.TIM1_OCNIdleState = ?; //
设置不完整少了这两句....不然没PWM输出.........
|
|
2009-08-15,00:46:05 |
|
【8楼】 deadiceboy 积分:34 派别: 等级:------ 来自:广州
|
mark |
|
2010-02-06,10:52:23 |
|
【9楼】 huchengxtu 费米机器 积分:90 派别: 等级:------ 来自:
|
//TIM1基本计数器设置(设置PWM频率) //频率=TIM1_CLK/(ARR+1) TIM_BaseInitStructure.TIM_Period = 1000-1; TIM_BaseInitStructure.TIM_Prescaler = 72-1; 请问这里的1000-1 和72-1 分别是装载计数和分频 不解的事为什么都要减1? 谢谢 |
|
2010-03-17,17:41:58 |
|
【10楼】 bingobravo 积分:9 派别: 等级:------ 来自:
|
回复【9楼】huchengxtu 费米机器 -----------------------------------------------------------------------
TIMx的计数器到时频率为TIMxCLK/(Prescaler+1),这里加1,前面初值自然要减1啊!
TIM_BaseInitStructure.TIM_Period是最大的计数值,考虑到从0开始故而减1的吧! |
|
|