跳转至

spi - spi操作库

作者:马亚丹

一、概述

SPI( Serial Peripheral Interface,串行外设接口):是一种同步串行通信协议,主要用于嵌入式系统中,微控制器与各外设之间的短距离高速通信。

SPI 的通信是主从架构,即一主多从,其协议层面没有总线仲裁、冲突检测等机制,所以 SPI 系统不适合存在多个主设备,只能有一个主机。标准的 SPI 有四根信号线:

  • SCLK(Serial Clock):时钟线,由主设备唯一控制,决定数据传输的节奏。
  • MOSI(Master Output, Slave Input):主线输出 / 从线输入,主设备通过此线向从设备发送数据。
  • MISO(Master Input, Slave Output):主线输入 / 从线输出,从设备通过此线向主设备返回数据。
  • CS(Chip Select ,又称 SS:Slave Select):从设备选择线(低电平有效),主设备通过拉低某从设备的 CS 脚,指定与哪个从设备通信(同一总线上可接多个从设备,需独立 CS)。同一时间只能有一个从设备的 CS 被拉低,对总设备来说 CS 只能是输入状态。

SPI 总线的通信速率范围很广,常见的速率为 1MHz,5MHz,10MHz,20MHz,以合宙 Air780EPM 模组为例,最高支持 25.6Mbps 的 SPI 速率。

二、核心示例(缺少实操示例)

1、核心示例是指:使用本库文件提供的核心 API,开发的基础业务逻辑的演示代码;

2、核心示例的作用是:帮助开发者快速理解如何使用本库,所以核心示例的逻辑都比较简单;

3、更加完整和详细的 demo,请参考 LuatOS 仓库 中各个产品目录下的 demo/spi

-- 本库支持2套API风格
-- 1. 老的API,spi.xxx 方式,需要自己控制软件cs引脚,不同设备要手动重新配置spi参数
-- 2. 新的API(推荐使用), spidevice对象方式,不需要手动控制cs引脚,不同设备也无需重复配置参数,设备内部自动管理

--以下发送0x9F指令读取nor flash芯片id为例,用新老API演示核心示例

-- 老API示例log:
--I/user.硬件spi初始化结果: 0
--I/user.发送结果: 1
--I/user.spi0接收到flash的id:239 64 24
--I/user.关闭spi0结果:0
-- CS引脚,根据实际情况修改
local CS_PIN = 8  
--CS脚置于高电平                 
local cspin = gpio.setup(CS_PIN, 1) 
local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)    
log.info("硬件spi初始化结果:",spiDevice)
local function sendRecv(data, len)
    local recv_result = ""
    --cs拉低进行数据传输
    cspin(0)
    if data then
        local send_result = spi.send(0, data)
        log.info("发送结果:", send_result)
    end
    if len then
        local recv_result = spi.recv(0, len)
        --传输完成拉高cs
        cspin(1)         
        local b1, b2, b3 = recv_result:byte(1, 3)
        log.info("spi0接收到flash的id:", b1, b2, b3)
    end   
end
sys.taskInit(sendRecv, string.char(0x9F), 3)
log.info("关闭spi0结果:",spi.close(0)

-- 新API示例log:
-- I/user.硬件spi初始化结果: SPI*: 0C7F59D0
--I/user.发送结果: 1
--I/user.spi0接收到flash的id:239 64 24
--I/user.关闭spi0结果:0
local spi_device= spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)    
log.info("硬件spi初始化结果:",spi_device)
local function sendRecv(data, len)
    local recv_result = ""
    if data then
        local send_result = spi_device:send(data)
        log.info("发送结果:", send_result)
    end
    if len then
        local recv_result = spi_device:recv(len)            
        local b1, b2, b3 = recv_result:byte(1, 3)
    log.info("spi0接收到flash的id:", b1, b2, b3)
    end   
