PWM、、英语好的人估计又知道这三个大写字母代表哪三个英语单词了、小弟不才,就说中文意思好了:脉冲宽度调制,玩过飞思卡尔的人估计对PWM非常的不陌生吧、电机驱动需要PWM,控制舵机的转向需要PWM,总之、可以说,PWM,you are so good。

好了、、言归正传,广大的互联网的网友们,咱们又见面了,大家早上晚上中午好好好、额、、好像也没见过面,STM32的PWM,可谓是小强中的小强,STM32的PWM,就是由定时器产生的,但是奇怪的是除了定时器TIM6和TIM7不能产生PWM外,其他的定时器都可以产生,而且还有多路之分,“高级官员”TIM1和TIM8说:老子可以产生多达7路,而其他的定时器默默的哀伤,因为自己最多只能产生4路(四个通道)。

上篇博客介绍了几位寄存器大神(http://www.cnblogs.com/alvis-jing/p/3691901.html),请把他们的脚步继续留下,因为还需用到,如不肯留,给他们最残酷的惩罚:金钱美女伺候、好了,言归正传,接下来,为了诞生PWM,我们还将有请以下的几位寄存器大神(由于大神们都比较低调,在此就不隆重介绍了,大家有兴趣的找下“葵花兄”)

注:对于寄存器,本博客就不再深入的讲解,大家也可以参照STM32的参考手册,因为本博客讲解的是思路和用库函数,所以就不再细讲寄存器,请见谅

1、捕获/比较模式寄存器1(TIMx_CCMR1)

2、捕获/比较使能寄存器(TIMx_CCER)

3、捕获/比较寄存器2(TIMx_CCR2)

那好,我们该怎么利用定时器来产生PWM呢??再此之前,我们来了解产生PWM的背后那不为人知的秘密:

脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。

在TIMx_CCMRx寄存器中的OCxM位写入’110’(PWM模式1)或’111’(PWM模式2),能够独立地设置每个OCx输出通道产生一路PWM。必须设置TIMx_CCMRx寄存器OCxPE位以使能相应的预装载寄存器,(请注意这句话!!!!)最后还要设置TIMx_CR1寄存器的ARPE位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。

在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始终在进行比较,(依据计数器的计数方向)以确定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。

所以,该寄存器的值一直与CNT比较,根据比较结果产生相应的动作,利用这里一点,我们通过修改这个寄存器的值,就可以控制PWM的输出脉宽了,(在这里有专门的库函数可以操作,所以是相当方便)

那怎么操作呢??在这里,我们通过一直没有提过的非常重要的概念:重映射,把TIM3_CH2的PA7重映射到PB5,而PB5是连接LED的,所以我们可以通过观察LED的亮度才体验PWM、、也难为了LED君,老是被观察,脸也不红下、、

所谓的重映射,就是把原本默认的引脚给诱惑到另一个引脚上,专业上给的是重映射,但是我觉得并非这么简单、果然,它还有一个功能:复用、、所以第一步:

我们要打开复用的时钟和把IO口设成复用推挽输出,当然也要打开TIM3的时钟,见代码:(映射有部分映射和全部映射,都有可用的函数,在这里我们是部分映射,但是,映射了一个引脚,另外的引脚也被牵扯下来了,哎)

            注意红色代码
1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);

接下来: 通用计时器的初始化:(由于上篇博客已讲解,在这就不细讲了哈,请见谅哈http://www.cnblogs.com/alvis-jing/p/3691901.html)请看代码:

            TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc;
TIM_TimeBaseStructure.TIM_ClockDivision = ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);

接下来,就是PWM的重头戏了,在这里,我们要设置TIM3_CH2为PWM模式,(注意,由于TIM3可以产生四路PWM,每路都有不同的但类似的函数来控制)在这里,我们是通过

void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct)来实现的

打开"stm32f10x_tim.h"可以看到,在这里,我们只显示一些跟我们有用的参数:

TIM_OCMode输出模式;—>PWM2

TIM_OutputState输出使能;—>使能PWM

TIM_OCPolarity输出极性;—>极性为高           代码如下:

1          TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);

接下来,最关键的一步也是最容易遗漏的:就是使能预装载寄存器,在这里我们通过库函数

TIM_OC2PreloadConfig     使能或者失能TIMx在CCR2上的预装载寄存器   请看代码:

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);    

好了,最后一步,我们开启定时器TIM3,这个大家也不陌生了吧、、还是老规矩;知道的,来人,赏美女十个,还不知道的,拉出去调戏十分钟

 /* Enables the TIM3 counter */
TIM_Cmd(TIM3, ENABLE);

亲、、在这里、、你觉得你能看到LED从暗到亮了吗??你想看,LED君还不肯呢、没错了、、但这是为什么呢??

原因就是这里设置产生的PWN是固定脉宽的、、那我们怎么来改变它呢??咦、库函数为我们提供了这样的一个好机会:

TIM_SetCompare2   设置TIMx捕获比较2寄存器值

通过这个函数我们就可以设置脉冲宽度,从而控制PWM了、、代码如下:

  TIM_SetCompare2(TIM3, temp);

好了,我们来总结下步骤:

1、开启TIM3定时器的时钟,如果有复用,也要打开复用的时钟。

2、初始化TIM3

3、设置TIM3_CH2的PWM模式,并使能其输出(注:要使能预装载寄存器)

4、开启TIM3

5、改变脉冲宽度,从而改变PWM

