当前课程知识点:智能车制作:嵌入式系统 > 第三章 MCU基础 > 3.6 复位、时钟、存储器和总线 > Video
各位同学大家好
我是清华大学工程物理系的曾鸣老师
欢迎大家继续回到我们
ARM微控制器与嵌入式系统的MOOC课堂
继续进行我们第三章基础知识的学习
在这个章节里我们经过前面
对于CPU的概念 它的指令
它的编程模型的一些理解和学习
以及上一个单元里头
我们对于最最困难的中断的
一些基本概念的第一次初步认识
那么那个部分很难 我们先放下来
我们来进入把视野放在这样一个
MCU的片上计算机系统
来进行一个更宏观的理解
来构建我们对于这样一个MCU
麻雀虽小 五腑俱全的全面的认识
那么这个单元
我们来进入一个新的部分
就是关于复位 时钟
以及总线存储器等等
这样一些外围的这些部分的
逐一认知
首先说说复位
我们都会用很多很多的计算机系统
包括手机 包括我们手上的
这些智能设备
都会有功能是复位
大家都会理解说我们计算机上
最简单有两个按键
现在笔记本可能没有了
一个就是reset
我们按一下就强行复位了
或者长按我们可以开关它的电源 对吧
那么我们随而带来的一个问题是
学习了微控制器
知道它是个小型计算机系统
我们通过头脑体操也学习了
说一个程序在里头
究竟怎么一步一步的运行
一条条指令怎么走
我们开始有了一点做这个计算机的
上帝的这种感觉
能够知道他如何一步一步的运行
但进而言之的问题是大家说
我们这个计算机系统
他究竟上电是怎么运行起来的呢
它究竟怎么从一上电跑到
我的程序里头来的呢
很多同学如果好读书求甚解的话
就很想弄明白这件事
那我们来看看复位
复位是一个初始化微控制器内部电路的
这样一种过程
那么在一个上电复位的过程当中
或者在一个复位的过程当中
它会做很多很多事
比如说把我们这个微控制器
这样一个计算机系统里头
所有的寄存器都初始化成默认值
然后确认整个它的CPU
它这个MCU的工作模式
是不是在一个正确的工作模式
然后把全局中断先全部关掉
有的CPU可能然后再打开
把所有的外设都关闭
进入一个低功耗的状态
把所有的IO设成输入
或者是高阻的状态
然后等待系统的时钟进入稳定
最后从复位向量取第一条指令
开始执行程序
这就是一个复位的过程
我们接下来把这件事情弄清楚
那么刚才讲的所有这些过程
都是自动完成的
在我们学习计算机的时候
我们在这个单元里把它弄清楚
但是在我们编程和使用的时候
其实你不会涉及到真正去开发
去做这件事
那么我们回过头来看一眼中断向量表
我们会发现在讲中断时
我们一扫而过的中断向量表
其实有非常多的表项
现在终于有个时间
我们再把它仔细的再来看一看
我曾经提过中断向量表
对于ARM的这样一种处理器
微处理器的CPU的设计
在上电的时候
它的默认位置是从00地址开始
四个字节 一个表项
每个表项能存一个指针
存一个函数的入口地址
一共有多少个表项呢
一共有48个表项
而这48个表项里头 前16项
也就从0到15 这15项是称为异常
或者叫exception
这个异常不是说一种错误
而是指它是一种打断CPU必须响应的
一种类似于中断的 特殊的中断
那么这些异常是由CPU内部
也就是ARM设计CPU的时候所保留的
那么它包括了我们的复位
那么48减16 剩下的32项
是我们更通常意义上所讲的interrupt
也就是ARMCPU留给片内的外设
和外部的外部设备来产生的中断
包括按键 定时 通讯等等
所以我们在用户程序编程的时候
更多的使用的是后面那32项的中断
而在前面16项异常类的
我们从最上面开始往下看
就会发现表里头的第二个
也就是表项里头的顺序0 1的那个1
它是reset 所以它是复位的中断向量
或者叫异常向量
那么换言之在这个表项里
所存储的那个入口地址
那个函数的入口地址
是任何一个芯片 是这个ARM
这个芯片复位以后所取回的
第一条指令的执行地址
这句话用一个更通俗的语言讲
就是这样一个芯片一旦完成了复位
CPU会自动的从这个位置取一个地址
跳转到那里 赋给PC指针
跳转到那个地方
从第一条指令开始逐条执行
是不是就进入了我们程序的流程
那很多同学会想 说这个地址填谁呢
有很多同学会说 我们在这个地址
填我的main函数的第一条指令
这样是不是这个单片机
这个微控制器一上电复位
就开始执行我写的main函数
很多同学都学过C语言
都说从main函数开始执行
这是一个很好的想法
但是在绝大多数嵌入式系统里头
开发工具会帮你生成一段startup code
一小段入口函数
以后大家使用开发工具
可以自己把那段函数打开看
你会发现 这个地方填入的
是那个入口函数的第一条指令的地址
而那个入口函数一般来讲
它的最后一条语句
最后一条指令
就是jump到你的main函数开始执行
所以上电的流程是将开发工具
生成的入口函数那一小段代码的
第一条指令的地址填在这儿
而上电以后 CPU自动从这儿
加载那个地址 开始执行那个入口函数
而入口函数一条一条指令
自动PC指针累加执行的
最后一条指令
跳转到大家写的main函数
就进入了大家写的程序
这就是一个微控制器的计算机系统
从上电复位的整个流程
它如何一个指令一个指令执行到
我们所写的程序
多说一句 在这个表里头你会发现
reset向量是它的第二项是编号1
那编号0的第一项是什么呢
是堆栈指针向量
所以这里头也能存一个四字节的地址值
这个值在ARM的处理器里
跟别家的处理器不太一样
是一个额外的功能
它会把堆栈指针的那个CPU
内部那个寄存器的初始值存在这里
也就是说我们内存一上电
哪段内存空间给堆栈用
堆栈指针要初始化
那个值可以填在这里
这样在上电复位的时候
CPU自动把这两项的值
一个给CPU的堆栈指针寄存器
一个给CPU的PC指针寄存器
这样CPU在上完电的一个瞬间之后
PC指针寄存器指向了可以执行程序的
第一条指令 堆栈指针寄存器指向了
可以使用内存的堆栈的起始地址
是不是就可以开始有序的执行我们程序
所以刚才讲的这个过程
是在ARM CPU设计时候自动完成的
而我们在编写程序的时候
借助开发工具
完成这两个表项的填写
就能控制这个计算机
平稳的完成启动跳转到我们的程序来运行
与之呼应的 在个人电脑上
大家觉得很神秘的上电以后
它的流程比这要复杂多得多
会执行主板上所加载的bios程序
而bios程序之后又会跳转到
我们的硬盘的引导区
执行里头存储的一小段MBR的引导程序
最后跳转到我们windows
或者linux操作系统完成加载
所以虽然复杂 但是类似
通过学习它我们可以对计算机
从上电的一瞬间所执行的过程
有着更深的理解 那么我们需要理清
包括我刚才隐隐约约在语言当中
提到的是复位不仅仅指计算机
在运行的时候
必须重启它的那样一种操作
严格意义上来讲
我们对一个计算机上电的过程
就是一个复位 称为上电复位
Power on reset 所以它的过程
是等待电源和时钟稳定进行一次复位操作
加载复位向量开始执行程序
所以说上电也就是复位
然后我们在刚才说的那些exception里头
那些中断向量把它前16项里头
一个CPU要响应各种各样的异常状况
完成自我保护的一些复位
比如说电源不稳定的电源丢失
由外部的人为按键强行的一个外部复位
比如说reset引脚引出来的复位
然后软件执行一个复位指令
引发的软件复位
然后CPU的PC指针
因为堆栈的溢出等等这些错误跑飞
取回了一个不是指令的指令
让CPU运行的非法指令的复位
以及时钟不再稳定
时钟的这个振荡丢失了的时钟复位
还有一些高可靠性的程序
要求的看门狗保护电路
得知程序已经死机的看门狗的复位
这些都是CPU
或者一个计算机设计的时候
必须响应的一些内部的异常
这些都可以引起我们刚才所说的复位
使我们的程序自动的重新加载恢复到
一个正常的运行状态
这在嵌入式系统设计里头
与台式计算机的软件不一样
是一个非常需要考虑的特殊性
那么除了复位
我们一个计算机要想运行起来
还会有一个非常重要的功能就是时钟
我老给同学打一个非常详细的比喻
如果大家系统的学习了数字系统的设计
再到嵌入式系统
或者从我们第二章的课程里头
组合逻辑电路
时序逻辑电路这么过来
我们会非常清楚的认识到
计算机的嵌入式系统
是一个典型的数字的时序逻辑的系统
那么它需要一个时钟的驱动
来让一切有序的进行
比如我们深切的感受到
我们一个个时钟的跳动
会驱动我们的PC指针寄存器
一个一个地址的往下跳转
一个一个的指令取回来
有序的进行解析和运算
所以我们可以理解时钟
是指令执行的基本时间间隔
它会推动我们CPU真正一个周期
一个周期的往前运转
或者是呼应了我们抽象的图灵机里
那个纸带子一格一格的旋转
时钟的频率越高 在某种意义上
意味着CPU的执行运算能力可能越强
当然 运算能力也取决于指令集的
优化程度和不同的指令它的效率
那么 我们的整个计算机的
稳定的运行
包括我们的定时器
包括我们所依赖的各种各样的通讯
包括我们整个时序的控制
都需要一个稳定的时钟源
而在CPU内部
为了时序逻辑上的边沿的
对齐和时序上的一致性
往往会有一个统一的时钟树的概念
也就是在CPU在一个计算机系统
在微控制器的内部
会有一个统一的时钟树
从一个比较高的频率
逐一分成它的子频率
它的低频率来给不同的模块
不同的通讯
不同的时钟部分来加以使用
这样构成了一个时钟树的概念
也就是Clock Tree
那么我们的时钟往往会使用一个
我们在大学物理里学过的经典电路
也就是就于晶体的振荡电路
来产生一个由低电压到高电压的
来回跳变的周期固定频率来作为
我们的计算机系统的时钟源
那么我们往往有时候会使用一个外部的
引脚接一个外围的时钟振荡电路
来作为我们的时钟源
而当代的MCU有时候
为了让它更低成本 更简易的运行
也会在片内设置时钟源
那么我打一个比较通用的
或者不恰当的比喻来讲
我们可以想象成计算机系统
一定要有一个时钟
就像我们动物一定要有个心脏
在这个心脏一下一下的跳动当中
营养送给我们的器官我们能够活着
能够去做很多思考
而这个时钟是整个计算机系统
一个脉动一个脉动向前运行的根本
那么最后说 在当代的计算机系统里头
我们会广泛使用锁相环 锁频环的技术
在片外使用一个较低频率的振荡电路
比如说几KHz 几十KHz
而在片内翻到几十兆 乃至上GHz
推动计算机内部高速的运行
同时又使计算机对外的电磁辐射和
电磁兼容性达到最优 在这里不展开讲
那么具体到我们ARM Kinetis处理器
我们看看它的时钟树 就是这样一张图
那么我们会 日后如果有时间学习
会详细的学习它的MCG SIM和OSC
这些时钟振荡和时钟管理模块的
基本配置运行
我们现在所需要知道的
是这样几个点 在这个时钟里头
在这样一个时钟树里头
对我们处理器它既有片内的
采用IRC振荡产生的几十KHz的
振荡源作为片内的时钟源
也可以通过引脚在外
使用高精度的时钟
石英晶振的振荡电路
给它提供一个高精度的时钟源
都是可以的
然后片内有锁相环和锁频环
有若干种时钟的通路
把一个较低的频率翻成一个几十兆
乃至几百兆的高频 来给CPU运行
最终这个频率出来形成一个时钟tree
又分出我们指令运行的Bus Clock
和我们各个模块包括通讯包括定时器
所要使用的时钟
那么在上电复位的一瞬间
就是我这个箭头所画的部分
从一个片内的IRC振荡的32K的时钟
经过锁频环的倍频
最后产生一个20.97兆的固有频率
是这个单片机这个MCU上电以后
默认所使用的时钟
这个时钟因为IRC的片内的振荡
有一定的误差 所以它是20.97兆
正负百分之几的一个误差
所以我们日后要做更高的频率的时候
我们既可以选择将这个频率翻的更高
得到更好的性能
而我们要做更高的速度的通讯的时候
我们也可能要使用片外的晶振的时钟
振荡电路 获得我们所需要的
高精度的频率
比如串行通讯和USB的通讯
讲完了复位和时钟
最后在这个单元里
还要给大家讲的一个概念就是存储器
存储器我们用了很多次
在这里非常简单的可以讲
我们又回到这个章节一开始
给大家拉这张图 我们花了很多时间
讲清楚了在一个麻雀虽小
五腑俱全的计算机系统
一个片上的计算机系统里头
在这个芯片内部会有CPU 会有时钟
会有复位 我们还有一个
不可以缺少的东西
就是存储器
在一个片上的计算机系统里头
我们会有RAM相当于
我们计算机上的内存
会有基于Flash等等各种工艺
所生产出来的ROM
相当于我们计算机上的硬盘
也就是关掉计算机 关掉电源
它的数据不会丢失这样基本的
两大类存储器
所以 一个CPU内部可能会有一些
少量的寄存器来存储一些临时的数据
我们称为草稿纸
但是一个计算机完整的运行
它需要大量的非易失的存储器
来保存我们的程序 我们的指令
我们的数据表和我们的常量
还需要大量的易失的存储器
也就是我们的RAM来作为
我们的堆栈 作为我们的堆
作为我们的栈来帮助我们
程序运行当中保存变量
保存返回地址
保存这些函数调用之间的
堆栈的使用
所以这些存储器构成了
我们一个计算机系统不可或缺的部分
那么对于我们一个计算机系统而言
这个存储器的体量是有大有小的
比如说我们一般会在当代的
这个32位处理器
会有百K量级的非易失存储器
会有几十K量级的RAM来供我们使用
这也就是我们所学习的型号
MKL25Z128的来源
那么有了CPU 有了中断 有了时钟
有了存储器 从存储器演发
我们不得不讲的另外一个概念
就是总线 总线在我们这门课里
不展开详细讲解它的更多的内容
我们只是进行一个概念性的认识
我们总会抽象的在前面的课程里讲
说存储器我们必须把它
理解为一个做了
有序的地址编号的存储空间
一个一个的格子可以存数据
每个格子有个地址
有个address 那么到了具体计算机
实践的时候 就是这张图
其实从CPU来讲我们是通过总线
与外面这些存储器加以连接的
我们的总线会完成数据的读和写
以及读写当中的这些控制
总而言之
就是我们会构成三个部分
包括传递数据本身的数据线
有若干个线上面每个传递0
或者1 构成单字节
或者多字节数据的传递
传递这些数据所存储的
目标的地址的地址线
我们用若干根平行的线
传递0或者1来构成我们的地址
比如我们在0004这个地址上
我们就一定要有若干根线
传递0000 0100这样的一组
地址编码 来选中一个一个的格子
而在这样的读和写的过程当中
一定会发生CPU与存储器之间的交互
设备与设备之间的在通讯上的协调
会有一些线来完成控制
所以地址线 数据线和控制线构成
我们一个完整的总线
使我们的CPU能够按照地址对片外的
这些存储器进行逐一的访问
那么从CPU按照地址总线的视角
我们来往外看的时候
我们就会发现受总线所限
我们会受到这样一些约束
比如我们地址线
会有一个固定的位宽
我们前面讲计算机历史会讲
它是多少位的计算机
我们的地址线如果是8位
就意味着地址只能从0000 0000
到1111 1111进行编码
能够编出的地址一共就只有256个
那换言之对外能够访问的地址格子
最多只有256个 而如果16位
我们就可以想象65536个地址可以访问
我们现在的ARM Cortex M的处理器
是32位的CPU系统
所以它的地址线是32位
对外能够访问的地址空间
是4G个字节的地址空间访问范围
然后第二个概念是我们的数据总线
数据总线可以是8比特
16比特 32比特也就是8根
16根 32根并行
意味着我们在单次的数据访问里
是以字节 双字节还是以四字节
为单位进行数据存储
而我们的ARM Cortex M是一个
真32位的CPU 它的数据线也是32位
所以它最高效率的时候可以四字节
四字节的进行数据的存储访问
有了地址的概念
我们知道从CPU往外看
根据地址的位宽和数据的位宽
我们可以看待CPU外面这样一个
计算机系统里的其它设备
那么我们就会构建起一个从CPU视角
按地址段来看待外围世界
这样一种概念
这样一个概念在这里需要加以区分
我们前面讲过的所有CPU内部的寄存器
不管是R0 R1 R2还是那些状态寄存器
它都是CPU内部的一个单元
对它的访问是通过指令直接实现的
而当我们一旦越过了CPU的边界线
要看这样一个片上计算机系统里头
这些存储器的时候
我们就必须通过地址来加以访问
而如果我们拿到了一个芯片
我们学习去看这个芯片手册
我们就可以看到这样一张表格
它给出了每一个地址段
所对应的在这样一个片上的
计算机系统里头 所对应的那些设备
那么特别是存储器一一映射到了
这些空间里 我们把它画制成
这样一张图 加以抽象
那么我刚才所讲的内容
就可以更清晰的看到
从CPU的视角往外看
我们会发现比方说从0x0000 0000开始的
这个地址段一直到0x0800 0000
是我们的128K的Flash
而在最上面这一小段
它是非易失的用来保存了中断向量表
而从0x1FFF F000这个地址段
一直到我们的0x2000 0000这个地址段
是我们的RAM 它由4K和16K的RAM
构成了一个RAM的存储空间
而在这当中会有一个地址段是None
或者叫reserve 它虽然在CPU的编址上
有4G的地址可以编
但是没有那么多的东西可以让地址来用
所以有大量的地址空间是空白的
是浪费的 对它的访问是没有意义的
那么我们接下来会往下学
还有很多地址段在下面是用来映射
我们对于外设的控制
在下一个单元我会给大家讲
所以我们通过总线的学习
逐渐树立了对于CPU按地址往外看
计算机内 外设 的这样一种概念
希望大家逐渐的理解
-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