1、TIMER输出PWM基本概念

        脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。

STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。

1.1   PWM输出模式

STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式)。模式1和模式2的区别如下:

:PWM模式1-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为有效电平,否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

:PWM模式2-在向上计数时,一旦TIMx_CNT<TIMx_CCR1时通道1为无效电平,否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CCR1时通道1为有效电平,否则为无效电平。

由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。

而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。

1.2   PWM输出管脚

PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如说TIM3的第2个通道,在没有重映像的时候,指定的管脚是PA.7,如果设置部分重映像之后,TIM3_CH2的输出就被映射到PB.5上了,如果设置了完全重映像的话,TIM3_CH2的输出就被映射到PC.7上了。

1.3   PWM输出信号

PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR预分频器所决定的,具体设置方法在前面一个学习笔记中有详细的交代。而输出信号的占空比则是由TIMx_CRRx寄存器确定的。其公式为“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通过向CRR中填入适当的数来输出自己所需的频率和占空比的方波信号。

2、TIMER输出PWM实现步骤

1.       设置RCC时钟;

2.       设置GPIO时钟;

3.       设置TIMx定时器的相关寄存器;

4.       设置TIMx定时器的PWM相关寄存器。

第1步设置RCC时钟已经在前文中给出了详细的代码,在此就不再多说了。需要注意的是通用定时器TIMx是由APB1提供时钟,而GPIO则是由APB2提供时钟。注意,如果需要对PWM的输出进行重映像的话,还需要开启引脚复用时钟AFIO。

第2步设置GPIO时钟时,GPIO模式应该设置为复用推挽输出GPIO_Mode_AF_PP,如果需要引脚重映像的话,则需要用GPIO_PinRemapConfig()函数进行设置。

第3步设置TIMx定时器的相关寄存器时,和前一篇学习笔记一样,设置好相关的TIMx的时钟和技术模式等等。具体设置参看“TIMER基本定时功能”的学习笔记。

第4步设置PWM相关寄存器,首先要设置PWM模式(默认情况下PWM是冻结的),然后设置占空比(根据前面所述公式进行计算),再设置输出比较极性:当设置为High时,输出信号不反相,当设置为Low时,输出信号反相之后再输出。最重要是是要使能TIMx的输出状态和使能TIMx的PWM输出使能。

相关设置完成之后,就可以通过TIM_Cmd()来打开TIMx定时器,从而得到PWM输出了。

3、TIMER输出PWM源代码

由于我现在手上的奋斗开发板是将PB.5接到LED上,因此需要使用TIM3的CH2通道,并且要进行引脚重映像。打开TIM3之后,PWM输出,使得LED点亮,通过改变PWM_cfg()中的占空比可以调节LED的亮度。

#include "stm32f10x_lib.h"

void RCC_cfg();

void GPIO_cfg();

void TIMER_cfg();

void PWM_cfg();

//占空比,取值范围为0-100

int dutyfactor = 50;

int main()

{

     int Temp;

       RCC_cfg();

       GPIO_cfg();

       TIMER_cfg();

       PWM_cfg(); 

       //使能TIM3计时器,开始输出PWM

       TIM_Cmd(TIM3, ENABLE); 

       while(1);

} 

void RCC_cfg()

{

       //定义错误状态变量

       ErrorStatus HSEStartUpStatus;   

       //将RCC寄存器重新设置为默认值

       RCC_DeInit(); 

       //打开外部高速时钟晶振

       RCC_HSEConfig(RCC_HSE_ON);

       //等待外部高速时钟晶振工作

       HSEStartUpStatus = RCC_WaitForHSEStartUp();

       if(HSEStartUpStatus == SUCCESS)

       {

              //设置AHB时钟(HCLK)为系统时钟

              RCC_HCLKConfig(RCC_SYSCLK_Div1);

              //设置高速AHB时钟(APB2)为HCLK时钟

              RCC_PCLK2Config(RCC_HCLK_Div1);

              //设置低速AHB时钟(APB1)为HCLK的2分频

              RCC_PCLK1Config(RCC_HCLK_Div2);           

              //设置FLASH代码延时

              FLASH_SetLatency(FLASH_Latency_2);

              //使能预取指缓存

              FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

              //设置PLL时钟,为HSE的9倍频 8MHz * 9 = 72MHz

              RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

              //使能PLL

              RCC_PLLCmd(ENABLE); 

              //等待PLL准备就绪

              while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

              //设置PLL为系统时钟源

              RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

              //判断PLL是否是系统时钟

              while(RCC_GetSYSCLKSource() != 0x08);

       } 

       //开启TIM3的时钟

       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

       //开启GPIOB的时钟和复用功能

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE); 

} 

void GPIO_cfg()

{

       GPIO_InitTypeDef GPIO_InitStructure;   

       //部分映射,将TIM3_CH2映射到PB5

//     GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

       GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

       //选择引脚5

       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

       //输出频率最大50MHz                                                        

       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

       //复用推挽输出                                              

      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

       GPIO_Init(GPIOB,&GPIO_InitStructure);

} 

void TIMER_cfg()

{

       TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

       //重新将Timer设置为缺省值

       TIM_DeInit(TIM3);

       //采用内部时钟给TIM3提供时钟源

       TIM_InternalClockConfig(TIM3);

       //预分频系数为0,即不进行预分频,此时TIMER的频率为72MHz

       TIM_TimeBaseStructure.TIM_Prescaler = 0;

       //设置时钟分割

       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

       //设置计数器模式为向上计数模式

       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

       //设置计数溢出大小,每计7200个数就产生一个更新事件,即PWM的输出频率为10kHz

       TIM_TimeBaseStructure.TIM_Period = 7200 - 1;

       //将配置应用到TIM3中

       TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

}

void PWM_cfg()

