1、SPI 总线在 51 系列单片机系统中的实现摘要:MCS51 系列、MCS96 系列等单片机由于都不带 SPI 串行总线接口而限制了其在 SPI 总线接口器件的使用。文中介绍了 SPI 串行总线的特征和时序,并以串行 E2PROM 为例,给出了在 51 系列单片机上利用 I/O口线实现 SPI 串行总线接口的方法和软件设计程序。 关键词:单片机 SPI 串行总线 总线接口1 引言SPI(Serial Peripheral Interface-串行外设接口)总线系统是一种同步串行外设接口,它可以使 MCU 与各种外围设备以串行方式进行通信以交换信息。外围设置 FLASHRAM、网络控制器、LCD
2、 显示驱动器、A/D 转换器和 MCU 等。SPI 总线系统可直接与各个厂家生产的多种标准外围器件直接接口,该接口一般使用 4 条线:串行时钟线(SCK) 、主机输入/从机输出数据线 MISO、主机输出/从机输入数据线 MOST 和低电平有效的从机选择线 SS(有的 SPI 接口芯片带有中断信号线 INT 或 INT、有的 SPI 接口芯片没有主机输出/从机输入数据线 MOSI)。由于 SPI 系统总线一共只需34 位数据线和控制即可实现与具有 SPI 总线接口功能的各种 I/O 器件进行接口,而扩展并行总线则需要 8 根数据线、816 位地址线、23位控制线,因此,采用 SPI 总线接口可以
3、简化电路设计,节省很多常规电路中的接口器件和 I/O 口线,提高设计的可靠性。由此可见,在 MCS51系列等不具有 SPI 接口的单片机组成的智能仪器和工业测控系统中,当传输速度要求不是太高时,使用 SPI 总线可以增加应用系统接口器件的种类,提高应用系统的性能。2 SPI 总线的组成利用 SPI 总线可在软件的控制下构成各种系统。如 1 个主 MCU 和几个从MCU、几个从 MCU 相互连接构成多主机系统(分布式系统) 、1 个主 MCU和 1 个或几个从 I/O 设备所构成的各种系统等。在大多数应用场合,可使用 1 个 MCU 作为控机来控制数据,并向 1 个或几个从外围器件传送该数据。从
4、器件只有在主机发命令时才能接收或发送数据。其数据的传输格式是高位(MSB)在前,低位(LSB)在后。SPI 总线接口系统的典型结构如图 1 所示。当一个主控机通过 SPI 与几种不同的串行 I/O 芯片相连时,必须使用每片的允许控制端,这可通过 MCU 的 I/O 端口输出线来实现。但应特别注意这些串行 I/O 芯片的输入输出特性:首先是输入芯片的串行数据输出是否有三态控制端。平时未选中芯片时,输出端应处于高阻态。若没有三态控制端,则应外加三态门。否则 MCU 的 MISO 端只能连接 1 个输入芯片。其次是输出芯片的串行数据输入是否有允许控制端。因此只有在此芯片允许时,SCK 脉冲才把串行数
5、据移入该芯片;在禁止时,SCK 对芯片无影响。若没有允许控制端,则应在外围用门电路对 SCK 进行控制,然后再加到芯片的时钟输入端;当然,也可以只在 SPI 总线上连接 1 个芯片,而不再连接其它输入或输出芯片。3 在 MCS51 系列单片机中的实现方法对于不带 SPI 串行总线接口的 MCS51 系列单片机来说,可以使用软件来模拟 SPI 的操作,包括串行时钟、数据输入和数据输出。对于不同的串行接口外围芯片,它们的时钟时序是不同的。对于在 SCK 的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件,一般应将其串行时钟输出口 P1.1 的初始状态设置为 1,而在允许接口后再置 P1.1
6、为 0。这样,MCU 在输出 1 位 SCK 时钟的同时,将使接口芯片串行左移,从而输出1 位数据至 MCS51 单片机的 P1.3 口(模拟 MCU 的 MISO 线) ,此后再置 P1.1为 1,使 MCS51 系列单片机从 P1.0(模拟 MCU 的 MOSI 线)输出 1 位数据(先为高位)至串行接口芯片。至此,模拟 1 位数据输入输出便宣告完成。此后再置 P1.1 为 0,模拟下 1 位数据的输入输出,依此循环 8次,即可完成 1 次通过 SPI 总线传输 8 位数据的操作。对于在 SCK 的下降沿输入数据和上升沿输出数据的器件,则应取串行时钟输出的初始状态为 0,即在接口芯片允许时
7、,先置 P1.1 为 1,以便外围接口芯片输出1 位数据(MCU 接收 1 位数据) ,之后再置时钟为 0,使外围接口芯片接收1 位数据(MCU 发送 1 位数据),从而完成 1 位数据的传送。图 2 所示为 MCS51 系列单片机与存储器 X25F008(E2PROM)的硬件连接图,图 2 中,P1.0 模拟 MCU 的数据输出端(MOSI) ,P1.1 模拟 SPI 的 SCK 输出端,P1.2 模拟 SPI 的从机选择端,P1.3 模拟 SPI 的数据输入端(MISO) 。下面介绍用 MCS51 单片机的汇编语言模拟 SPI 串行输入、串行输出和串行输入/输出的 3 个子程序,实际上,这
8、些子程序也适用于在串行时钟的上升沿输入和下降沿输出的其它各种串行外围接口芯片(如 A/D转换芯片、网络控制器芯片、LED 显示驱动芯片等) 。对于下降沿输入、上升沿输出的各种串行外围接口芯片,只要改变 P1.1 的输出电平顺序,即先置 P1.1 为低电平,之后再次置 P1.1 为高电平,再置 P1.1 为低电平,则这些子程序也同样适用。3.1 MCU 串行输入子程序 SPIIN从 X25F008 的 SPISO 线上接收 8 位数据并放入寄存器 R0 中的应用子程序如下:SPIIN:SETB P1.1 ;使 P1.1(时钟)输出为 1CLR P1.2 ;选择从机MOV R1,#08H ;置循环
9、次数SPIIN1:CLR P1.1 ;使 P1.1(时钟)输出为 0NOP ;延时NOPMOV C,P1.3 ;从机输出 SPISO 送进位 CRLC A ;左移至累加器 ACCSETB P1.1 ;使 P1.0(时钟)输出为 1DJNZ R1,SPIIN1 ;判断是否循环 8 次(8 位数据)MOV R0,A ;8 位数据送 R0RET3.2 MCU 串行输出子程序 SPIOUT将 MCS51 单片机中 R0 寄存器的内容传送到 X25F008 的 SPISI 线上的程序如下:SPIOUT:SETB P1.1 ;使 P1.1(时钟)输出为 1CLR P1.2 ;选择从机MOV R1,#08H
10、 ;置循环次数MOV A,R0 ;8 位数据送累加器 ACCSPIOUT1:CLR P1.1 ;使 P1.1(时钟)输出为 0NOP ;延时NOPRLC A ;左移至累加器 ACC 最高位至 CMOV P1.0,C ;进位 C 送从机输入 SPISI 线上SETB P1.1 ;使 P1.1(时钟)输出为 1DJNZ R1,SPIOUT1 ;判是否循环 8 次(8 位数据)RET3.3 MCU 串行输入/输出子程序 SPIIO将 MCS51 单片机 R0 寄存器的内容传送到 X25F008 的 SPISI 中,同时从X25F008 的 SPISO 接收 8 位数据的程序如下:SPIIO:SETB
11、 P1.1 ;使 P1.1(时钟)输出为 1CLR P1.2 ;选择从机MOV R1,#08H ;置循环次数MOV A,R0 ;8 位数据送累加器 ACCSPIIO1:CLR P1.1 ;使 P1.1(时钟)输出为 0NOP ;延时NOPMOV C,P1.3 ;从机输出 SPISO 送进位 CRLC A ;左移至累加器 ACC 最高位至 CMOV P1.0,C ;进位 C 送从机输入SETB P1.1 ;使 P1.1(时钟)输出为 1DJNZ R1,SPIIO1 ;判断是否循环 8 次(8 位数据)RET4 结束语本文介绍了通过 SPI 总线接口实现数据传输的实现方法,给出了用 MCS51单片机汇编语言模拟 SPI 串行总线的输入、输出,输入/输出以传送 8 位数据的子程序。实际上,也可以根据 SPI 串行总线的操作时序特点来在MCS96 系列、ATMEL89 系列等单片机上实现 SPI 总线的接口。