快速 SPI 端口可通过 GPIO 引脚进行位冲击,并作为具有 SPI 端口的 8051 兼容微控制器的低成本替代方案。本应用笔记所示的代码利用8051特有的特性,使用最少的额外代码创建快速SPI端口。
虽然可以使用带有SPI端口的8051兼容微控制器,但具有SPI端口通过GPIO引脚位敲击的低成本器件通常足以满足许多应用的需求。此处显示的代码利用特定于 8051 内核的功能,以最小的工作量创建快速 SPI 端口。#define语句中的 CPHA、CPOL 和CS_TOGGLE_BETWEEN_BYTES常量初始化宏,这些宏根据正在实现的 SPI 端口类型定制代码。 预处理器在编译时而不是运行时执行此代码定制,从而节省了宝贵的时钟周期,如果使用决策结构(即常规的 if-else 语句),这些周期将被浪费。
下面的代码包括利用 8051 内核功能所需的特定于 8051 的 C 命令。尽管这些命令是特定于编译器的(在本例中为 8051 的 Keil μVision v2 开发工具),但所有适用于 8051 兼容设备的“好”C 编译器都包含类似的命令。
检查代码,PORT_0定义为 sfr 类型,它提醒编译器此标签是 8051 特殊功能寄存器 (SFR)。由于此 SFR 是位可寻址的,因此 sbit 类型定义引用特定 SFR 位以充当 SPI 端口引脚的标识符。spiTmp 声明中使用的 bdata 类型允许将此变量放置在 8051 内核的直接可寻址 RAM 内的特殊位可寻址内存中。同样,sbit 类型定义了将引用 spiTmp 变量中特定位的标识符。
要通过 SPI 端口发送的字节将加载到全局字节数组 spiData 中。将此变量声明为全局变量允许 SPI 发送/接收函数访问 spiData,而无需将其作为参数传递。使用数据标识符声明它强制编译器将数组存储在 8051 内核内最快的可访问内存(直接可寻址内存)中。
spiReadWriteBlock 函数包含位撞击 SPI 端口的代码。它使用此 SPI 端口有效地传输 spiData 数组中的每个字节,从数组中的最后一个元素到第一个元素。使用此反向顺序访问数组允许与零进行比较(请参阅代码),由于 8051 指令集,这意味着更快的组装。当 spiReadWriteBlock 函数完成时,使用 SPI 端口读取的字节将替换 spiData 数组中的原始数据,再次从数组中的最后一个元素开始到第一个元素。
请注意,代码经过优化,可以发送和接收大于一个字节的数据块。对于单字节传输,应删除 spiReadWriteBlock 中的循环结构和局部变量。(这可以使用预处理器完成。
当针对Maxim DS89C430/450系列8051兼容微控制器进行编译时,该位撞击式SPI端口的运行速度略高于2Mbps,如图1所示。此外,该代码只需要两个字节的可直接寻址RAM和139字节的闪存用于代码空间(包括SPI端口初始化和主程序循环)。
图1.这些波形表示当CPHA、CPOL和CS_TOGGLE_BETWEEN_BYTES常数设置为1时,位撞击SPI端口的输出。此固件使用 8051 内核中的位可寻址存储器来提高 SPI 端口的速度。