少了一些自认为是幽默风趣的语言、、为了是让自己不再显得那么吊儿郎当、、这篇博客在这又到了尾声、、本人也在学习阶段、、尽量把自己当成读者,让读者看得懂、、有写错之处望指出来、不胜感激、、希望能对你有理解上的帮助、、

STM32之PWM君的更多相关文章

  1. STM32之PWM波形输出配置总结

    一.   TIMER分类: STM32中一共有11个定时器,其中TIM6.TIM7是基本定时器:TIM2.TIM3.TIM4.TIM5是通用定时器:TIM1和TIM8是高级定时器,以及2个看门狗定时器 ...

  2. stm32之PWM

    PWM是pulse width modulation的缩写,即脉冲宽度调制.其通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形: 1.PWM是一种对模拟信号电平进行数字编码的方法.通过高分辨率计 ...

  3. 【转载】 stm32之PWM

    发现这位博主的博客被大量的转发,我也转载一篇,谁叫人家写的好呢. 原文地址:http://blog.sina.com.cn/s/blog_49cb42490100s6uh.html 脉冲宽度调制(PW ...

  4. 【STM32】PWM DAC基本原理(实验:PWM实现DAC)

    虽然STM32F103ZET6具有内部DAC,但是也仅仅只有两条DAC通道,并且STM32还有其他的很多型号是没有DAC的.通常情况下,采用专用的D/A芯片来实现,但是这样就会带来成本的增加. 不过S ...

  5. STM32的PWM输入模式设置并用DMA接收数据

    参考 :STM32输入捕获模式设置并用DMA接收数据 PWM input mode This mode is a particular case of input capture mode. The ...

  6. stm32之PWM博客好文收藏

    https://www.cnblogs.com/jiwangbujiu/p/5616376.html STM32F103 使用TIM3产生四路PWM https://www.cnblogs.com/c ...

  7. stm32之PWM学习

    下图是一个STM32普通PWM形成的图形原理说明 自动重装载寄存器(ARR)用于确定波形的频率(即周期).捕获比较寄存器(CCRx)(用于确定占空比的) PWM的工作过程如下:首先ARR寄存器里面的值 ...

  8. 关于STM32 定时器 PWM 实时调节占空比时,预装载特性

    最近在调试项目的时候遇到一个奇怪的现象:在调试状态下,给定时器捕获比较寄存器赋不同值,能产生不同占空比的波形(图1).反映到器件上也有不同的电压显示,但是在设备运行的时候,就不行了(图2). 图1 图 ...

  9. STM32基础分析——PWM配置

    在使用STM32F103产生固定频率.固定占空比的PWM波时,虽然有官方以及众多开发板提供的例程,但是关于有点问题并没有说的很清晰,并且<STM32F10X参考手册>的中文翻译可能容易造成 ...

随机推荐

  1. Python全栈开发【基础三】

    Python全栈开发[基础三]  本节内容: 函数(全局与局部变量) 递归 内置函数 函数 一.定义和使用 函数最重要的是减少代码的重用性和增强代码可读性 def 函数名(参数): ... 函数体 . ...

  2. mysql主从复制实现数据库同步

    mysql主从复制相信已经用得很多了,但是由于工作原因一直没怎么用过.趁着这段时间相对空闲,也就自己实现一遍.尽管互联网上已有大把类似的文章,但是自身实现的仍然值得记录. 环境: 主服务器:cento ...

  3. 448. Find All Numbers Disappeared in an Array

    https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/ 给出一列数,1 ≤ a[i] ≤ n,n是数组大小,有些 ...

  4. java内存溢出和内存泄露

    虽然jvm可以通过GC自动回收无用的内存,但是代码不好的话仍然存在内存溢出的风险. 最近在网上搜集了一些资料,现整理如下: —————————————————————————————————————— ...

  5. OpenLayers.2.10.Beginners.Guide---第一章

    从网上下载openlayers2,解压取得img theme 文件夹和openlayes.js文件.放在同一文件夹下用phpstorm打开. 创建index.html-------------每一行都 ...

  6. [Android Pro] 完美Android Cursor使用例子(Android数据库操作)

    reference to : http://www.ablanxue.com/prone_10575_1.html 完美 Android Cursor使用例子(Android数据库操作),Androi ...

  7. 【转】arm 开发工具比较(ADS vs RealviewMDK vs RVDS)

      ADS REALVIEW MDK RVDS 公司 ARM Keil(后被ARM收购) ARM 版本 最新1.2 ,被RVDS取代 最新4.0 是否免费 破解情况 有 有 工程管理 CodeWarr ...

  8. python的异常处理

    在所有的程序中,都会遇到异常,有些异常是代码编写的时候产生的,在前期过程中可能会直接导致程序无法运行.这一类的异常,在编写代码的时候,程序可以直接排查修改.但有些异常,是在程序运行过程中产生的,可能是 ...

  9. android面试宝典

    一.listview的优化: 首先要知道getview实际就是个for循环. 我们重写的getview方法中本身有一个convertview,因为只需要保留能够显示的最大个数的view即可,所以: 第 ...

  10. 技术杂记-改造具有监控功能的数据库连接池阿里Druid,支持simple-jndi,kettle

    kettle内置的jndi管理是simple-jndi,功能确实比较简单,我需要监控kettle性能,druid确实是很不错的选择,但没有提供对应的支持,我改进了druid源码,实现了simple-j ...