目錄
概述
1 SPI相關的寄存器
1.1 SPI的框架結構
1.2 功能描述
1.3 SPI Master模式引腳配置
1.4 SPI Master模式下的時序
2 SPI相關的寄存器?
2.1?Instances
2.2 詳細寄存器定義
2.3?SPI master interface特性
3 Zephyr 平臺下SPI功能時序(寄存器)
3.1 寄存器的文件地址
?3.2 SPI驅動實現
3.3 源代碼
概述
本文詳細介紹了nRF52832芯片的SPI接口寄存器配置與功能實現。主要內容包括:1)SPI主設備框架結構,重點說明雙緩沖TXD/RXD寄存器的工作機制;2)SPI主模式下的引腳配置(SCK/MOSI/MISO)與時序控制要求;3)給出了完整的寄存器定義表,涵蓋使能、引腳選擇、頻率配置等關鍵寄存器;4)基于Zephyr平臺提供了SPI驅動實現方案,包含初始化代碼、數據傳輸函數及芯片選擇控制邏輯,并附有完整的源代碼示例。特別強調SPI主設備不直接支持片選功能,需通過GPIO獨立控制從設備選擇。
1 SPI相關的寄存器
1.1 SPI的框架結構
SPI 主設備提供了一個簡單的 CPU 接口,其中包括用于發送數據的 TXD 寄存器和用于接收數據的 RXD 寄存器。
1.2 功能描述
TXD和RXD寄存器是雙緩沖的,以便在一定程度上允許不間斷的數據流進出SPI主機。SPI主控不直接實現對芯片選擇的支持。因此,CPU必須使用可用的 gpio來選擇正確的從站,并獨立于SPI主站進行控制。SPI主機支持 SPI模式0 ~ 3。
SPI 工作列表
1.3 SPI Master模式引腳配置
與SPI主控相關聯的不同信號SCK、MOSI和MISO被映射到物理引腳。該映射分別根據PSELSCK、PSELMOSI和PSELMISO 寄存器中指定的配置。如果在這些寄存器中指定了0xFFFFFFFF的值,則相關的SPI 主信號不會連接到任何物理引腳。
PSELSCK、PSELMOSI和PSELMISO寄存器 及其配置僅在SPI主設備啟用時使用,并且僅在 設備處于ON模式時保留。
1.4 SPI Master模式下的時序
SPI主事務通過將第一個字節寫入 TXD寄存器來啟動,該字節將由SPI主服務器傳輸。由于發送器是雙緩沖的,第二個字節可以在第一個字節 之后立即寫入TXD寄存器。然后SPI主機將按照寫入TXD寄存器的順序發送這些字節。
SPI主控將傳入的字節移動到RXD寄存器后,隨著SCK時鐘 在字節的最后一位周期的短暫延遲。這也意味著READY事件將相應地延遲,參見下圖的SPI主事務。因此,務必始終清除 READY事件,即使沒有使用RXD寄存器和正在接收的數據。
2 SPI相關的寄存器?
2.1?Instances
nRF52832總共有3個SPI接口可供使用
和SPI相關的寄存器總表
2.2 詳細寄存器定義
1)Enable interrupt
2)?Disable interrupt
3)?Enable SPI
4)?PSELSCK
5)?PSELMOSI
6)?PSELMISO
7) RXD
8)?TXD
9)?FREQUENCY
?10)?CONFIG
2.3?SPI master interface特性
1)?SPI master interface的電器特性
2)?SPI master interface的時序
3 Zephyr 平臺下SPI功能時序(寄存器)
Zephyr OS下定義的SPI寄存器數據結構
3.1 寄存器的文件地址
D:\ncs\v2.9.0\modules\hal\nordic\nrfx\hal\nrf_spi.h
D:\ncs\v2.9.0\modules\hal\nordic\nrfx\drivers\include\nrfx_spim.h
?使用寄存器時,必須在.c文件中引用如下兩個頭文件:
#include <hal/nrf_spi.h>
#include <nrfx_spim.h>
?3.2 SPI驅動實現
1) 初始化SPI接口
2) SPI相關的接口配置
3)數據傳輸函數
4)芯片使能引腳
3.3 源代碼
#include <zephyr/kernel.h>
#include <hal/nrf_spi.h>
#include <nrfx_spim.h>/*psels = <NRF_PSEL(SPIS_SCK, 0, 27)>,<NRF_PSEL(SPIS_MISO, 0, 28)>,<NRF_PSEL(SPIS_MOSI, 0, 26)>,<NRF_PSEL(SPIS_CSN, 0, 24)>;
*/#define SPI_SCK_PIN 27
#define SPI_MOSI_PIN 26
#define SPI_MISO_PIN 28#define SPI_OBJ NRF_SPI2Flash_Info flash_Info_Obj;void spi_init( void )
{// 1 enable POWER dk_set_led(CTRL_FLASH_POWER_PIN, 1);// 1 選擇SPI引腳SPI_OBJ->PSEL.SCK = SPI_SCK_PIN;SPI_OBJ->PSEL.MOSI = SPI_MOSI_PIN;SPI_OBJ->PSEL.MISO = SPI_MISO_PIN;// 2. 配置 SPI 模式 (模式0)NRF_SPI0->CONFIG = (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos) |(SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos);SPI_OBJ->FREQUENCY = NRF_SPI_FREQ_4M; // 4 MHz// 使能SPISPI_OBJ->ENABLE = SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos;
}u8 spi_transfer_byte( u8 data )
{SPI_OBJ->EVENTS_READY = 0; // 清除就緒事件// 發送數據SPI_OBJ->TXD = data;// 等待發送完成while(!SPI_OBJ->EVENTS_READY);// 清除事件標志SPI_OBJ->EVENTS_READY = 0;// 讀取接收到的數據(如果需要)return (u8)SPI_OBJ->RXD; // 返回接收數據
}/**** @brief select the flash chip * * @details en = true, select the chip* en = false, release the chip* * @ingroup spi flash driver */
void spi_cs_ctrl( bool en )
{if( en )dk_set_led(CTRL_FLASH_PIN, 0); // cs is enable elsedk_set_led(CTRL_FLASH_PIN, 1);
}