你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

查看: 1131|回复: 0

【MCU实战经验】+stm32之pwm浅谈

[复制链接]

28

主题

143

回帖

3

蝴蝶豆

中级会员

最后登录
2018-7-31
发表于 2014-4-10 13:05:43 | 显示全部楼层 |阅读模式
 STM32的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出!这里我们仅利用TIM3的CH2产生一路PWM输出。
       要使STM32的通用定时器TIMx产生PWM输出,我们会用到3个寄存器,来控制PWM的。这三个寄存器分别是:捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。(注意,还有个TIMx的ARR寄存器是用来控制pwm的输出频率)
首先是捕获/比较模式寄存器(TIMx_CCMR1/2),该寄存器总共有2个,TIMx _CCMR1和TIMx _CCMR2。TIMx_CCMR1控制CH1和2,而TIMx_CCMR2控制CH3和4。
 
其次是捕获/比较使能寄存器(TIMx_CCER),该寄存器控制着各个输入输出通道的开关。
 
最后是捕获/比较寄存器(TIMx_CCR1~4),该寄存器总共有4个,对应4个输通道CH1~4。4个寄存器都差不多,说的简单一点,这个寄存器就是用来设置pwm的占空比的。
 
(具体的各个寄存器的各个位,详见stm芯片手册。)
 
  上面提到的,TIMx_ARR寄存器是用来设置pwm的频率的,那么它的原理是怎样的呢?
 
 
 
 
 
     对于我们这些初学 的菜鸟,有一个非常好的消息就是stm32给我们提供了一套库函数,这可比直接操作寄存器简单多了。下面是我们的pwm配置函数
 
    void PWM_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
 
TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;
 
/* GPIOB clock enable */
//GPIOB使用的RCC时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
//配置使用的GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_PP;//;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 100-1;//1000; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 80K
 
(._Period这个即是设置TIMx_ARR的值,即用来设置pwm的频率)
TIM_TimeBaseStructure.TIM_Prescaler =0; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
/* Output Compare Active Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值,设置占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OC3Init(TIM4, &TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //使能TIMx在CCR3上的预装载寄存器
 
TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在ARR上的预装载寄存器
/* TIM4 enable counter */
 TIM_Cmd(TIM4, ENABLE); //使能TIMx外设
}
 
 各个函数的使用,详见stm32固件库的使用。
 
   那么TIMx_ARR寄存器的值是怎样来确定pwm的频率的呢?TIM_Period(即是TIMx_ARR寄存器的值) 的大小实际上表示的是需要经
过TIM_Period 次计数后才会发生一次更新或中断。接下来需要设置时钟预分频
数TIM_Prescaler,这里有一个公式,我们举例来说明:例如时钟频率=72MHZ/(时
钟预分频+1)。(假设72MHZ为系统运行的频率,这里的时钟频率即是产生这个pwm的时钟的频率)说明当前设置的这个TIM_Prescaler,直接决定定时器的时钟频率。
通俗点说,就是一秒钟能计数多少次。比如算出来的时钟频率是2000,也就是
一秒钟会计数2000 次,而此时如果TIM_Period 设置为4000,即4000 次计数后就会中断一次。由于时钟频率是一秒钟计数2000 次,因此只要2 秒钟,就会中
断一次。
还有一个需要注意的,就是我们一般采用向上计数模式。
好了,累了,就写到这儿!!!
回复

使用道具 举报

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版