当前课程知识点:ARM微控制器与嵌入式系统 > 第五章 ARM微控制器的各种外设 > 5.5.1 ARM微控制器外设:PWM的原理 > 5.5.1 ARM微控制器外设:PWM的原理
各位同学大家好
我是清华大学工程物理系的曾鸣老师
欢迎大家继续回到
我们ARM微控制器与嵌入式系统的MOOC课堂
那么我们继续进行我们第五章关于外设的学习
在前面几个单元里呢
我们学习了各种各样的外设
特别在上一个单元
我们学习了最最简单的一类时钟
SysTick
它是由ARM公司定义的ARM内核里
通用的一类时钟模块
我们也做了一个小小的实验在中断模式下
用它来点我们的灯
建立了一些对于时钟的初步概念
那么在这个单元里呢
我们要学习一类比那个更强大
更完善的一类关于时钟的外设
但是在这个单元的学习里头
我们不再把它当做一个时钟来学习
而是借这个机会去学习一类新的功能
那么我们把它称为脉冲调制模块
脉冲调制模块在绝大多数的嵌入式系统
也就微控制器里头都是有的
我们通常会把它称为PWM
那么PWM是Pulse-Width Modulation的缩写
也就是顾名思义的脉宽调制
那么我们经常会使用的是一些数字型号
在逻辑0和逻辑1之间进行跳变
也就是我们大家都有这样一种概念
会形成一个个的方波
但是当我们对这些方波进行一些调制的时候
我们可以产生一些周期信号
就像这张图所示
他们根据两个这个唯一的时间的变化的
这个时间间隔会有不同的频率
那么他可以调整的这个参数呢
就既包括这个频率
也包括在一个时钟周期里为1和为0的
这个时间长短的差异
所以我们会有一个概念
经常在学数字电路会学到叫做占空比
也就在一个时钟周期里
有多长的百分比的时间是逻辑1
它跟这个总周期的比例就是我们的占空比
所以如另外一张图所示
我们可以看到从占空比为1%、5%、10%
乃至到90%的同样频率的信号
它在这个
画在一起时钟沿上是这样一种感觉
所以我们会建立一种模糊的概念
也就是说对于这样一种信号
它实际上是在幅度的维度上
锁定成了逻辑0和逻辑1
但是在他自身的频率上
这个频率是可以变的
而它的占空比
也就是为1和整个周期的这个比例
也是可以连续调整的
所以它可以成为一类最最简单的数模变化电路
我们换一个角度用一种更简单的语言来说
我们调整一个周期里为1的这个时间长短
占的比例的不同
使我们整个这个信号的平均的电压值
可以发生连续的调整和变化
所以这样一类的脉冲调制模块
既可以通过时间上的特性
就是周期频率以及占空比
来实现一些时序的控制
也可以通过平均幅度上的特性
来实现一些模拟上的控制
所以在我们的微控制器里头
就像我们刚才所说
绝大多数嵌入式系统微控制器
都有这样一个模块
我们可以把它用起来做很多很多不同的应用
那么这样一类外设
在我们所学习的KL25这样一个
ARMCortexM0的微控制器里头呢
它放在了一个统一的外设
就是刚才最最开始所讲的
首先它是一个Timer
为什么是Timer 待会会讲
然后又是一个PWM
所以合起来叫Timer and PWM Module
所以在我们这一类外设
在我们所用这个芯片里头简称为TPM模块
那么如果大家有兴趣学习呢
可以翻到我们芯片手册的第31章
也就第547页可以找到相关的信息
那么我们知道了什么是PWM
就是产生一个周期占空比可变的信号
我们就可以知道
它其实像曾老师刚才所说的
可以有很多很多的应用
比如我们看到的应用里头
我们可以通过一个滤波电路加上跟随的驱动
把它作为最最简单的一类数模变换电路
产生我们所想要的模拟电压值
那么我们在后面的实验里也会涉及到
我们可以通过一个简单的晶体管驱动电路
来驱动一个发音的这个扬声器
产生不同频率的声音得到电子音乐
那么我们也可以通过一个电阻
类似于数模变换电路的思想
通过一个晶体管的驱动门
来控制一个真正的灯
让这个灯的亮度可以连续的可调发生变化
那么还有一类大家做机器人啊
做智能车经常会用到的
我们对于直流伺服电机
我们可以用一对反向的时钟信号
来控制一个电机的转动和驱动
那么这一系列的功能
在我们学习了PWM模块以后
都可以学会进行使用
我们来看看它的原理
和我们待会要学习它怎么来进行编程
那么PWM模块就像我们所说
它是一个高级一点的
功能复杂一点的时钟来触发的
所以它的内部结构非常非常的好理解
其实就是Timer
我们都知道Timer
上一节课 上上个单元给大家学过
它是一个累加的计数器
Timer是对一定频率进行counter
进行计数的模块形成了一个定时
定时的本质就是对固定的时间间隔
进行数数对吧
那么我们要产生PWM信号的时候
就跟这个Regulated的Timer是非常类似的
我们在一个固定频率下进行累加的计数
我们通过一个Count的寄存器的结构
来存当前的计数值
在一个时钟的频率下
让它不断的累加或者累减
大多数是累加
那么我们应该至少要有个寄存器
来控制这个计数器计到多少值应该归零对吧
这我们在Timer里学过
那么这个寄存器存的这个参考的归零的值呢
构成了我们的这个信号的周期
那么作为PWM的时候呢
就是在这Timer基础上还要再多一个寄存器
当计数值计到这个寄存器
所存的设定值的时候呢
使我们的引脚上的输出信号发生一次翻转
于是当计时开始的时候
引脚上的信号由0变1
那么计到第一个计数值的时候
引脚上的信号由1变0
计到周期那个计数值的时候
一个周期完成
周而复始
计数器的值归0
引脚上的值再从此由逻辑0变成逻辑1
这样周而复始
我们就得到了固定频率
固定占空比的脉冲宽度的调制信号
这就是它的一个基本原理
那么如果我们站在这样一个原理
已经清楚的视角来看一看
我们要把这样一个PWM模块给用起来
或者说设计这样一个PWM模块
给我们的微控制器用
让我们能够通过编程来方便的使用
我们要怎么来设计这个寄存器呢
这就直接关联到我们待会
对这个模块进行编程开发的时候
寄存器的理解
那么大家想一想
那么在我们这样一种模块的
嵌入式行业的设计里呢
一般会涉及到这样几个寄存器
我们往往会采用一个时钟源
构成一个PWM模块
那么这个时钟源可以同时驱动
若干个引脚产生不同的脉冲调制信号
所以我们都会有一个通用的
每个PWM模块共有的 Counter
也就是TPMx_CNT计数器
来记存这个计数器的值数到多少了
那么作为周期的设置呢
我们肯定还有一个跟计时器一样的
Modulo Value这样一个寄存器
我们称为TPMx_MOD的寄存器
来存这个计数器值
数到多少应该归0来决定周期
然后我们还要有一个寄存器
来保存我们所需要的对应的这一个引脚
比如这一个TPM模块里头
某一个引脚的占空比
我们可能要有一个单独的寄存器来存
数到多少发生引脚信号上
由1到0的相位翻转
那么这里头存的这个值
决定了我们的占空比 对不对
那么我们打一个比方
假设说我们计数器的值一秒钟累加1
那么我们计数的频率就是1赫兹
如果我们的Modulator寄存器
存的参考值是100
也就数到100我们这个信号就完成一个周期
那我们也就是说周期是100秒
频率是0.01赫兹 对不对
那么如果我们参考的
这个Duty Cycle这个寄存器的值设成10
也就数到10
发生相位的跳变
于是这个计数器是数到10 就跳变
数到100再归0
于是我们得到一个频率是0.01赫兹
周期是100秒
占空比是10%的一个脉冲调制信号
依此类推我们就可以完成对它的配置和控制
那么当然我们熟悉了各种编程以后
我们对于整个PWM模块
对于我们所使用的每个通道和引脚
肯定都有一些Status and Control register
来对他进行一些功能上的配置和状态的读取
那么有了这样一种基本概念以后
我们再深入的学习PWM编程之前
还要熟悉两个概念呢
一个是PWM的对齐方式的概念
所谓对齐方式是指
我们在一个PWM模块输出的多个PWM信号当中
这些信号以何种的方式来发生变化
以什么时间点来进行对齐
那么很自然而然的产生两种对齐方式
一种我们称为边沿对齐
也就是说在同一个时钟驱动下的
不同通道的PWM引脚
它们可以产生这个PWM信号都是同周期
但是占空比可以不一样
于是如这张图所示
他们都在左侧的第一个上升沿处对齐
然后在不同的时间点产生下降沿
得到各自不同的占空比
但在同样的时钟周期结束后
各自又都产生上升沿
这是一种对齐方式
那么在实际的工程应用里
比大家这种直观能想到的边沿对齐方式之外
其实还有一类是中心对齐方式
也就是说会产生一系列占空比不一样
周期一样的信号
他们总在为逻辑1的
那个部分的中心位置进行对齐
就如后面这张图所示
这样一种我们称为中心对齐方式
那么这样两种方式
实际上隐含的是比刚才讲的
最基本原理要略微复杂一点
我们对于计数器
对于Timer控制PWM
实际上可以有两种不同的
计数和工作模式
当我们计数值是单调的累加或者累减
遇到不同的值产生沿的跳变
和周期的切换的时候
就自然而然会产生不同通道间的
边沿对齐的输出信号
而如果这个模块被配置为
中心对齐方式的时候
实际上一旦我们设定了一个周期寄存器的值
它是完成一次由累加到最大值
再累减到0的连续计数
于是我们所得到的频率
所得到的频率值
是我们周期时设计值还要再除以2
那么在这样一种计数累加项
大家脑袋里想想这个过程
我们自然而然会得到一个背靠背拼起来的
看上去是以中心对齐的脉冲调制信号
那么有同学要问边沿对齐理解很容易啊
为什么要有中心对齐信号呢
在这门课的范畴里我不展开讲
就只给大家一个例子
就是前面提到我们对于直流伺服电机的驱动
那么在驱动的时候
我们需要一对反向的脉冲调制的脉冲信号
如果我们这两个信号的占空比都是50%
而且都是边沿对齐
就会直接导致我们在两路反向信号的
为1为0的跳转的这个上升沿和下降沿
是在时间上几乎对齐的
那么在电路上它会出现一个非常短暂的瞬态
是处于近似短路的状态
所以实际上在电机控制里
就会需要使用这样一种中心对齐的
脉冲调制方式
使它在中心对齐而占空比略小于50%
那么在电机的驱动当中会产生一个一个的
小的时间上的间隔
避免出现瞬态的短路导通
那么这是一个非常典型的例子
为什么我们的脉冲信号会产生中心对齐
有兴趣同学
因为大家做智能车和做机器人
还可以更深入的去进行学习和讨论
那么如果要对于这样一个模块
在我们KL25这样一个芯片里
进行详细的编程
在下一个单元我教大家怎么一点点去编程
我在这里给大家拉一下
它涉及到的基本的几个寄存器
那么大家如果看一看
屏幕上左边这个图呢
会发现它是一个PWM模块
也就是我们TPM模块的详细内部结构图
所以如果对照这张图可以非常容易看出
有若干个时钟源选通开关
包括我们说到的Timer
以及这个计数的比较的功能
那么这个图不展开详细讲
所涉及到的寄存器
放在我们所使用的KL25这样一个芯片里头
我来给大家讲一讲
他的模块和引脚的定义
在我们的芯片里一共有三个PWM模块
它被命名成了TPM
所以分别是TPM0到TPM2一共三个模块
我们简称为TPMx
那么在这个芯片设计里头
每一个模块最多可以驱动6个通道
也就是6个引脚的输出信号
那么这些引脚就称为Channel
称为通道
我们把它命名为TPMx
比如TPM0、TPM1
对应的C0、C1、C2、C3一直到C5
所以我们以TPMxC0
TPMxC3、C4、C5这样的名字来定义
每一个唯一的通道
然后每个模块它的Counter
也就是计数器当前值的寄存器和Modulator
也就是决定周期的寄存器
在每个模块里都只有一个是通用的
所以每一个模块上的6个引脚
它一定使用同样的时钟源和同样的周期
而每个引脚每个通道
可以有单独的占空比设置的
这个CNV这个寄存器
来设置它的占空比略有区别
那么大家记住这个概念
每一个模块的周期和频率是固定的
但是每个模块上所有引脚之间
每个引脚占空比是可以独立调整的
然后每个模块有一个总的状态和控制寄存器
每个引脚也有一个
各自独立的状态和控制寄存器
我们可以对它进行一些更加灵活的配置
那么这些寄存器
放在我们寄存器映射地址表里头
大家也非常熟悉了
就是会映射到400这个地址段
一个外设模块占有一段地址空间
所以PWM模块占有的就是
40038000开始的地址
那么每一个TPM模块大约有17个寄存器
占用这样一个地址段
之后再是TPM1、TPM2依次重复都是一样的
也就是我们刚才所介绍的寄存器
都对应到了这些物理地址
那么在下一个单元
我就会教大家对于这样一些寄存器
如何进行编程 使用
大家不要怕
使用其中仅仅的两到三个寄存器
就可以把这样一个模块给用起来
那么对于这些地址映射
还有这些寄存器的值
大家可以在芯片手册的第550页
详细的可以找到 自己再进一步的阅读
但是编程还是我说的那句话 不用怕
我们每次给大家讲内容
只用两到三个寄存器就可以把它玩起来
所以在下个单元
我们看看如何用三个步骤
把PWM模块给编程 用起来
-1.1 课程概览
--1.1 课程概览
-1.2 如何学好嵌入式系统
-2.1 计算机的基本概念、发展历史
-2.2 从晶体管到CPU
-2.3 概念CPU、微控制器MCU和嵌入式系统
-2.4 八卦计算机史
-2.5 不同领域、不同系列的嵌入式系统
-2.6 ARM历史与MKL25Z128 MCU
--2.6 ARM历史与MKL25Z128 MCU【习题】
-3.1 CPU的基本结构和运行机制
-3.2.1 堆栈的概念
--3.2.1 堆栈的概念【习题】
-3.2.2 堆栈的概念-头脑体操
-3.3.1 ARM的体系结构
--3.3.1 ARM的体系结构【习题】
-3.3.2 ARM的体系结构-头脑体操
-3.4.1 中断的概念和机制
-3.4.2 中断子程的概念和编程
-3.5 复位、时钟、存储器和总线
--3.5 复位、时钟、存储器和总线【习题】
-3.6 小结:MCU的总体结构和程序运行机制
--3.6 小结:MCU的总体结构和程序运行机制【习题】
-4.1 第一种外设:IO
-4.2 IO外设的编程实操-点亮LED
-4.3 IO外设的进阶知识
-4.4 嵌入式开发的基本概念与工具链
-4.5 嵌入式开发的进阶知识
-4.6 嵌入式开发中的C语言(上)
--4.6 嵌入式开发中的C语言(上)【习题】
-4.7 嵌入式开发中的C语言(下)
--4.7 嵌入式开发中的C语言(下)【习题】
-E0.1 实验零 开发板的初步认识与工具链的安装
-E0.2 实验零 体验一个例程的编译与下载
-E0.3 实验零 编写第一个程序:点亮核心板LED
-E1 实验一 点灯秘籍
-5.1 ARM微控制器外设学习概述
-5.2.1 ARM微控制器外设:通讯
-5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)
--5.2.2 ARM微控制器外设:异步串行通讯UART的原理(上)【习题】
-5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)
--5.2.3 ARM微控制器的外设:异步串行通讯UART的原理(下)
--5.2.3 ARM微控制器外设:异步串行通讯UART的原理(下)【习题】
-5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口
--5.2.4 ARM微控制器外设:RS-232串口与USB虚拟串口
-5.2.5 ARM微控制器外设:UART的寄存器编程(上)
--5.2.5 ARM微控制器外设:UART的寄存器编程(上)
-5.2.6 ARM微控制器外设:UART的寄存器编程(下)
--5.2.6 ARM微控制器外设:UART的寄存器编程(下)
--5.2.6 ARM微控制器外设:UART的寄存器编程(下)【习题】
-E2 实验二 UART编程实操
-5.3.1 ARM微控制器外设:IO的中断编程(上)
-5.3.2 ARM微控制器外设:IO的中断编程(下)
-5.4.1 ARM微控制器外设:定时器的原理
-5.4.2 ARM微控制器外设:定时器的编程
--5.4.2 ARM微控制器外设:定时器的编程【习题】
-E3 实验三 定时器中断编程实操
-5.5.1 ARM微控制器外设:PWM的原理
-5.5.2 ARM微控制器外设:PWM寄存器与编程
-5.5.3 ARM微控制器外设:PWM编程实例—电子音乐
--5.5.3 ARM微控制器外设:PWM编程实例—电子音乐
-E4 实验四 数码管显示编程实操
-5.6.1 ARM微控制器外设:SPI通讯简介
--5.6.1 ARM微控制器外设:SPI通讯简介【习题】
-5.6.2 ARM微控制器外设:SPI寄存器与编程
-5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动
--5.6.3 ARM微控制器外设:SPI编程实例—OLED显示屏驱动
-5.7.1 ARM微控制器外设:I2C通讯简介
-5.7.2 ARM微控制器外设:I2C的通讯协议
-5.7.3 ARM微控制器外设:I2C寄存器与编程
--5.7.3 ARM微控制器外设:I2C寄存器与编程【习题】
-5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器
--5.7.4 ARM微控制器外设:I2C编程实例—加速度传感器
-5.8.1 ARM微控制器外设:ADC简介
-5.8.2 ARM微控制器外设:ADC基础
-5.8.3 ARM微控制器外设:ADC寄存器与编程
-E5 实验五 ADC编程实操
-E6 挑战实验
--E6 挑战实验
-6.1 嵌入式系统的接口与设计
-6.2 嵌入式系统的实例