打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
九九的STM32笔记(二)TIM模块产生PWM (www.ourdev.cn)
九九的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的吧!
 
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
STM32 PWM输出总结
STM32的PWM
STM32 高级定时器-PWM简单使用
stm32_定时器3控制PWM的输出脉冲_步进电机的控制
STM32高级定时器TIM1产生两路互补的PWM波(带死区)
stm32 TIM定时器 PWM脉冲输出[操作寄存器+库函数]-Changing's Blog
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服