对,所以我们目前在这个世界上有 8 位、16 位和 32 位微控制器。所有这些都经常使用。编程 8 位和 16 位微控制器有何不同?我的意思是,它需要不同的技术或技能吗?让我们以微芯片为例。如果一个人想要从 8 位微控制器过渡到 32 位微控制器,需要学习哪些新东西?
8 位微控制器与 32 位微控制器在编程方面有何不同
一般来说,从 8 位微控制器到 16 位微控制器再到 32 位微控制器意味着您将对资源(尤其是内存)以及用于进行算术和逻辑运算的寄存器宽度的限制更少。8、16 和 32 位名字对象通常指内部和外部数据总线的大小以及用于算术和逻辑运算的内部寄存器的大小(过去只有一个或两个称为累加器) ,现在通常有 16 个或 32 个寄存器组)。
I/O 端口的端口大小通常也遵循数据总线的大小,因此 8 位微控制器将具有 8 位端口,16 位将具有 16 位端口等。
尽管有一个 8 位数据总线,但许多 8 位微控制器有一个 16 位地址总线,并且可以寻址 2^16 或 64K 字节的内存(这并不意味着它们有任何接近实现的地方)。但是一些 8 位微控制器,如低端 PIC,可能只有非常有限的 RAM 空间(例如 PIC16 上的 96 字节)。
为了解决它们有限的寻址方案,一些 8 位微控制器使用分页,其中页寄存器的内容决定了要使用的几个内存库之一。无论页面寄存器设置为什么,通常都会有一些公共 RAM 可用。
16 位微控制器通常限制为 64K 内存,但也可以使用分页技术来解决这个问题。32 位微控制器当然没有这样的限制,最多可以寻址 4GB 的内存。
随着不同的内存大小是堆栈大小。在低端微控制器中,这可以在内存的特殊区域中实现并且非常小(许多 PIC16 具有 8 级深调用堆栈)。在 16 位和 32 位微控制器中,堆栈通常是一般的 RAM,并且仅受 RAM 大小的限制。
在各种设备上实现的内存量(程序和 RAM)也存在巨大差异。8 位微控制器可能只有几百字节的 RAM 和几千字节的程序存储器(或者更少——例如 PIC10F320 只有 256 个 14 位字的闪存和 64 字节的 RAM)。16 位微控制器可能有几千字节的 RAM 和几万字节的程序存储器。32 位微控制器通常有超过 64K 字节的 RAM,可能有 1/2 MB 或更多的程序存储器(PIC32MZ2048 有 2 MB 的闪存和 512KB 的 RAM;新发布的 PIC32MZ2064DAH176,针对图形进行了优化,有 2 MB 的闪存和高达 32MB 的片上 RAM)。
如果您使用汇编语言进行编程,那么寄存器大小的限制将非常明显,例如添加两个 32 位数字在 8 位微控制器上是一件苦差事,但在 32 位微控制器上却微不足道。如果您使用 C 编程,这将在很大程度上是透明的,但当然,对于 8 位,底层编译代码会大得多。
我说的基本上是透明的,因为各种 C 数据类型的大小可能因大小而异;例如,针对 8 位或 16 位 micro 的编译器可能使用“int”来表示 16 位有符号变量,而在 32 位 micro 上,这将是一个 32 位变量。所以很多程序使用#defines 来明确说明所需的大小是多少,例如“UINT16”表示一个无符号的 16 位变量。
如果您使用 C 编程,最大的影响将是变量的大小。例如,如果你知道一个变量总是小于 256(如果有符号则在 -128 到 127 范围内),那么你应该在 8 位微控制器上使用 8 位(无符号字符或字符)(例如 PIC16 ) 因为使用更大的尺寸会非常低效。同样,16 位微控制器(例如 PIC24)上的 16 位变量。如果您使用的是 32 位 micro (PIC32),那么它并没有任何区别,因为 MIPS 指令集具有字节、字和双字指令。但是,在某些 32 位微控制器上,如果它们缺少此类指令,则由于屏蔽,操作 8 位变量的效率可能低于 32 位变量。
正如论坛成员 vsz 指出的那样,在您有一个大于默认寄存器大小的变量(例如 8 位微控制器上的 16 位变量)的系统上,并且该变量在两个线程之间或在基本线程之间共享和中断处理程序,必须对变量atomic进行任何操作(包括读取),即使其看起来像一条指令完成。这称为临界区。缓解这种情况的标准方法是用禁用/启用中断对围绕关键部分。
因此,从 32 位系统到 16 位,或 16 位到 8 位,对这种类型的变量的任何操作现在大于默认寄存器大小(但以前不是)都需要被视为关键部分。
从一个 PIC 处理器到另一个 PIC 处理器的另一个主要区别是外围设备的处理。这与字长的关系不大,而与分配在每个芯片上的资源的类型和数量有关。一般来说,Microchip 试图使跨不同芯片使用的相同外设的编程尽可能相似(例如 timer0),但总会有差异。使用他们的外围库将在很大程度上隐藏这些差异。最后一个区别是中断的处理。Microchip 库再次提供了帮助。
8 位和 32 位微控制器之间的一个常见区别是,8 位微控制器通常具有一系列内存和 I/O 空间,无论执行上下文如何,都可以在一条指令中访问这些空间,而 32 位微控制器通常会需要一个多指令序列。例如,在典型的 8 位微控制器(HC05、8051、PIC-18F 等)上,可以使用一条指令更改端口位的状态。在典型的 ARM(32 位)上,如果寄存器内容最初是未知的,则需要一个四指令指令序列:
ldr r0,=GPIOA
ldrh r1,[r0+GPIO_DDR]
ior r1,#64
strh r1,[r0+GPIO_DDR]
在大多数项目中,控制器将把大部分时间花在设置或清除单个 I/O 位之外的事情上,因此清除端口引脚等操作需要更多指令这一事实通常并不重要。另一方面,有时代码将不得不“大爆炸”地进行大量端口操作,而用一条指令完成这些事情的能力证明是非常有价值的。
另一方面,32 位控制器总是被设计为有效访问可存储在内存中的多种数据结构。相比之下,许多 8 位控制器在访问非静态分配的数据结构时效率非常低。一个 32 位控制器可以在一条指令中执行一个数组访问,而这在一个典型的 8 位控制器上需要六条或更多指令。
最大的实际区别是文档的数量,实际上,要完全理解整个芯片。市面上有 8 位微控制器,其中包含近 1000 页的文档。相比之下,1980 年代的 8 位 CPU 和它所使用的流行外围芯片大约需要 200-300 页。一个外设丰富的 32 位设备将需要您阅读 2000-10,000 页的文档才能理解该部件。具有现代 3D 图形的部件在 20k 页的文档中占据优势。
根据我的经验,了解给定现代 32 位控制器的所有信息所需的时间大约是了解现代 8 位部分所需的 10 倍。我所说的“一切”是指您知道如何使用所有外围设备,甚至以非常规的方式,并且了解机器语言、平台使用的汇编程序以及其他工具、ABI 等。
很多很多设计都是在部分理解的情况下完成的,这根本不是不可想象的。有时它无关紧要,有时则不然。转换平台时必须了解,您会为从更强大的架构中获得的生产力收益付出短期和中期的生产力代价。尽职尽责。
我个人不会太担心同一家族的升级(8 位-> 32 位)uC,而且您正在全面增加规格。一般来说,我不会对数据类型做任何不规范的事情,因为以后很难维护。
降级设备代码是另一回事。