end
sys.taskInit(sendRecv, string.char(0x9F), 3)
log.info("关闭spi0结果:",spi_device:close()

三、常量详解

核心库常量,顾名思义是由合宙 LuatOS 内核固件中定义的、不可重新赋值或修改的固定值,在脚本代码中不需要声明,可直接调用;

3.1 spi.MSB

常量含义:大端模式,按最高有效位优先的顺序传输数据
数据类型:number
取值范围:0
示例代码:-- 如下方所示,为spi.MSB常量的基本写法
       local spi_device = spi.deviceSetup(
               spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

3.2 spi.LSB

常量含义:小端模式,按最低有效位优先的顺序传输数据
数据类型:number
取值范围:1
示例代码:-- 如下方所示,为spi.LSB常量的基本写法
        local spi_device = spi.deviceSetup(
              spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.LSB,   -- 低位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

3.3 spi.master

常量含义:主机模式,设置当前设备为主机
数据类型:number
取值范围:1
示例代码:-- 如下方所示,为spi.master常量的基本写法
         local spi_device = spi.deviceSetup(
               spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

3.4 spi.slave

常量含义:从机模式,设置当前设备为从机
数据类型:number
取值范围:0
示例代码:-- 如下方所示,为spi.slave常量的基本写法
        local spi_device = spi.deviceSetup(
               spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.slave, -- 从机模式
               spi.full)  -- 全双工模式

3.5 spi.full

常量含义:全双工模式,设置通讯模式为全双工
数据类型:number
取值范围:1
示例代码:-- 如下方所示,为spi.full常量的基本写法
       local spi_device = spi.deviceSetup(
               spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

3.6 spi.half

常量含义:半双工模式,设置通讯模式为半双工
数据类型:number
取值范围:0
示例代码:-- 如下方所示,为spi.half常量的基本写法
      local spi_device = spi.deviceSetup(
               spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.half) -- 半双工模式

3.7 spi.SPI_0

常量含义:SPI0的总线ID号
数据类型:number
取值范围:0
示例代码:-- 如下方所示,为spi.slave常量的基本写法
        local spi_device = spi.deviceSetup(
               spi.SPI_0, -- SPI总线ID为0
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

3.8 spi.SPI_1

常量含义:SPI1的总线ID号
数据类型:number
取值范围:1
示例代码:-- 如下方所示,为spi.slave常量的基本写法
        local spi_device = spi.deviceSetup(
               spi.SPI_1, -- SPI总线ID为1
               8,         -- CS管脚
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               2000000,   -- 波特率(Hz),初始化为2MHz
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

四、函数详解

4.1 spi.setup(id, cs, CPHA, CPOL, dataw, bandrate, bitdict, master_slave, mode)

功能

设置并启用硬件 SPI 总线

注意事项

这个接口是旧方式,相对于下述的 spi.deviceSetup 新接口方式固件会自动管理控制 cs 引脚,这个老接口使用过程需要自己控制软件 cs 引脚,不同设备在使用 send(),recv()和 transfer()接口时要手动配置 spi 的 id 参数.

具体使用看下述 spi.send(),spi.recv()和 spi.transfer()接口的用法

例如:local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

--如下方所示,send 接口需要写 spi 的 id 号必须要配置

local result = spi.send(0, "123")--发送 123

参数

id

参数含义:SPI的总线ID号
数据类型:number
取值范围:spi.SPI_0/spi.SPI_1
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1
参数示例:--如下方所示,第一个参数spi.SPI_0为初始化spi时的id
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

cs

参数含义:SPI总线的CS片选引脚对应的GPIO编号
数据类型:number
取值范围:根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:该接口需要自己手动控制软件cs引脚
参数示例:--如下方所示,第二个参数CS_PIN为初始化spi时的cs,传输数据前后手动拉低拉高cs脚
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
         gpio.setup(CS_PIN, 0) 
         ....
         gpio.setup(CS_PIN, 1)

CPHA

参数含义:SPI总线的时钟相位,决定数据采样的时钟边沿,
数据类型:number
取值范围:nil,空值,0/1
是否必选:非必须,nil和空都是默认0
注意事项:当CPOL值为0时
         0是表示数据在SCK上升沿(第一边沿)采样,
         1是表示数据在SCK下降沿(第二边沿)采样。
         CPOL值为1时
         0是表示数据在SCK下降沿(第一边沿)采样,
         1是表示数据在SCK上升沿(第二边沿)采样。
参数示例:--如下方所示,第三个参数0为初始化spi时的CPHA
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

CPOL

参数含义:SPI总线的时钟极性,决定时钟SCK在空闲时的电平状态
数据类型:number
取值范围:nil,空值,0/1
是否必选:非必须,nil和空都是默认0
注意事项:0表示时钟SCK在空闲时的电平状态是低电平
         1表示时钟SCK在空闲时的电平状态是高电平
参数示例:--如下方所示,第四个参数0为初始化spi时的CPOL
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

dataw

参数含义:SPI总线的数据宽度(位)
数据类型:number
取值范围:nil,空值,481632等常见取值
是否必选:非必须,nil和空值是默认8bit
注意事项:暂无
参数示例:--如下方所示,第五个参数8为初始化spi时的dataw
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

bandrate

参数含义:SPI总线的波特率
数据类型:number
取值范围:nil,空值,其他常用取值
是否必选:非必须,默认2M=2000000
注意事项:合宙Air780EPM系列和Air8000系列模组的波特率最高是25.6Mbps
参数示例:--如下方所示,第六个参数2000000为初始化spi时的bandrate
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

bitdict

参数含义:设置SPI总线的大小端模式
数据类型:number
取值范围:nil,空值,spi.MSB/1spi.LSB/0
是否必选:非必须,默认spi.MSB/1
注意事项:spi.MSB是大端模式
         spi.LSB是小端模式
参数示例:--如下方所示,第七个参数spi.MSB为初始化spi时的bitdict
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

master_slave

参数含义:设置SPI总线的主从模式
数据类型:number
取值范围:nil,空值,spi.master/1,spi.slave/0
是否必选:非必须,默认主模式;
注意事项:1是设置SPI总线为主机模式0是设置SPI总线为从机模式,合宙Air780EPM系列和Air8000系列只支持主机模式
         Air6101/Air8101支持主机模式 作为主控外挂 4G 模组(如 Air780EPM)时,可作为 SPI 从机使用
参数示例:--如下方所示,第八个参数spi.master为初始化spi时的master_slave
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

mode

参数含义:设置SPI总线的工作模式
数据类型:number
取值范围:nil,空值,spi.full/1,spi.half/0
是否必选:非必须,默认全双工;
注意事项:1是设置SPI总线为全双工0是设置SPI总线为半双工,目前合宙主推型号都支持全双工和半双工模式。
参数示例:--如下方所示,第九个参数spi.full为初始化spi时的mode
         local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

返回值

local spi_result = spi.setup(id, cs, CPHA, CPOL, dataw, bandrate, bitdict, master_slave, mode)

有一个返回值 spi_result

spi_result

含义说明:判断设置并启用SPI总线是否成功
         成功时返回0
         失败时返回-1
数值类型:number
取值范围:0/-1
注意事项:有返回失败的情况,需做好对应逻辑处理;
返回示例:例如返回0时表示spi初始化成功

示例

-- 如下方所示是填写参数的写法,正常情况会打印  SPI启用结果:0
local spi_result = local spiDevice = spi.setup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
log.info("SPI启用结果:",spi_result)

-- 如下方所示是填写部分参数的写法,正常情况会打印  SPI启用结果:0
local spi_result = local spiDevice = spi.setup(spi.SPI_0)
log.info("SPI启用结果:",spi_result)

4.2 spi.createSoft(cs, mosi, miso, clk, CPHA, CPOL, dataw, bitdict, master_slave, mode)

功能

设置并启用软件 SPI

注意事项

软件 SPI 的速率极低,最高可用波特率不超过 100K,远低于硬件 SPI 最高 25.6M 的波特率。软件 SPI 因依赖 CPU 执行指令模拟时序,存在速度慢、占用 CPU 资源、实时性差等问题, 通常是不使用这种模式,在硬件 spi 管脚被占用, 但是还想接 spi 外设的时候才会使用该方式,可用于一些 spi 接口的传感器等传输量少、分辨率低、刷新频率要求不高的外设。

参数

cs

参数含义:SPI总线的CS片选引脚编号
数据类型:number
取值范围:nil,根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:传入nil意为Lua控制cs脚
参数示例:--如下方所示,第一个参数0为初始化软件spi时的cs
local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

mosi

参数含义:设置mosi引脚编号
数据类型:number
取值范围:根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:mosi表示主线输出 / 从线输入,主设备通过此线向从设备发送数据。
参数示例:--如下方所示,第二个参数1为初始化软件spi时的mosi
local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

miso

参数含义:设置miso引脚编号
数据类型:number
取值范围:根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:miso表示主线输入 / 从线输出,从设备通过此线向主设备返回数据。
参数示例:--如下方所示,第三个参数2为初始化软件spi时的miso
local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

clk

参数含义:设置clk引脚编号
数据类型:number
取值范围:根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:clk是时钟线,由**主设备唯一控制**,决定数据传输的节奏。
参数示例:--如下方所示,第四个参数3为初始化软件spi时的clk
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

CPHA

参数含义:SPI总线的时钟相位,决定数据采样的时钟边沿,
数据类型:number
取值范围:nil,0/1
是否必选:必须,默认0
注意事项:当CPOL值为0时
         0是表示数据在SCK上升沿(第一边沿)采样,
         1是表示数据在SCK下降沿(第二边沿)采样。
         CPOL值为1时
         0是表示数据在SCK下降沿(第一边沿)采样,
         1是表示数据在SCK上升沿(第二边沿)采样。
参数示例:--如下方所示,第五个参数0为初始化软件spi时的CPHA
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式
         --如下方所示,是用nil值的写法,第五个参数nil为初始化软件spi时的CPHA设置为0
         local softSpiDevice = spi.createSoft(0,1,2,3,nil,nil,8,spi.MSB,
               spi.master, spi.full)

CPOL

参数含义:SPI总线的时钟极性,决定时钟SCK在空闲时的电平状态
数据类型:number
取值范围:nil,0/1
是否必选:必须,默认0
注意事项:0表示时钟SCK在空闲时的电平状态是低电平
         1表示时钟SCK在空闲时的电平状态是高电平
参数示例:--如下方所示,第六个参数0为初始化软件spi时的CPOL
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式
         --如下方所示,是用nil值的写法,第六个参数nil为初始化软件spi时的CPOL设置为0
         local softSpiDevice = spi.createSoft(0,1,2,3,nil,nil,8,spi.MSB,
               spi.master, spi.full)

dataw

参数含义:SPI总线的数据宽度(位)
数据类型:number
取值范围:nil,481632等常见取值
是否必选:必须,默认8bit
注意事项:暂无
参数示例:--如下方所示,第七个参数8为初始化软件spi时的dataw
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

bitdict

参数含义:设置SPI总线的大小端模式
数据类型:number
取值范围:spi.MSB/1,spi.LSB/0
是否必选:必须,默认spi.MSB/1
注意事项:spi.MSB是大端模式
         spi.LSB是小端模式
参数示例:--如下方所示,第八个参数spi.MSB为初始化软件spi时的bitdict
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

master_slave

参数含义:设置SPI总线的主从模式
数据类型:number
取值范围:nil,spi.master/1,spi.slave/0
是否必选:必须,默认1主模式;
注意事项:1是设置SPI总线为主机模式0是设置SPI总线为从机模式,软件spi只支持主机模式
参数示例:--如下方所示,第九个参数spi.master为初始化软件spi时的master_slave
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

mode

参数含义:设置SPI总线的工作模式
数据类型:number
取值范围:nil,spi.full/1,spi.half/0
是否必选:必须,默认0半双工;
注意事项:1是设置SPI总线为全双工0是设置SPI总线为半双工
         合宙支持LuatOS的模组度支持全双工和半双工,软件spi通常使用半双工模式以减少cpu负载的影响
参数示例:--如下方所示,第十个参数spi.full为初始化软件spi时的mode
         local softSpiDevice = spi.createSoft(
               0,         -- cs引脚GPIO编号
               1,         -- mosi引脚GPIO编号
               2,         -- miso引脚GPIO编号
               3,         -- clk引脚GPIO编号
               0,         -- 时钟相位
               0,         -- 时钟极性
               8,         -- 数据宽度(位)
               spi.MSB,   -- 高位优先
               spi.master,-- 主机模式
               spi.full)  -- 全双工模式

返回值

local softSpiDevice = (cs, mosi, miso, clk, CPHA, CPOL, dataw, bitdict, master_slave, mode)

有一个返回值 softSpiDevice

softSpiDevice

含义说明:软件SPI对象,可当作SPI的id使用         
数值类型:userdata
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如返回ESPI*:0C7F56A0表示软件spi初始化成功

示例

--I/user.软件SPI启用结果: ESPI*:0C7F56A0
local softSpiDevice =  spi.createSoft(0, 1, 2, 3, 0, 0, 8, spi.MSB, 1, 1)
log.info("软件SPI启用结果:",softSpiDevice)
-- 发送指令,接收返回的值
local recv_res = ""
local send_res = spi.send(softSpiDevice, string.char(0x9f))
local recv_res = spi.recv(softSpiDevice,3)
--关闭spi
spi.close(softSpiDevice)

4.3 spi.transfer(id, send_data, send_len, recv_len)

功能

传输 SPI 数据

注意事项

暂无

参数

id

参数含义:SPI总线id号,或软件SPI对象
数据类型:number/userdata
取值范围:spi.SPI_0/spi.SPI_1,软件SPI对象
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 第一个参数spi.SPI_0为传输数据时的参数id值,发送123,并读取1位数据1
        local recv = spi.transfer(spi.SPI_0, "123")

send_data

参数含义:待发送的数据
数据类型:string/zbuff
取值范围:string/zbuff类型的数据,长度1~4096字节
是否必选:必须传入此参数;
注意事项:如果为zbuff数据,则会从对象所处的指针处开始读
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 不设置传输数据长度的方式,第二个参数“123”为要传输的数据
        local recv = spi.transfer(spi.SPI_0, "123")

send_len

参数含义:发送数据的长度,单位字节
数据类型:number
取值范围:nil,空值,1~待发送数据的长度(最长4096
是否必选:非必须传入此参数;
注意事项:默认为1
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 设置send_len参数的方式传输数据,第三个参数3为要传输的数据长度是3
        local recv = spi.transfer(spi.SPI_0, "123",3,3)

recv_len

参数含义:读取数据的长度,单位字节
数据类型:number
取值范围:nil,空值,1~待读取数据的长度(最长4096
是否必选:非必须传入此参数;
注意事项:默认为1
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 设置recv_len参数的方式传输数据,第四个参数3为要接收的数据长度是3
        local recv = spi.transfer(spi.SPI_0, "123",3,3)

返回值

local recv = spi.transfer(id, send_data, send_len, recv_len)

有一个返回值 recv

recv

含义说明:读取成功返回字符串,否则返回nil         
数值类型:string
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如返回"123"表示读取到3字节数据"123"

示例

-- 这里我们把spi_mosi和spi_miso接在一起,模拟收发数据
-- 初始化spi
spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下方所示,发送123,并读取1位数据1
local recv = spi.transfer(spi.SPI_0, "123")
--如下方所示,发送123,并读取全部数据123
local recv = spi.transfer(spi.SPI_0, "123",3,3)
--如下方所示,传输zbuff数据,创建一个初值全为0x33的内存区域
local buff = zbuff.create(1024, 0x33) 
--把zbuff数据从指针开始,发送并读取1位数据3
local recv = spi.transfer(spi.SPI_0, buff)
--把zbuff数据从指针开始,全发出去,并读取数据是3333...333,即1024位3
local recv = spi.transfer(spi.SPI_0, buff,1024,1024)

4.4 spi.recv(id, size, buff)

功能

接收指定长度的 SPI 数据

注意事项

暂无

参数

id

参数含义:SPI总线id号,或软件SPI对象
数据类型:number/userdata
取值范围:spi.SPI_0/spi.SPI_1,软件SPI对象
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 第一个参数spi.SPI_0为接收数据时spi的id
        local recv = spi.recv(spi.SPI_0, 4)

        -- 当传入zbuff参数时,返回值有所不同. 2024.3.29新增
        -- 读取成功后, 指针会往后移动len个字节
        -- 写入位置以当前buff:used()位置开始, 请务必确保有足够空间写入size长度的数据
        local len = spi.recv(spi.SPI_0, 4, buff)

size

参数含义:待读取的数据长度,单位字节
数据类型:number
取值范围:1~可读取的数据总长度(最长4096
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 第二个参数4为接收4字节的数据
        local recv = spi.recv(spi.SPI_0, 4)

        -- 当传入zbuff参数时,返回值有所不同. 2024.3.29新增
        -- 读取成功后, 指针会往后移动size个字节
        -- 写入位置以当前buff:used()位置开始, 请务必确保有足够空间写入size长度的数据
        local len = spi.recv(spi.SPI_0, 4, buff)

buff

参数含义:zbuff对象
数据类型:userdata
取值范围:zbuff对象,nil,最长4096字节
是否必选:非必须传入此参数;
注意事项:写入位置以当前buff:used()位置开始, 请务必确保有足够空间写入size长度的数据
参数示例:-- 初始化spi
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

        -- 当传入zbuff参数时,返回值有所不同. 2024.3.29新增
        -- 读取成功后, 指针会往后移动size个字节
        -- 写入位置以当前buff:used()位置开始, 请务必确保有足够空间写入size长度的数据
        local len = spi.recv(spi.SPI_0, 4, buff)

返回值

local recv = spi.recv(spi.SPI_0, 4)--接收 4 字节数据

返回值 recv

含义说明:读取成功返回字符串,出错返回nil         
数值类型:string
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如返回1234表示读取了4字节数据1234

local len = spi.recv(spi.SPI_0, size, buff)-- 读取成功后, buff 的指针会往后移动 size 个字节

返回值 len

含义说明:传入的是zbuff,返回读取数据的长度,出错返回nil         
数值类型:int
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
         写入位置以当前buff:used()位置开始, 请务必确保有足够空间写入size长度的数据
返回示例:例如返回6表示读取了6字节数据

示例

-- 这里我们把spi_mosi和spi_miso接在一起,模拟收发数据
-- 初始化spi
spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local result = spi.send(spi.SPI_0, "1234")
-- 如下方所示,正常情况会打印  读到的数据为:1234
local recv = spi.recv(spi.SPI_0, 4)
log.info("读到的数据为:",recv)

-- 当传入zbuff参数时,返回值有所不同. 2024.3.29新增
-- 读取成功后, 指针会往后移动size个字节
-- 写入位置以当前buff:used()位置开始, 请务必确保有足够空间写入size长度的数据
local recv_len = spi.recv(spi.SPI_0, 4, buff)
-- log打印  读到的数据为:4
log.info("读到的数据为:",recv_len )

4.4 spi.send(id, data ,len)

功能

发送 SPI 数据

注意事项

data 可以为 string 或者 zbuff,

如果为 string,不设定 len 时是全部发送,设定 len 时发送第一个字节到第 len 字节的数据

如果为 zbuff 数据,不设定 len 时则会从对象所处的指针处开始全部发送出去,

设定 len 时会从对象所处的指针处开始到第 len 字节的数据,

如果 len 设定大于 zbuff 数据长度,发送情况和不设定 len 时一样。

参数

id

参数含义:SPI总线id号,或软件SPI对象
数据类型:number/userdata
取值范围:spi.SPI_0/spi.SPI_1,软件SPI对象
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1
参数示例:-- 初始化spi        
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 第一个参数spi.SPI_0为发送数据时spi的id
        local result = spi.send(spi.SPI_0, "123")        

        --如下方所示,发送buff数据,创建一个初值全为0x33的内存区域
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去
        local result = spi.send(spi.SPI_0, buff)

data

参数含义:待发送的数据
数据类型:string/zbuff
取值范围:string/zbuff类型的数据,长度1~4096字节
是否必选:必须传入此参数;
注意事项:如果为zbuff数据,则会从对象所处的指针处开始读
参数示例:-- 初始化spi        
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,发送string类型数据 第二个参数"123"为要发送的数据,
        local result = spi.send(spi.SPI_0, "123")        

        --如下方所示,发送buff数据,创建一个初值全为0x33的内存区域
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去
        local result = spi.send(spi.SPI_0, buff)

len

参数含义:待发送数据的长度,单位字节
数据类型:int
取值范围:nil,空值,0~待发送数据的长度(最长4096
是否必选:非必须传入此参数;
注意事项:默认为data长度
参数示例:-- 初始化spi        
        spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示, 第三个参数3为要发送的数据长度
        local result = spi.send(spi.SPI_0, "123",3)

返回值

local spi_result = spi.send(spi.SPI_0, "123")--发送 string 类型数据"123"

返回值 spi_result

含义说明:发送成功返回数据长度       
数值类型:int
取值范围:无特别限制;
注意事项:有返回失败的情况,需做好对应逻辑处理;

local buff_result = spi.send(spi.SPI_0, buff)--把 zbuff 的数据从指针开始,全发出去

返回值 buff_result

含义说明:发送成功返回buff的长度        
数值类型:number
取值范围:非负整数
注意事项:有返回失败的情况,需做好对应逻辑处理;
返回示例:例如返回6表示 发送了6字节数据

示例

-- 初始化spi
spi.setup(spi.SPI_0,8 ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下方所示,不设置发送长度,发送123
local result = spi.send(spi.SPI_0, "123")
--如下方所示,设置发送3字节数据123
local result = spi.send(spi.SPI_0, "123",3)
--如下方所示,发送buff数据,创建一个初值全为0x33的内存区域
local buff = zbuff.create(1024, 0x33) 
--把zbuff数据从指针位置开始,全发出去
local buff_result = spi.send(spi.SPI_0, buff)
--I/user,send发送结果:1024
log.info("send发送结果:",buff_result
--把zbuff数据从指针位置开始,发送120字节数据
local buff_result = spi.send(spi.SPI_0, buff,120)
--I/user,send发送结果:120
log.info("send发送结果:",buff_result

4.5 spi.close(id)

功能

关闭指定的 SPI

注意事项

暂无

参数

id

参数含义:SPI总线id号,或软件SPI对象
数据类型:number/userdata
取值范围:spi.SPI_0/spi.SPI_1,软件SPI对象
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1,如有其他需求可联系我们开发
参数示例:--如下所示  spi.SPI_1就是参数id
        log.info("关闭SPI1",spi.close(spi.SPI_1))

返回值

local close_result = spi.close(spi.SPI_0)

返回值 close_result

含义说明:关闭成功返回0,出错返回其他         
数值类型:int
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如成功返回0表示成功

示例

local close_result = spi.close(spi.SPI_1)
log.info("关闭SPI1结果:",close_result)
--log打印  关闭SPI1结果:0

4.6 spi.deviceSetup(id, cs, CPHA, CPOL, dataw, bandrate, bitdict, master_slave, mode)

功能

以对象方式设置并启用硬件 SPI

注意事项

spidevice 对象方式是设置并启用 SPI 的新方式,不需要手动控制 cs 引脚,不同设备在使用 send(),recv()和 transfer()接口时无需再次配置 spi 的 id 参数,由设备固件自动管理,具体看下述 spi_device:send(),spi_device:recv()和 spi_device:transfer()接口的用法

例如:spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full) --如下方所示,send 接口只需要写 data 内容,不用再设置 spi 的 id 号 local result = spi_device:send("123")

spi 对象要定义为全局变量,否则会被系统回收

参数

id

参数含义:SPI的总线ID号
数据类型:number
取值范围:spi.SPI_0/spi.SPI_1
是否必选:必须传入此参数;
注意事项:目前合宙模组的硬件SPI的总线ID只有0/1
参数示例:--如下方所示,第一个参数spi.SPI_0为初始化spi时的id
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

cs

参数含义:SPI总线的CS片选引脚编号
数据类型:number
取值范围:根据自己的电路设计选择对应的GPIO编号
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下方所示,第二个参数CS_PIN为初始化spi时的cs
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

CPHA

参数含义:SPI总线的时钟相位,决定数据采样的时钟边沿,
数据类型:number
取值范围:nil,空值,0/1
是否必选:非必须,默认0
注意事项:当CPOL值为0时
         0是表示数据在SCK上升沿(第一边沿)采样,
         1是表示数据在SCK下降沿(第二边沿)采样。
         CPOL值为1时
         0是表示数据在SCK下降沿(第一边沿)采样,
         1是表示数据在SCK上升沿(第二边沿)采样。
参数示例:--如下方所示,第三个参数0为初始化spi时的CPHA
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

CPOL

参数含义:SPI总线的时钟极性,决定时钟SCK在空闲时的电平状态
数据类型:number
取值范围:nil,空值,0/1
是否必选:非必须,默认0
注意事项:0表示时钟SCK在空闲时的电平状态是低电平
         1表示时钟SCK在空闲时的电平状态是高电平
参数示例:--如下方所示,第四个参数0为初始化spi时的CPOL
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

dataw

参数含义:SPI总线的数据宽度(位)
数据类型:number
取值范围:nil,空值481632等常见取值
是否必选:非必须,默认8bit
注意事项:暂无
参数示例:--如下方所示,第五个参数8为初始化spi时的dataw
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

bandrate

参数含义:SPI总线的波特率
数据类型:number
取值范围:nil,空值其他常用取值
是否必选:非必须,默认20M=20000000
注意事项:暂无
参数示例:--如下方所示,第六个参数2000000为初始化spi时的bandrate
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

bitdict

参数含义:设置SPI总线的大小端模式
数据类型:number
取值范围:空值,spi.MSB/0spi.LSB/1
是否必选:非必须,默认spi.MSB/0
注意事项:spi.MSB是大端模式
         spi.LSB是小端模式
参数示例:--如下方所示,第七个参数spi.MSB为初始化spi时的bitdict
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

master_slave

参数含义:设置SPI总线的主从模式
数据类型:number
取值范围:nil,空值,spi.master/1,spi.slave/0
是否必选:非必须,默认1主模式;
注意事项:1是设置SPI总线为主机模式0是设置SPI总线为从机模式
         合宙Air780EPM系列和Air8000系列只支持主机模式
         Air6101/Air8101支持主机模式 作为主控外挂 4G 模组(如 Air780EPM)时,可作为 SPI 从机使用
参数示例:--如下方所示,第八个参数spi.master为初始化spi时的 master_slave
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

mode

参数含义:设置SPI总线的工作模式
数据类型:number
取值范围:nil,空值,spi.full/1,spi.half/0
是否必选:非必须,默认1全双工;
注意事项:1是设置SPI总线为全双工0是设置SPI总线为半双工。合宙支持LuatOS的模组都支持全双工和半双工
参数示例:--如下方所示,第九个参数spi.full为初始化spi时的mode
         spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

返回值

local spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)

有一个返回值 spi_device

spi_device

含义说明:SPI对象,判断设置并启用SPI总线是否成功
         成功时返回userdata数据结构,可当SPI的id用于其他逻辑                
数值类型:userdata
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如返回SPI*: 0C7F5948表示初始化SPI成功

示例

-- 如下方所示,获取SPI对象,用于初始化lf.正常情况会打印 
--I/user.启用的SPI对象是:SPI*: 0C7F5948    lf初始化结果是:0
local spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local flash_device = lf.init(spi_device)
log.info("启用的SPI对象是:",spi_device"lf初始化结果是:",flash_device)

4.7 spi_device:transfer(send_data,send_len,recv_len)

功能

以对象方式传输 SPI 数据

注意事项

暂无

参数

spi_device

参数含义:SPI对象,对象方式设置并启用硬件SPI返回的值
数据类型:userdata
取值范围:userdata类型的SPI对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,发送字符串,指定传输数据的id是spi_device
        local recv = spi_device:transfer("123")
        --如下方所示,发送0x00,0x01,指定传输数据的id是spi_device
        local result = spi_device:transfer({0x00,0x01})

        --如下方所示,传输buff数据的id是spi_device
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去,并读取数据
        local recv = spi_device:transfer(buff)

send_data

参数含义:待发送的数据
数据类型:string/zbuff
取值范围:string/zbuff类型的数据,长度1~4096字节
是否必选:必须传入此参数;
注意事项:如果为zbuff数据,则会从对象所处的指针处开始读
参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,send_data是字符串"123"
        local recv = spi_device:transfer("123")
        --如下方所示,send_data是{0x00,0x01}
        local result = spi_device:transfer({0x00,0x01})

        --如下方所示,send_data是buff数据
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去,并读取数据
        local recv = spi_device:transfer(buff)

send_len

参数含义:待发送数据的长度,单位字节
数据类型:number
取值范围:nil,空值,1~待发送数据的长度(最长4096
是否必选:非必须传入此参数;
注意事项:不设置此参数最多传输8字节数据
参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,不指定send_len直接传输字符串"123"
        local recv = spi_device:transfer("123")
        --如下方所示,指定send_len为3传输字符串"123"
        local recv = spi_device:transfer("123",3,3)
        --如下方所示,不指定send_len直接传输{0x00,0x01}
        local result = spi_device:transfer({0x00,0x01})

        --如下方所示,不指定send_len直接传输buff数据
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去,并读取数据
        local recv = spi_device:transfer(buff)

recv_len

参数含义:待读取的数据长度,单位字节
数据类型:number
取值范围:nil,空值,1~待读取数据的长度(最长4096
是否必选:非必须传入此参数;
注意事项:不设置此参数最多传输8字节数据
参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,不指定recv_len直接传输字符串"123"
        local recv = spi_device:transfer("123")
        --如下方所示,指定recv_len为3传输字符串"123"
        local recv = spi_device:transfer("123",3,3)
        --如下方所示,不指定recv_len直接传输{0x00,0x01}
        local result = spi_device:transfer({0x00,0x01})

        --如下方所示,不指定recv_len直接传输buff数据
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去,并读取数据
        local recv = spi_device:transfer(buff)

返回值

local recv = spi_device:transfer(0, "123",3,3)--发送 123,并读取数据

有一个返回值 recv

recv

含义说明:读取成功返回字符串,否则返回nil        
数值类型:string
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如返回字符串表示读取成功

示例

-- 初始化spi
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下方所示,不指定send_len和recv_len直接传输字符串"123"
local recv = spi_device:transfer("123")
--如下方所示,指定send_len和recv_len为3传输字符串"123"
local recv = spi_device:transfer("123",3,3)
--如下方所示,不指定send_len和recv_len直接传输{0x00,0x01}
local result = spi_device:transfer({0x00,0x01})

--如下方所示,不指定send_len和recv_len直接传输buff数据
local buff = zbuff.create(1024, 0x33) 
--把zbuff数据从指针开始,全发出去,并读取数据
local recv = spi_device:transfer(buff)

4.8 spi_device:send(data, send_len)

功能

以对象方式发送 SPI 数据

注意事项

暂无

参数

spi_device

参数含义:SPI对象,对象方式设置并启用硬件SPI返回的值
数据类型:userdata
取值范围:userdata类型的SPI对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,发送字符串,指定传输数据的id是spi_device
        local result = spi_device:send("123")
        --如下方所示,发送0x00,0x01,指定传输数据的id是spi_device
        local result = spi_device:send({0x00,0x01})
        --如下方所示,传输buff数据的id是spi_device,创建一个初值全为0x33的内存区域 
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去
        local result = spi_device:send(buff)

data

参数含义:待发送的数据
数据类型:string/zbuff
取值范围:string/zbuff类型的数据,长度1~4096字节
是否必选:必须传入此参数;
注意事项:如果为zbuff数据,则会从对象所处的指针处开始读
参数示例:参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,data是字符串"123"
        local result = spi_device:send("123")
        --如下方所示,data是{0x00,0x01}
        local result = spi_device:send({0x00,0x01})
        --如下方所示,data是buff数据,创建一个初值全为0x33的内存区域 
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去
        local result = spi_device:send(buff)

send_len

参数含义:待发送数据的长度,单位字节
数据类型:int
取值范围:nil,空值,0~待发送数据的长度(最长4096
是否必选:非必须传入此参数;
注意事项:默认为data长度
参数示例:参数示例:-- 初始化spi
        spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
        --如下方所示,不指定send_len直接传输字符串"123"
        local result = spi_device:send("123")
        --如下方所示,指定send_len为3传输字符串"123"
        local result = spi_device:send("123",3)
        --如下方所示,不指定send_len直接传输{0x00,0x01}
        local result = spi_device:send({0x00,0x01})
        --如下方所示,不指定send_len直接传输buff数据
        local buff = zbuff.create(1024, 0x33) 
        --把zbuff数据从指针开始,全发出去
        local result = spi_device:send(buff)

返回值

spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full) local spi_device_result = spi_device:send("123")--发送 123

返回值 spi_device_result

含义说明:发送成功返回0,出错返回其他         
数值类型:int
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理;

local buff = zbuff.create(1024, 0x33) --创建一个初值全为 0x33 的内存区域 local buff_result = spi_device:send(buff)--把 zbuff 数据从指针开始,全发出去

返回值 buff_result

含义说明:发送成功返回0,出错返回其他         
数值类型:int
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理; 
返回示例:例如返回0是发送成功

示例

-- 初始化spi
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
local result1 = spi_device:send("123")--发送123
local result2 = spi_device:send({0x00,0x01})--发送0x00,0x01

local buff = zbuff.create(1024, 0x33) --创建一个初值全为0x33的内存区域
local result3 = spi_device:send(buff)--把zbuff数据从指针开始,全发出去
--I/user.发送结果1*2*3: 3 2 1024
log.info("发送结果1*2*3:",result1,result2,result3)

4.9 spi_device:recv(size)

功能

以对象方式接收 SPI 数据

注意事项

暂无

参数

spi_device

参数含义:SPI对象,对象方式设置并启用硬件SPI返回的值
数据类型:userdata
取值范围:userdata类型的SPI对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 初始化spi
 spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下方所示,接收4字节数据,指定接收数据的id是spi_device
local recv = spi_device:recv(4)

size

参数含义:待读取的数据长度,单位字节
数据类型:int
取值范围:1~可读取的数据总长度(最长4096
是否必选:必须传入此参数;
注意事项:暂无
参数示例:-- 初始化spi
 spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下方所示,指定接收4字节数据
local recv = spi_device:recv(4)

返回值

spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN,0,0,8,2000000,spi.MSB,spi.master,spi.full) local recv = spi_device:recv(4)

返回值 recv

含义说明:读取成功返回字符串,否则返回nil         
数值类型:string
取值范围:无特别限制;
注意事项:有返回其他的情况,需做好对应逻辑处理; 
返回示例:例如返回字符串表示读取成功

示例

-- 初始化spi
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)
--如下方所示,先发送字符串"123",指定接收3字节数据,收到123
local result = spi_device:send("123")
local spi_rev=spi_device:recv(3)

4.10 spi.xfer(id, txbuff, rxbuff, transfer_len, transfer_done_topic)

功能

非阻塞方式硬件 SPI 传输 SPI 数据

注意事项

该方式目的为了提高核心利用率。API 直接返回是否启动传输,传输完成后通过 topic 回调,本 API 适合硬件 SPI 传输大量数据传输,外设功能(LCD SPI,W5500 SPI 之类的)占据的 SPI 和软件 SPI 不能用,少量数据传输建议使用传统阻塞型 API

如果是用 spi_device,即 spi 对象的方式,需要手动在传输完成后拉高 cs!!!!!!

因为用的是非阻塞式的 SPI 传输模型(启动传输后不会 “卡住” 等完成,后续通过回调通知结果),为了保证数据在动态传输过程中(比如异步收发时)不会失效(比如避免数据被意外覆盖、释放),所以只能使用 zbuff 这种专门的缓冲区来存储要发送或接收的数据。

参数

id

参数含义:SPI的总线ID号
数据类型:userdata/int/spi_device/spi_id
取值范围:spi.SPI_0/spi.SPI_1/userdata类型的SPI对象
是否必选:必须传入此参数;
注意事项:暂无
参数示例:--如下方所示 spi.SPI_0就是传输数据的id
        local result = spi.xfer(spi.SPI_0, txbuff, rxbuff, 1024, "SPIDONE")

txbuff

参数含义:待发送的数据
数据类型:zbuff
取值范围:zbuff类型的数据
是否必选:必须传入此参数;
注意事项:如果为nil,则只接收数据,由于用的非阻塞模型,为保证动态数据的有效性,
        只能使用zbuff,发送的数据从zbuff所处的指针处开始读
参数示例:--如下方所示 txbuff就是待发送的数据,创建一个初值全为0x33的内存区域
        local txbuff = zbuff.create(1024, 0x33)
        local result = spi.xfer(spi.SPI_0, txbuff, rxbuff, 1024, "SPIDONE")

rxbuff

参数含义:待接收的数据存储的缓冲区
数据类型:zbuff
取值范围:zbuff类型的数据
是否必选:必须传入此参数;
注意事项:如果为nil,则只发送数据,由于用的非阻塞模型,为保证动态数据的有效性,只能使用zbuff,接收的数据从zbuff所处的指针处开始存储
参数示例:--如下方所示 txbuff就是待发送的数据,创建一个初值全为0x33的内存区域
        local txbuff = zbuff.create(1024, 0x33) 
        --创建一个长度为1024*2的空置内存区域
        local rxbuff = zbuff.create(1024*2)
        --如下方所示  rxbuff就是待接收的数据存储的缓冲区
        local result = spi.xfer(spi.SPI_0, txbuff, rxbuff, 1024, "SPIDONE")

transfer_len

参数含义:传输数据长度
数据类型:int
取值范围:发送字节长度/发送字节+接收字节
是否必选:必须传入此参数;
注意事项:特别说明 如果为半双工,先发后收,比如spi flash操作这种
        则长度=发送字节+接收字节,注意上面发送和接收buff都要留足够的数据,后续接收数据处理需要跳过发送数据长度字节
参数示例:--如下方所示 txbuff就是待发送的数据,创建一个初值全为0x33的内存区域
        local txbuff = zbuff.create(1024, 0x33) 
        --创建一个长度为1024*2的空置内存区域
        local rxbuff = zbuff.create(1024*2)
        --如下方所示  1024*2就是传输数据长度
        local result = spi.xfer(spi.SPI_0, txbuff, rxbuff, 1024, "SPIDONE")

transfer_done_topic

参数含义:传输完成后回调的topic
数据类型:string
取值范围:自定义的string类型的topic
是否必选:必须传入此参数;
注意事项:传输完成后发布topic消息,携带boolean型传输结果,通知订阅该消息的回调执行
参数示例: --如下方所示  "SPIDONE"就是传输完成后回调的topic
local result = spi.xfer(spi.SPI_0, txbuff, rxbuff, 1024, "SPIDONE")

返回值

local spi.xfer_result = spi.xfer(spi.SPI_0, txbuff, rxbuff, 1024*2, "SPIDONE")

返回值 spi.xfer_result

含义说明:本次传输是否正确启动,true代表启动false代表有错误无法启动
         传输完成会发布消息transfer_done_topic和boolean型结果         
数值类型:boolean
取值范围:true/false 
注意事项:有返回其他的情况,需做好对应逻辑处理;
返回示例:例如返回true代表启动

示例

--log打印I/user.spi ok
spi_device = spi.deviceSetup(spi.SPI_0,CS_PIN ,0,0,8,2000000,spi.MSB,spi.master,spi.full)    
--创建一个初值全为0x33的内存区域
local txbuff = zbuff.create(1024, 0x33) 
--创建一个长度为1024*2的空置内存区域
local rxbuff = zbuff.create(1024*2)
local result = spi.xfer(spi_device, txbuff, rxbuff, 1024*2, "SPIDONE")
if result then
    result, spi_id, succ, error_code = sys.waitUntil("SPIDONE")
end
if not result or not succ then
    log.info("spi fail, error code", error_code)
else
    log.info("spi ok")
end
gpio.setup(CS_PIN, 1)

五、产品支持说明

支持 LuatOS 开发的所有产品都支持 spi 核心库。