跳到主要内容

SPI

前言

Core 提供 1 个 SPI 接口,分别对应管脚 CLK,MOSI,MISO,CS。引脚接口在 Core 上的分布如下图:

layout

一、SPI初始化

在使用 SPI 进行收发数据之前需要在 Lua 代码中执行一次 LIB_SpiMasterConfig() 初始化函数,LIB_SpiMasterConfig() 函数介绍如下:

函数名称:LIB_SpiMasterConfig(p1,p2,p3)

函数描述:配置Core的SPI接口以master模式开始工作,SPI使用Core的CLK,MOSI,MISO,CS引脚 注意:该函数只能调用一次

p1字符串类型,SPI时钟速率选择
"125K","250K","500K","1M","2M","4M","8M"
p2字符串类型,SPI通信模式选择,一般情况下Mode0和Mode3比较常用
"Mode0","Mode1","Mode2","Mode3"
"Mode0"CPOL=0 CPHA=0, SCK active high, Data sampled on the rising edge and shifted out on the falling edge
"Mode1"CPOL=0 CPHA=1, SCK active high, Data sampled on the falling edge and shifted out on the rising edge
"Mode2"CPOL=1 CPHA=0, SCK active low, Data sampled on the falling edge and shifted out on the rising edge
"Mode3"CPOL=1 CPHA=1, SCK active low, Data sampled on the rising edge and shifted out on the falling edge
p3字符串类型,发送数据高低位顺序选择,一般情况下都是先发送一个字节的最高位"MSB_First"
"MSB_First","LSB_First"

示例代码:

--使能SPI以master模式工作在模式0,时钟为4Mhz的频率,MSB_First:每次先发送字节里的最高位
LIB_SpiMasterConfig("4M","Mode0","MSB_First")

二、SPI发送和接收数据

SPI收发数据函数为LIB_SpiMstTransmit(),相关介绍如下:

函数名称:LIB_SpiMstTransmit(p1, ...)

函数描述:SPI主机开始发送和接收数据,需要注意的是每次收发的数据个数不能超过128个字节。

p1字符串类型,传输模式
"TxAndRx","TxThenRx","Tx","Rx"
"TxAndRx"全双工模式,发送和接收同时进行,即SPI主机发送出去多少字节,同时也会收到多少字节
"TxThenRx"单双工模式,SPI主机先发送数据,发送完后紧接着又开始接收数据
"Tx"单双工模式,SPI主机只发送数据
"Rx"单双工模式,SPI主机只接收数据

注意:不同传输模式(p1参数)下,函数 LIB_SpiMstTransmit() 的输入参数和返回值不一样,下面的例子会介绍不同模式下函数的调用方法

TxAndRx 类型传输的示例代码:

TxData = {1,2,3}
RxLen = 3
--全双模式,SPI主机发送3个数据同时接收3个数据
RxData = LIB_SpiMstTransmit("TxAndRx",TxData,RxLen)
print(string.format("Spi master had recv %d bytes data,Data[1]=%d,Data[2]=%d,Data[3]=%d", #RxData,RxData[1],RxData[2],RxData[3]))

TxThenRx 类型传输的示例代码:

TxData = {1,2,3}
RxLen = 3
--半双模式,SPI主机发送3个数据完成后,再紧接着接收3个数据
RxData = LIB_SpiMstTransmit("TxThenRx",TxData,RxLen)
print(string.format("Spi master had recv %d bytes data,Data[1]=%d,Data[2]=%d,Data[3]=%d", #RxData,RxData[1],RxData[2],RxData[3]))

Tx 类型传输的示例代码:

TxData = {1,2,3}
--半双模式,SPI主机仅发送3个数据
LIB_SpiMstTransmit("Tx",TxData)

Rx 类型传输的示例代码:

RxLen = 3
--半双模式,SPI主机仅接收3个数据
RxData = LIB_SpiMstTransmit("Rx",RxLen)
print(string.format("Spi master had recv %d bytes data,Data[1]=%d,Data[2]=%d,Data[3]=%d", #RxData,RxData[1],RxData[2],RxData[3]))

三、实例:SPI NorFlash 芯片厂商ID读操作

这里采用华邦W25QXX系列SPI接口NorFlash芯片模块作为演示实例:

1

下面我们通过读取W25QXX芯片的厂商ID以及其他信息,来展示Core的SPI接口使用方法

LIB_SpiMasterConfig("1M","Mode0","MSB_First")
--配置USB以虚拟串口模式工作
LIB_UsbConfig("CDC")
--开始大循环
while(GC(1) == true)
do
TxData = {0x9F}
RxLen = 3
--半双模式,SPI主机发送1个数据(0x9F指令)完成后,再紧接着自动接收3个数据
RxData = LIB_SpiMstTransmit("TxThenRx",TxData,RxLen)
print(string.format("ManufacturerID = 0x%02X,MemoryTypeID = 0x%02X,CapacityID = 0x%02X", RxData[1],RxData[2],RxData[3]))
LIB_DelayMs(1000)
end

代码运行结果如下图(可以看到厂商ID为0xEF,芯片类型ID为0x40,芯片容量类型为0x16):

2

附录:

W25QXX芯片数据手册中读取厂商代码的操作描述如下(更多信息请在华邦官网自行查阅W25QXX数据手册):

3