{

       TIM_OCInitTypeDef TimOCInitStructure;

       //设置缺省值

       TIM_OCStructInit(&TimOCInitStructure);

       //PWM模式1输出

       TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

       //设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100%

       TimOCInitStructure.TIM_Pulse = dutyfactor * 7200 / 100;

       //TIM输出比较极性高

       TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

       //使能输出状态

       TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

       //TIM3的CH2输出

       TIM_OC2Init(TIM3, &TimOCInitStructure);

       //设置TIM3的PWM输出为使能

       TIM_CtrlPWMOutputs(TIM3,ENABLE);

}

  

STM32(7)——通用定时器PWM输出的更多相关文章

  1. (五)转载:通用定时器PWM输出

    1.     TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有 ...

  2. STM32之通用定时器

    广大的互联网的大家早上中午晚上..又好..没错了..我又来了..写博客不是定时的..为什么我要提写博客不是定时的呢??聪明的人又猜到我要说什么了吧.有前途.其实我还是第一次听到定时器有通用和高级之分的 ...

  3. [stm32] STM32的通用定时器TIMx系统了解

    通用定时器(TIMx) 一.TIMx简介 二.TIMx主要功能 三.TIMx功能描述 3.1 时基单元 3.2 计数器模式 3.3 时钟选择 3.4 捕获/比较通道 3.5 输入捕获模式 3.6 PW ...

  4. stm32之通用定时器TIM

    STM32系列的CPU,有多达8个定时器: 1.其中TMI1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动:它们的时钟有APB2的输出产生: 2.其它6个为普通定时器,时钟由 ...

  5. Stm32之通用定时器复习

    因为毕业设计要用到PWM调光很久都没用到Stm32的定时器,有些内容已经遗忘,为了回顾复习相关内容今天开下通用定时器这一章节的数据手册. 1.时钟 通用定时器一般是TIM2~TIM5,TIM1.TIM ...

  6. NUCLEO-L053R8 TIM定时器 PWM输出

    TIM2 PWM输出测试 今天给大伙分享一个TIM2 PWM输出小实验. 实验开发板:Nucleo-L053R8,即STM32L053R8T6. 开发环境:MDK5 图1 - 工程界面 本次实验测试的 ...

  7. 一文打尽PWM协议、PPM协议、PCM协议、SBUS协议、XBUS协议、DSM协议 | STM32的通用定时器TIM3实现PPM信号输出

    PWM.PPM.PCM.SBUS.XBUS.DSM都是接收机与其他设备通信的协议. 请注意这里不要将遥控器和接收机之间的协议混淆.遥控器和接收机之间会采用某种协议来互相沟通,这些协议往往各个厂牌各自有 ...

  8. STM32F103ZET6 PWM输出

    1.通用定时器的PWM功能 STM32F103ZET6有4个通用定时器,分别是TIM2.TIM3.TIM4.TIM5. 通用定时器由一个可编程预分频器驱动的16位自动装载计数器构成. 通用定时器的很多 ...

  9. STM32 PWM输出(映射)

    STM32 的定时器除了 TIM6 和 7.其他的定时器都可以用来产生 PWM 输出.其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出.而通用定时器也能同时产生多达 4 ...

随机推荐

  1. 【java开发系列】—— java输入输出流

    前言 任何语言输入输出流都是很重要的部分,比如从一个文件读入内容,进行分析,或者输出到另一个文件等等,都需要文件流的操作.这里简单介绍下reader,wirter,inputstream,output ...

  2. ThinkPHP5.0更改框架的验证方法:对象->validate(true)->save();

    我们更希望看到: // 新增对象至数据表 $result = $Teacher->validate(true)->save(); 而不是: // 新增对象至数据表 $result = $T ...

  3. 使用Cloud application Studio在C4C UI里创建下拉列表(dropdown list)

    在Cloud Application Studio里新建一个Code List Data Type: 维护Value和描述信息,以及在ABSL里使用的constant值. 保存之后,上述维护的信息会存 ...

  4. 【洛谷5292】[HNOI2019] 校园旅行(思维DP)

    点此看题面 大致题意: 给你一张无向图,每个点权值为\(0\)或\(1\),多组询问两点之间是否存在一条回文路径. 暴力\(DP\) 首先,看到\(n\)如此之小(\(n\le5000\)),便容易想 ...

  5. HDU 1757 A Simple Math Problem 【矩阵经典7 构造矩阵递推式】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1757 A Simple Math Problem Time Limit: 3000/1000 MS (J ...

  6. Spring 的AOP底层实现技术:JDK和CGLIB动态代理

    Spring 的AOP实现技术之JDK的动态代理技术实例: 接口:IUserService (Spring的AOP是动态AOP,实现技术:JDK提供的动态代理和cglib代理,cglib它可以为没有实 ...

  7. SpringMVC学习记录六——异常定义和上传图片

    19       异常处理 19.1      异常处理思路 系统中异常包括两类:预期异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试 ...

  8. Android学习笔记_1_拨打电话

    1.首先需要在AndroidManifest.xml文件中加入拨打电话的权限,对应的配置文件: <?xml version="1.0" encoding="utf- ...

  9. Oracle数据库对象,同义词、序列、视图、索引

    数据库对象简介 Oracle 数据库对象又称模式对象 数据库对象是逻辑结构的集合,最基本的数据库对象是表 其他数据库对象包括: 同义词是现有对象的一个别名. 简化SQL语句 隐藏对象的名称和所有者 提 ...

  10. ASP.NET MVC中使用表单上传文件时的注意事项

    最近了好久没写ASP.NET 使用HTML的FORM来上传文件了,结果写了个文件上传发现ASP.NET MVC的Controller中老是读取不到上传的文件. MVC的View(Index.cshtm ...