串行外設接口(Serial Peripheral Interface)是一種同步外設接口,它可以使單片機與各種外圍設備以串行方式進行通信以交換信息。SPI最早是Motorola公司提出的全雙工三線同步串行外圍接口,采用主從模式(Master—Slave)架構,支持一個或多個Slave設備,由於其簡單實用、性能優異,因此許多廠家的設備都支持該接口,廣泛應用於單片機和外設模塊之間的連接。
SPI接口只需4條線:串行時鍾線(SCK)、主機輸入/從機輸出數據線(MISO)、主機輸出/從機輸人數據線(MOSI)和低電平有效的從機選擇線(SS)。
(1)MISO:主設備輸入/從設備輸出引腳。該引腳在從模式下發送數據,在主模式下接收數據。
(2)MOSI:主設備輸出/從設備輸入引腳。該引腳在主模式下發送數據,在從模式下接收數據。
(3)SCK:串口時鍾,作為主設備的輸出,從設備的輸入。
(4)SS:從設備選擇。這是一個可選的引腳,用來選擇主/從設備。它的功能是用來作為片選引腳,讓主設備可以單獨地與特定從設備通信,避免數據線上的沖突。
SPI是一個環形總線結構,MOSI引腳相互連接,MISO引腳相互連接,數據在主和從之間串行地傳輸(MSB位在前),具體如下圖所示。
SPI有主從兩種工作模式,在主模式下,SPI為其他節點的CLK引腳提供串行時鍾,數據從MOSI引腳輸出,從MISO引腳輸入。在從模式下,數據從MISO引腳移出並由MOSI引腳移入,CLK引腳作為串行移位時鍾的輸入。
LPC824片內設計有SPI接口,具體的引腳取決於開關矩陣SWM的配置。
LPC824的SPI接口具有以下特點:
•直接支持1至16位的數據發送。軟件支持更大的幀。
•主機和從機操作。
•無需讀取輸入數據即可將數據發送至從機,這在設置SPI存儲器的時候很有用。
•控制信息還可與數據一同寫入,這樣便實現了極為豐富的操作,包括任意長度的幀。
•最多4個從機選擇輸入/輸出,極性可選且使用靈活。
•支持DMA傳輸,SPIn發送與接收功能可配合系統DMA控制器使用。
下圖是SPI接口的功能框圖。
在LPC824中,一共有兩組SPI接口,分別為SIP0和SPI1。其中SPI0組接口有7根引腳(SCK、MOSI、MISO及SSEL0~3),SPI1組接口有5根引腳(SCK、MOSI、MISO及SSEL0~1)。在默認狀態下,這些引腳並沒有被分配到芯片的物理引腳上,所以在使用SPI功能之前,需要先配置SWM矩陣,以把這些引腳部分或全部連接到物理引腳上。下面給出了這些引腳各自的SWM配置寄存器。
從上表中可以看出,兩個SPI接口的共12個引腳可以被分配到任意一個物理引腳上,涉及的配置寄存器為PINASSIGN3~PINASSIGN6共4個,接下來就分別給出這4個寄存的具體結構。
下表給出的是引腳分配寄存器PINASSIGN3的全部位結構,其字節地址為0x4000C00C。
(1)第0到7位為串口USART2中的請求發送端RTS分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(2)第8到15位為串口USART2中的清除發送端CTS分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(3)第16到23位為串口USART2中的同步時鍾端SCLK分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(4)第24到31位為SPI0接口中的時鍾端SCK分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
下表給出的是引腳分配寄存器PINASSIGN4的全部位結構,其字節地址為0x4000C010。
(1)第0到7位為SPI0接口中的主出從入端MOSI分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(2)第8到15位為SPI0接口中的主入從出端MISO分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(3)第16到23位為SPI0接口中的片選端SSEL0分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(4)第24到31位為SPI0接口中的片選端SSEL1分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
下表給出的是引腳分配寄存器PINASSIGN5的全部位結構,其字節地址為0x4000C014。
(1)第0到7位為SPI0接口中的片選端SSEL2分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(2)第8到15位為SPI0接口中的片選端SSEL3分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(3)第16到23位為SPI1接口中的時鍾端SCK分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(4)第24到31位為SPI1接口中的主出從入端MOSI分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
下表給出的是引腳分配寄存器PINASSIGN6的全部位結構,其字節地址為0x4000C018。
(1)第0到7位為SPI1接口中的主入從出端MISO分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(2)第8到15位為SPI1接口中的片選端SSEL0分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(3)第16到23位為SPI1接口中的片選端SSEL1分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
(4)第24到31位為多功能定時/計數器SCT的計數輸入端PIN0分配引腳,可選范圍從PIO0_0到PIO0_28一共29根引腳,默認為未分配狀態。
下表給出了SPI接口用到的全部寄存器描述。
由於LPC824的SPI接口功能很完善,所以涉及到的寄存器較多,它一共使用了11個寄存器來進行控制,應用上有些復雜。下面給出了上述寄存器對應的結構體定義。
typedef struct {
__IO uint32_t CFG;
__IO uint32_t DLY;
__IO uint32_t STAT;
__IO uint32_t INTENSET;
__O uint32_t INTENCLR;
__I uint32_t RXDAT;
__IO uint32_t TXDATCTL;
__IO uint32_t TXDAT;
__IO uint32_t TXCTL;
__IO uint32_t DIV;
__I uint32_t INTSTAT;
} LPC_SPI0_Type;
為了將2個SPI的基址指針強制轉換為上述結構體,還要加上下面的定義。
#define LPC_SPI0_BASE 0x40058000UL
#define LPC_SPI1_BASE 0x4005C000UL
#define LPC_SPI0 ((LPC_SPI0_Type *) LPC_SPI0_BASE)
#define LPC_SPI1 ((LPC_SPI0_Type *) LPC_SPI1_BASE)
SPI接口涉及到的寄存器較多,后面會對它們進行具體分析。
--待續--