由乔恩·怀尔德
一次又一次,我看到初学者试图开始嵌入电子产品,只是不知所措,不知道从哪里开始。有些人甚至在没有完全理解他们所使用的微控制器/微处理器、所使用的编程语言、甚至是基本的编程概念的情况下就试图编写自己的代码。不过也不用担心,这篇文章应该是你涉足嵌入式电子领域的入门读物。
这篇文章不打算教任何特定的微控制器/微处理器,但更多的是解释适用于所有微控制器/微处理器的一般概念的初级读本。
首先,让我们问自己几个问题。第一个问题是
什么是微控制器?
微控制器是在芯片上的微型计算机。CPU, RAM(随机存取内存),特殊功能寄存器,程序罗内存,内存芯片数据,从一个到多个并行I / O(输入/输出)端口,并且可以对芯片的外围设备包括但不限于模拟-数字转换器(ADC),数模转换器(DAC)串行UART,一个或多个计时器,比较器/芯片电压参考,捕获/比较/PWM(脉宽调制)模块,用于SPI(串行外围接口)/I2C(集成电路)通信的主同步串行端口,USB端口,以太网端口,芯片振荡器,以及主机的其他外围设备。
什么是微处理器(等等,你的意思是实际上有区别)?
微处理器和微控制器一样,只是没有芯片上的程序ROM。程序代码驻留在芯片外的一个单独的外部EPROM芯片。
程序ROM和数据ROM
微控制器上的片内ROM(只读存储器)就像微控制器的硬盘驱动器。它有两个分区。一个分区保留用于存储程序代码,而另一个分区保留用于永久存储芯片在正常程序执行期间使用的数据。在给定的PIC微控制器上,例如程序空间为8K,程序空间将占用ROM地址0x0000 - 0x1FFF(或十进制的0 - 8191)。数据空间将从程序ROM地址0x2100开始。如果数据ROM空间是256字节长,数据ROM空间将占用ROM地址0x2100 - 0x21FF(或十进制的8448 - 8704)。
CPU
CPU是中央处理器(Central Processing Unit)的缩写。它基本上是微控制器的“大脑”。它从代码内存中获取指令并执行它所获取的指令。
数据的内存
数据RAM (Random Access Memory)是用来临时存储微控制器在程序正常执行过程中所使用的常量和变量值的数据空间。一个给定的微控制器上的物理RAM空间的数量因微控制器的不同而不同。微控制器上的数据RAM被组织成几个“寄存器”,每个寄存器都有自己独特的“地址”。8位微控制器上的RAM寄存器总共可以容纳8位或一个字节的数据。一个典型的RAM空间规格可能指定为256 x 8。这意味着在RAM中总共有256个寄存器,每个寄存器可以容纳8位。
寄存器只是内存中的一个位置,你可以向它写入数据或从中读取数据。有些人把寄存器称为“位置”。
特殊功能寄存器
微控制器上的特殊功能寄存器(简称SFR)就像数据RAM中的寄存器一样。您可以向它们写入数据,也可以从它们读取数据。它们的不同之处在于,有些SFR直接控制微控制器上的片内硬件,而有些SFR是由微控制器上的片内硬件控制的。
SFR中的每一位都被赋给一个函数。在SFR中,你有控制位和标志位。控制位就像“开关”,打开或关闭一个函数,取决于你是否在SFR中写入1或0位位置。标志位就像“指示灯”,根据标志位是1还是0来指示给定条件是否存在。控制位直接控制硬件。标志位由硬件控制。在任何给定的程序中,我们通常在读取标志位的同时写入控制位(一些标志位必须通过手动写入来清除,这取决于微控制器……后面会详细介绍)。
微控制器上的每一块硬件将至少有一个SFR分配给它。一些硬件可能有几个SFR分配给它。请参阅微控制器的数据表以了解更多关于其特定SFR组织的信息。
配置部分
大多数微控制器都有被称为“配置位”的特殊位。这些位在微控制器上配置特殊选项,包括但不限于-
*振荡器类型
看门狗定时器开/关
*开启/关闭电源计时器
* Brown Out复位开关
*低电压编程开关
*故障安全时钟监视器打开/关闭
*内部/外部切换开关
在PIC单片机上,甚至还有用于程序代码保护和数据代码保护的配置位。这些位防止程序或数据空间被外部编程硬件读取,以防止其他人窃取您的代码。在Atmel AT89S芯片(8051派生)上,这是由所谓的“锁位”来设置的。
有些人把配置位称为“保险丝位”。这源于过去的微处理器,在芯片上有真正的“保险丝”,如果某些保险丝位控制功能关闭,就会爆炸。这些保险丝是“一次性可编程的”……一旦它们被吹断,就没有“恢复”它们的方法了。然而,随着现代微控制器上可用的闪存的出现,芯片上不再有字面意义上的“保险丝”了。但由于配置位本质上提供了与保险丝位相同的控制,这个术语本身被保留了下来。
算术逻辑单元(ALU)
这个硬件基本上负责由微控制器执行的所有数学和逻辑操作。在大多数微控制器上,ALU将有3个标志位与它相关联-
*零位-当数学运算结果为0时,该标志位被硬件设置为1。当一个数学运算结果为非零时,它将被硬件清除为0。
*携带/借一点-该标志位作为加法操作的进位,而作为减法操作的借位。当加法运算的结果大于寄存器所能容纳的值时,就会出现进位。一个8位寄存器可以容纳255(十六进制FF或二进制11111111)的最大值。
如果一个加法操作的结果大于255,进位标志将被设置为1。如果一个加法操作的结果小于255,则不会发生进位,因此进位标志将被清除为0。
对于减法操作,进位标志作为借位标志。borrow标志的作用与carry标志相反。如果减法操作结果为负,则borrow标志被清除为0。如果减法操作的结果是正的,则borrow标志设置为1。
*数字进位/借位-这个标志位和carry/borrow标志做同样的事情,但是它只用于指示carry/borrow是否只发生在第3位和第4位之间。
ALU标志位可以随时读取,以知道数学运算的结果是零、正/负、大于/小于,等等。
0位是一个方便的标志位,它允许我们比较两个值,看看它们是否相等。如果我们取两个数相减,如果相等,结果为零;如果不相等,结果为非零。因此,为了比较两个值,看看它们是否相等/不相等,我们将它们相减,然后读取/检查0位,看看该位是1还是0。如果0位= 1,则减法的结果为零,这意味着两个值相等。如果0位= 0,则减法的结果是非零的,这意味着两个值不相等。
carry/borrow位是一个方便的标志,它允许我们比较两个值,看看一个值是否大于/小于另一个值。例如,我们有两个值:VALUE1和VALUE2。在代码中,我们执行这个操作-
Value1 - value2 = value3
一旦执行了减法操作,我们就读取/检查进位/借位的高低状态。
如果VALUE2大于VALUE1,则减法的结果将为负,这将把进位/借位清除为0。如果VALUE2小于VALUE1,则减法的结果将为正,这将设置进位/借位为1。
查阅数据表了解哪些SFR包含这些位。在PIC微控制器上,ALU标志位驻留在STATUS SFR中。在MCS-51上,它们驻留在PSW SFR(程序状态字)中。
程序计数器
程序计数器是一个“地址指针”,它告诉CPU在哪里找到下一条指令要在程序ROM中执行。CPU将获取当前加载在程序计数器中的程序ROM地址中的指令。
当微控制器复位时,程序计数器初始化为0x0000。CPU将获取驻留在程序ROM地址0x0000的指令。一旦获取了这条指令,程序计数器自动增加到0x0001的值。程序计数器连续自动递增1,这导致CPU依次访问程序ROM中每个寄存器位置的内容。它一直这样做,直到CPU获取并执行了一条修改程序计数器值的指令。这样的指令是跳跃指令(在MCS-51上的ajmp和ljmp,在PIC上的goto),子程序调用(在MCS-51上的调用和lcall,在PIC上的调用),以及任何在程序计数器上加或减一个值的指令。
堆栈
微控制器上的堆栈主要在子程序调用和跳转到中断处理程序期间使用。这是一个“后进先出”的缓冲区,用于存储返回地址。在子例程调用期间,当前程序计数器地址被“推”到堆栈上,并给它加一个+1偏移量,然后用被调用的子例程所在的地址值修改程序计数器。这使得程序计数器跳转到子例程代码以执行子例程。
在子程序的末尾,会有一个“返回”指令(在MCS-51上ret,在PIC上return)。在执行返回指令时,堆栈被“弹出”,最后一个被推入堆栈的ROM地址值被弹出堆栈并返回到程序计数器中。这使得程序计数器返回指令之后的指令驻留,称为子程序(因此需要+ 1抵消当时个人电脑地址被压入堆栈),和程序执行前继续上次子程序调用。
有些微控制器有一个“软件栈”(MCS-51)。软件堆栈使用一些微控制器的内部RAM空间作为堆栈空间。其他的微控制器有一个硬件栈(PIC)。对于硬件堆栈,堆栈是独立于所有其他芯片内存空间的专用空间。
在一些微控制器上,堆栈是可写的。这允许我们在子例程调用和中断处理程序执行期间使用堆栈来临时备份关键寄存器。在执行子例程或中断处理程序之前,要备份的寄存器的内容被压入堆栈。然后,从子程序或中断处理程序返回之前,我们推到堆栈的内容的子例程将被弹出堆栈的一次,然后恢复到原来的位置在相反的顺序从如何推到堆栈(记得…后进先出)。
一个很好的例子是我们如何备份MCS-51上的累加器和PSW寄存器在执行中断处理程序的过程中
push ACC;将累加器备份到堆栈上
push PSW;将程序状态字备份到堆栈上
在这里执行中断处理程序代码
pop PSW;恢复程序状态字
pop ACC;恢复累加器
从中断返回到主代码
如你所见,我们首先将累加器的内容压入堆栈,然后将PSW的内容压入堆栈。然后执行中断处理程序代码。
在执行中断处理程序代码之后,PSW首先从堆栈中弹出,然后累加器在它之后从堆栈中弹出,顺序与它们被推入的顺序相反。
一个典型的SFR
一个典型的SFR设置如下所示。
|端口1 SFR |
———————————————————
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| p1.7 | p1.6 | p1.5 | p1.4 | p1.3 | p1.2 | p1.1 | p1.0 |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
这是用于并行端口1的MCS-51微控制器上的端口锁存器SFR。MCS-51上的每个端口是一个8位并行端口,端口SFR的每个位分配到端口上的每个引脚。P1.0是端口1上的引脚0,P1.1是端口1上的引脚1,P1.2是端口1上的引脚2,等等等等。
如图所示,我们将所有的零写到端口1锁存SFR的每个位上。这将把端口1上的所有引脚置于低状态(0伏)。如果我们将1写入任何端口SFR位,这将设置与我们在高状态(+5V)中写入“1”的位位置相关联的引脚。
例如,让我们将值01010101写入端口1 SFR -
|端口1 SFR |
———————————————————
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| p1.7 | p1.6 | p1.5 | p1.4 | p1.3 | p1.2 | p1.1 | p1.0 |
| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
如图所示,将P1.0、P1.2、P1.4和P1.6引脚置于高状态,而P1.1、P1.3、P1.5和P1.7引脚置于低状态。
一个关于数据表的词,以及为什么它们如此重要
并不是所有的微控制器都是一样的。每一个都是由芯片上的特定硬件设计的。不同制造商的微控制器都有不同的架构。你会发现PIC微控制器从通过mcs—51汇编语言有很大的不同微控制器通过mcs—51汇编语言一样大大不同于说摩托罗拉65 xx关于SFR的是如何实现的,RAM的数据是如何组织的,指令集,配置的话,并行端口是如何工作的,等等。
了解微控制器及其硬件如何工作的唯一方法是查阅其数据表。该数据表解释了每个SFR,芯片上的每一块硬件,绝对最大的电额定值,程序/数据存储组织,并行端口是如何连接和它们是如何工作的,指令集摘要(对于那些用汇编语言编码的人),等等等等。作为程序员,你需要了解的关于微控制器的几乎所有信息都在微控制器数据表中。
它们中的大多数都可以通过简单的谷歌搜索在网上免费获得(我还没有找到一个不是)。说你找不到数据表不是一个可以接受的借口。人们拒绝查阅数据表的唯一原因,要么是因为他们太懒,要么就是他们不懂,又不想让别人知道他们不懂。我现在要说的是,大多数关于微控制器的论坛问题都可以自己回答,只要人们花时间在数据表中查找答案。
数据表绝对是强制性的。没有它们,您将无法编写自己的代码。
关于作者
Jon Wilder是一名自由职业电子工程师和电子爱好者超过20年。他在美国海军当了四年的航空电子技术员。他从13岁开始弹吉他,从15岁开始将电子和音乐结合在一起。乔恩17岁时造出了他的第一个真空管放大器。“音乐电子产品”,乔恩说,是他的爱和激情。
乔恩也是一个频繁的贡献者和热情的成员Electro-Tech-Online工程社区。在Electro-Tech-Online从微控制器、可再生能源、汽车电子到电路模拟和设计,你可以向你的工程师同事提出问题并得到答案。此外,还有mcu特定的论坛8051/8951,AVR的,手臂,Arduino,Oshonsoft项目as well as也代码存储库成员共享代码片段。
在推特上关注乔恩@PICmcuguy.
《华盛顿邮报》微控制器的初学者指南第一次出现在微控制器的技巧.
了下:技术+产品,单片机的技巧,微处理器