当前课程知识点:智能车制作:嵌入式系统 > 第四章 MCU外设与开发 > 4.1 第一种外设:IO > Video
各位同学大家好
我是清华大学工程物理系的曾鸣老师
欢迎大家回到我们ARM微控制器
与嵌入式系统的慕课课堂
我们这门课呢
已经完成了前面三个章节的学习
我们学习了概论
学习了基础知识
学习了计算机的八卦历史
也学习了ARM的内部结构
那么在我自己在清华的课堂上
一般学到这个时候
同学们就会开始比较迫不及待的问我
说老师我们什么时候才能真正玩起来呀
讲了那么多
那么我们这一章节就开始学习ARM微控制器的开发
也就是真正把这样一个芯片给玩起来
所以呢今天这个第一个小节
我们主要两个内容
认识真正拿到手里的ARM微控制器
这样一个芯片
它是什么样的是什么样的组织形式
同时接触第一类最简单的外设也就是IO
看它是怎么工作的
那么我们在前面的学习当中
已经从逻辑上从概念上
对一个微控制器
有了一个编程模型的概念
抛开内部编程模型的寄存器和指令
我们对微控制器内部的组织形式
按总线的这样一种编址形式有了一个大的概念
从0000地址的flash
一直到下面的RAM
一直到4000地址开始的外设寄存器
乃至最后端的我们称之为Private或者叫私有寄存器
这样一些ARM定义的寄存器
构成了整个由0到ffff这样一个编址的
微控制器的内部结构
那么我们通过这样的学习
我们知道了一个程序
或者一个微控制器运行的基本流程
在flash的最顶端
是中断向量表 包括了复位向量表
一个程序烧写在flash
因为它上电不丢失
而从中断向量表加载了复位向量之后
跳转到flash的某处
开始执行程序
而在程序执行的过程当中
会根据程序我们编程人员的需要
进行内存的读写 变量的操作
以及堆栈的使用
而我们一个微控制器
要与外部的电路发生关联
进行外部信息的交互和人机的交互的时候
我们通过对外设寄存器区的寄存器进行编程
来实现各种控制和通讯的功能
那么我们今天后面的课程
就要学习第一类的外设
以及熟悉第一类的开发方法
那么有了这样一个编程模型的概念
我们真正看到的芯片是什么样的呢
如果大家把我们的嵌入式教学系统
或者把任何一个买到的电子产品拆开
你会发现有一个最明显的主芯片
很多时候它是一个黑黑的小方块儿
周围四边密密麻麻银色的腿儿
但是一个学习过我们这门课程 学习过嵌入式的同学
如果你对芯片的概念
对嵌入式系统的概念
还停留在它是一个小方块儿
有银色的腿儿 那就太少了
我们应该穿破这层迷雾
去看它的芯片手册
去了解它究竟是什么样的定义
那么不管各家厂商各种型号的芯片手册
如果你去找
一定会找到如图所示这样的Pinout图
那么在英文里一般叫做Pinout Diagram
也就是引脚定义图
比如说80引脚的芯片
我们可以看到它从逆时针从第一腿到八十腿
会给出每一个引脚
每边二十个腿的分布 顺序
以及它的名称
相应的同型号的芯片
基于成本的考虑
可能有些引脚不引出来
也会有更小封装的
比如48腿64腿的引脚封装
也会有这样的芯片存在
那么如果把这样一张图局部放大
我们会发现从
一个标识为小黑点的点开始沿逆时针1234
一直绕一圈到八十
那一个引出的引脚在这里抽象为了一个小方框
在现实中就是那个银色的腿
它都有一个名字
比如PTE1
PTE2一直到底下
还有VDD VSS 乃至USB
我们会发现呢
在一个真实的芯片上
除了VDD电源 VSS接地
以及USB通讯上的专用引脚之外
绝大数的引脚都会采用一种范式来命名
就是PT字母加数字
那么这就是我们对于这些引脚的一种
统一编组和识别的方式
因为引脚这么多
我们总要给编个号
就跟学生要编在班里一样
所以呢在计算机领域
我们往往会把这些引脚编成一个个的PORT
也就是端口
端口由ABCD的字母来进行分组
比如1号引脚
PTE0就是PORT E的第0个腿儿
那么顺势往下编
PORTE1 PORTE2
以及我们看到右上角
这个80腿是PTD PORTD的引脚
那么这样的一种编组
使我们所有通用引脚
都分组在了一个个的端口里
若干个引脚一组
这就是我们看到芯片的形式
而如果在任何一个厂商的芯片手册里
我们继续往下找
一定还能找到一张表格
这张表格左边的一列给出了不同封装里头
这些引脚
是否存在
比如在八十腿的封装里这些引脚全都存在
从1到80
那么第五列开始给出了这个引脚
我们刚才所看到的名字
那么这个引脚的名字是他的编组PORT
但是呢从Default功能之后
我们会看到每一列 Alternative 1 Alternative 2
那么这个ALT是Alternative的缩写
也就是我们可以使用的
选择使用的功能一 功能二
那换言之我们在这里有一个概念
就是每个引脚
在寸土寸金的这个芯片封装上
在这个芯片的成本跟它的尺寸
成正比的这样一种成本控制原因下
每一个引脚都可能有若干种不同的功能可以使用
这给我们的电路设计带来了灵活
我们可以把一个引脚接上一个灯来点一个灯
我们也可以把一个引脚
选择它的通讯功能来做通讯
从而我们可以在实际编程开发时
根据我们的电路
给每个引脚选择它所使用的功能
而我们今天也就是待会要学习的
就是他的第一类功能
当做普通的IO用
进行一类简单的数字量的输入输出
日后我们会学习后面他可以使用的其他功能
从而使我们的本领更加大
能够完成各种各样的更加好玩的事情
那么下面第二个部分呢
我们来讲讲什么是第一类简单的外设IO
一个引脚体现在外面
就是在我们这张图的最右端
它是一个物理的引脚
一个金属的腿
金属是导电的
在内部它会连接一系列的门电路
也就是支撑它的我们的这个引脚的IO的逻辑电路
那么从编程的角度
我们要控制这个引脚
我们只能用c语言进行0或者1
这样逻辑开关量的操作
也就数字量的读写
那么这些读写会体现在我们左侧的若干个寄存器上
这些寄存器我们映射到地址上
读写进去的是0或者1的值
而他传递在我们电路里的则是0或者1的逻辑电压
3.3V 0V沿着逻辑门电路的传递
最终体现在我们的引脚上
那么我们接下来要看看它的工作模式
如何通过编程通过有限个寄存器的操作
使一个引脚如我们所愿的工作起来
那么IO引脚在几乎全世界所有已知的
微控制器里头是一个非常常见通用的模块
也是最最简单最基本的一类模块
我们也把它说成是微控制器
与外部电路或者
外部物理世界连接的最基本手段
那么在各种各样的微控制器里头都有IO
那么IO有这样几个通用的功能
一个呢我们会经常把IO
就跟我们刚才说端口的引脚一样
8个 16个 32个编成一组
这个道理很简单
因为在C语言编程的时候
我们进行一个比特的操作是很困难的
我们往往会把寄存器八个比特一组
映射为一个字节占一个字节的地址
或者十六个比特一组
映射成一个word占两个字节地址
所以我们编程的时候
以IO为八个十六个一组
相应的正好对应寄存器
8个 16个乃至32个比特
构成了一个读写单元非常方便编程
其次呢IO往往是双向的
我们在功能使用的时候
应该指定这个IO
工作在输入或者输出的模式
它既可以对外输出一个数字量
也可以从外面获取一个数字量
最后呢这个IO的引脚就像我们刚才提到的
通常会跟一些其他的功能复用
我们可以选择让这个PORT
这个金属引脚当做IO用
也可以选择把这样一个引脚给别的功能用
那么这样一个引脚功能
用起来我们会涉及到若干个寄存器
这些寄存器不限于ARM
在各家各个厂商的微控制器里
都会存在
比如IO的方向寄存器 输出数据寄存器
输入数据寄存器
乃至状态寄存器
所以我们现在学习的呢
实际上是一个通用的编程模型
在下一节我们再具体到型号上看怎么编程
从基本功能上来讲
有着这么一个电路的框图
我们把一个引脚希望输一个出数字量
它内部的流程是怎么样的
如果我们高度抽象
可以把它想象成这样
首先我们应该通过一些复用的配置
确定这个引脚是给IO模块用
也就是说这个PORTE PORTD上面这个引脚
是给这样一个IO模块来用
那么我们通过配置选择打通它里头的
数据通路也就数字量传递通路
由我们这样一组IO的寄存器来接管
接着呢我们要输出
我们应该对一个叫做
PDDR方向寄存器进行编程
进一步进行数据通路的配置
使它工作在让这个引脚输出的状态
这个时候这个引脚的功能
由我们的第二个寄存器PDOR
Port Data Output Register 来控制
那么在这个寄存器里
我们写入一个比特的零或者一
我们会发现这个零或者一的电压
可以顺着建立的数据通路
一直送到我们的引脚上
从而在引脚外部
看到了一个逻辑零或者一
在我们芯片里就是3.3V或者0V
而如果我们希望
工作在输入模式的时候与之类似
首先通过复用将这个引脚
交给IO模块来接管
其次呢我们应该对PDDR Port Data Direction Register
方向寄存器进行编程
让它工作在输入状态
跟刚才有一点点不一样
那么这个时候我们在对
PDOR寄存器进行编程
会发现这里写的值
无法反应在在引脚上
他已经被隔断了
这个时候反过来是引脚上
从外部电路所连接的电压值
可以顺利的通过一个回路
一直送到了我们最上面的第三个寄存器
PDIR寄存器 也就是Port Data Input Register
输入数据寄存器
这个是我们对这个寄存器进行读操作
读到了零或者一
就反映了这个引脚收到了3.3V或者是0V
从而我们获得了外面电路所连接的电压关系
那么最后说一句
如果这个引脚不当IO用了
大家不用担心
我们在复用模块里同样进行编程
就会发现我们PORT这个端口上这个金属引脚
所对应的功能全部被导向了别的模块
由其他的日后我们要学习的
功能模块加以接管
而我们对于IO模块进行如何的编程
都与这个引脚不再发生联系
不会影响它的功能
所以这些复用的功能之间
是不会打架的
那么多说一句拔高的内容是
如果我们进行一个
这样深入地嵌入式的学习
特别是我们希望进行一个
智能车或者机器人
这样一个趣味的开发
我们不应该仅仅停留在
通过编程产生了零或者一这样一个层次
我们应该对它的内部电路
进行一些拓展的学习和阅读
在这里我只给大家进行点出
我们现在所使用的数字IO
内部是一个叫做Push and Pull的推挽输出结构
它由一对互补的对管
比如PMOS和NMOS来分别控制与电源和地的导通
那么在一个数字量输出的时候
可以有效的选通单侧导通
从而将电源或者地
以非常小的阻抗送到我们的引脚上
获得高电压和低电压
这样一种输出模式
我们有非常小的输出阻抗
有非常强的电流驱动能力
同时有比较快的切换速度
这种输出我们称为推挽输出
与之对应的呢
还要开源开漏的输出
在以后学习I2C通讯的时候
我会给大家介绍
有兴趣的同学可以拓展阅读
这一部分的模拟电路和数字电路基础知识
此外基于模拟和数字电路基础知识
我建议大家在使用任何一个芯片的时候
你学习去看他的Voltage and current operating ratings这样一个表格
这在所有的手册里都会有
是这样一个的芯片的
电压和电流基本工作参数
那么IO做为一个最基本的参数
一般都会出现在这个表格里
比如从这张表格的第三第四列
我们能看到在我们这个芯片里
一个数字IO工作在3.3V的时候
它输出逻辑1是3.3V吗
还是在它附近一个多大范围
输出逻辑0是真正刚好0V吗
还是最高不会高过多少
同时还会告诉我们
一个芯片一个引脚
对外输出逻辑零和一的时候
不仅仅是电压这个概念
一定会有功率的概念
会有电流的概念
比如在我们手上这个芯片里
他无论对外输出电流 3.3V的时候
还是从外获得电流
当它0V的时候
都不能超过正负25个毫安
最后我要提示大家
最上面两行
是我们这个芯片的总电源供电
比如说在3.3V的
一个范围内的一个供电电压
同时这个电源电压
有一个最大的供电电流值
那么这个值也会影响我们IO的使用
在后面我会提示大家去思考
那么讲完了这个拔高的内容
我们想一想
说老师你讲的这些基础知识我知道了原理
那具体到我们现在学的这个芯片
或者我拿到任何一个芯片
我想编程想用起来怎么办
我告诉大家要用四或者五个寄存器
我们才能把这样一个IO给使用起来
就像刚才所讲到的大家非常容易想到
我们有三个寄存器控制方向
控制输出的值或者读取输入的值
还有个寄存器要通过编程
来控制这个引脚是否给IO模块用
进行功能的配置
最后还漏了什么呢
还不要忘了我们学习的嵌入式系统
本质上是一个数字计算机系统
是个数字系统
每一个模块都应该在时钟的驱动下
才能有序的去工作
当我们不用的时候
这些模块都是在时钟断开的状态下
获得较低的功耗
而我们使用的时候
一定要通过配置把他的时钟打开
那么这些模块它的使用在
不同的芯片里
可能分布在芯片手册的不同章节
比如我们所使用的
芯片IO模块在第41章
而我们所使用的关于
引脚复用配置的模块
专门在PORT的配置模块章节
而所有的这个引脚时钟打开的模块
在系统集成的章节
我们应该具备能力
在芯片手册里找到对应的章节
而本门课程的学习呢
我会带着大家从使用的角度
倒过来先去阅读
日后大家应该具备
自己拿了一个新的芯片
把它加以使用的能力
那么学习编程是我们下一节课要讲的内容
我们学习了编程我们干嘛呢
在这里给大家多讲一点提示
最简单的一个功能就是点灯
我们都很熟悉从高中物理开始学习的东西
点灯点亮一个发光LED发光二极管
发光二极管是一个PN结
它能把电能转换为光能
学习电子知识往前更进一步的时候
日后我们应该学习
它除了一个简单亮或者灭
还有很多别的特性有待大家发掘
它的颜色它的尺寸它的亮度
它的封装它的亮度与电流的关系等等
那么如果更高阶的学习
还有它的切换速度
所以呢
我们点一个小小的灯
其实日后还有很多可以摸索的东西
但是在现在的功能里头
我们只用一个最简单的接法
就是通过一个限流电阻
因为它的亮度与电流成比例
我一定要对它进行限流
它是二极管 接上电源
然后正向连通接到我们的IO引脚上
那么问同学怎么样能让
这样一个电路连接的灯变亮呢
我们应该在IO引脚上给出一个低电平
这样形成了一个电压差
有电流流过这个灯就亮了
那么相反的我们要让这个灯灭掉
我们应该通过编程让这个
IO引脚上产生一个高电平
两者电平相等
3.3V之间没有压差
没有电流这个灯就灭了
那么这个时候跟我们大家
可能心里很多同学期望的是相反的
我们这样的接法给高电平灯是灭的
为什么呢
待会我们也会进行讨论
此外我们非常常用的
还会通过开关或者按键
来引入一个人为的输入量
开关在这个世界上
物理里头抽象成了一个简单的
单刀单掷或者双刀双掷
如果大家日后进行嵌入式系统的设计
你会发现有不同尺寸
不同颜色不同功能的开关
也是可以供大家选择
我们会慢慢培养起对各种元器件
有丰富选择的概念
而带有自恢复功能的开关
我们有时候称为按键
它会抽象成一个button
如果我们同样通过一个外部上拉电阻
和一个接地的电路
把它与一个IO相连
我们非常容易地读懂这个电路
当按键被按下的时候
我们的地与引脚连在了一起
上拉电阻隔断了这个高电压的压降
所以我引脚会拿到一个低电位
也就是逻辑零
当这个按键松开的时候地是断开的
由于我们这个(芯片引脚)输入阻抗较大
所以我们的IO引脚
会拿到一个近似于VCC3.3V的电压
也就是逻辑一
从而我们可以通过IO得到逻辑一
或者逻辑零知道外面的按键是否有被按下
那么很多同学会说
我很想做一个很好玩的东西
不论是个游戏机
还有个人机的小设备
你一定离不开一个按键的功能
学习了IO
我们可以把它给玩起来
所以呢
在我们后面的两个小节里
我会教大家如何真正
实操编程各种花样的
把这样一个最简单的模块和功能玩起来
实现点灯甚至实现呼吸灯
花式灯变色灯以及人机的交互
那么下一个小节我们将要编程的第一个任务
就是如何把这样八个灯
通过一个简单的main函数的编程点亮
你会发现它一点都不难
让我们下一节课再见
-1.1 课程概览
--Video
-1.2 进入嵌入式系统的世界
--Video
-1.3 如何学好嵌入式系统
--Video
-2.1 计算机的基本概念、发展历史
--Video
-2.2 从晶体管到CPU
--Video
-2.3 概念CPU、微控制器MCU和嵌入式系统
--Video
-2.4 八卦计算机史
--Video
-2.5 不同领域、不同系列的嵌入式系统
--Video
-2.6 ARM历史与MKL25Z128 MCU
--Video
-3.1 CPU的基本结构和运行机制
--Video
-3.2.1 堆栈的概念
--Video
-3.2.2 堆栈的概念-头脑体操
--Video
-3.3.1 ARM的体系结构
--Video
-3.3.2 ARM的体系结构-头脑体操
--Video
-3.4 中断的概念和机制
--Video
-3.5 中断子程的概念和编程
--Video
-3.6 复位、时钟、存储器和总线
--Video
-3.7 小结:MCU的总体结构和程序运行机制
--Video
-4.1 第一种外设:IO
--Video
-4.2 IO外设的编程实操-点亮LED
--Video
-4.3 IO外设的进阶知识
--Video
-4.4 嵌入式开发的基本概念与工具链
--Video
-4.5 嵌入式开发的进阶知识
--Video
-4.6 嵌入式开发中的C语言(上)
--Video
-4.7 嵌入式开发中的C语言(下)
--Video
-E0.1 实验零 开发板的初步认识与工具链的安装
--Video
-E0.2 实验零 体验一个例程的编译与下载
--Video
-E0.3 实验零 编写第一个程序:点亮核心板LED
--Video
-E1 实验一 点灯秘籍
--Video
-5 智能车视角的嵌入式设计
--Video