SPI
一、SPI 概述
SPI(Serial Peripheral Interface)是一种同步串行通信协议,广泛应用于微控制器和外围设备之间的数据传输。它由摩托罗拉公司开发,具有全双工通信能力,即可以同时进行数据的发送和接收。
SPI 通信通常涉及四条信号线:
- MOSI(Master Out Slave In):主设备发送数据,外设接收数据。
- MISO(Master In Slave Out):外设发送数据,主设备接收数据。
- SCLK(Serial Clock):由主设备生成的时钟信号,用于同步数据传输。
- SS(Slave Select):选择特定的从设备进行通信。(有时候也写作 CS,Chip Select)
SPI 的优点包括简单的硬件连接、高速数据传输和全双工通信。其缺点是通常需要更多的引脚,尤其是在多个从设备的情况下,每个从设备需要一个独立的 SS 引脚。此外,SPI 没有标准化的协议层,因此设备间的兼容性需要仔细管理。
SPI 协议具体可以参考下面这篇文章介绍:SPI 基础 - 合宙模组资料中心
二、演示功能概述
使用 Air780EHV 核心板通过 spi 接口驱动 RC522 传感器读取 ic 数据卡数据
2.1 RC522 简介
- 特点
容量为 8K 位 EEPROM
分为 16 个扇区,每个扇区为 4 块,每块 16 个字节,以块为存取单位
每个扇区有独立的一组密码及访问控制
每张卡有唯一序列号,为 32 位
具有防冲突机制,支持多卡操作
无电源,自带天线,内含加密控制逻辑和通讯逻辑电路
数据保存期为 10 年,可改写 10 万次,读无限次
- 储存结构
M1 卡分为 16 个扇区,每个扇区由 4 块(块 0、块 1、块 2、块 3)组成,(我们也将 16 个扇区的 64 个块按绝对地址编号为 0~63,存储结构如下图所示:
第 0 扇区的块 0(即绝对地址 0 块),它用于存放厂商代码,已经固化,不可更改。
每个扇区的块 0、块 1、块 2 为数据块,可用于存贮数据。
数据块可作两种应用:
用作一般的数据保存,可以进行读、写操作。
用作数据值,可以进行初始化值、加值、减值、读值操作。
每个扇区的块 3 为控制块,包括了密码 A、存取控制、密码 B。具体结构如下:
每个扇区的密码和存取控制都是独立的,可以根据实际需要设定各自的密码及存取控制。存取控制为 4 个字节,共 32 位,扇区中的每个块(包括数据块和控制块)的存取条件是由密码和存取控制共同决定的,在存取控制中每个块都有相应的三个控制位,定义如下:
三、准备硬件环境
3.1 Air780EHV 核心板
Air780EHV 核心板
参考:硬件环境清单第二章节内容,准备以及组装好硬件环境。
3.2 rc522 模块
我们将以下图所示的 RC522 模块进行演示说明,后续我们也会在合宙淘宝店铺上架官方 RC522 配件,原厂驱动,一键调用。
四、软件环境
在开始实践本示例之前,先筹备一下软件环境:
1. Luatools 工具;
2. 内核固件文件(底层core固件文件):LuatOS-SoC_V2007_Air780EHV;参考项目使用的内核固件(当前版本仅供测试使用);
3. luatos 需要的脚本和资源文件
lib 脚本文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件;
准备好软件环境之后,接下来查看如何烧录项目文件到 Air780EHV 核心板,将本篇文章中演示使用的项目文件烧录到 Air780EHV 核心板中。
五、软硬件资料
5.1 软件 API 接口介绍
spi 接口库:spi - luatos@air780EHV - 合宙模组资料中心
rc522 驱动库:rc522 - luatos@air780EHV - 合宙模组资料中心
5.2 硬件接线介绍
此教程 rc522 与 air780EHV 接线如下所示,其中 cs 和 rst 管脚可选用别的 gpio。
RC522引脚 | Air780EGH引脚 | 说明 |
---|---|---|
SDA | SPL.CS | 片选信号 |
SCK | SPL.CLK | SPI 时钟信号 |
MOSI | SPL.MOSI | 主设备输出从设备输入 |
MISO | SPL.MISO | 主设备输入从设备输出 |
RST | GPIO16 | 复位信号(可自定义) |
GND | GND | 地线 |
3.3V | 3.3V | 电源(3.3V) |
核心板上面 SPI 相关管脚可以查看核心板使用手册
与核心板实际连线图可参考下面:
六、代码示例介绍
--[[
必须定义PROJECT和VERSION变量,Luatools工具会用到这两个变量,远程升级功能也会用到这两个变量
PROJECT:项目名,ascii string类型
可以随便定义,只要不使用,就行
VERSION:项目版本号,ascii string类型
如果使用合宙iot.openluat.com进行远程升级,必须按照"XXX.YYY.ZZZ"三段格式定义:
X、Y、Z各表示1位数字,三个X表示的数字可以相同,也可以不同,同理三个Y和三个Z表示的数字也是可以相同,可以不同
因为历史原因,YYY这三位数字必须存在,但是没有任何用处,可以一直写为000
如果不使用合宙iot.openluat.com进行远程升级,根据自己项目的需求,自定义格式即可
本demo演示的功能为:
使用Air780EGH开发板通过spi接口驱动RC522传感器读取ic数据卡数据
]]
PROJECT = "spi_demo"
VERSION = "001.000.000"
-- 在日志中打印项目名和项目版本号
log.info("main", PROJECT, VERSION)
-- 如果内核固件支持wdt看门狗功能,此处对看门狗进行初始化和定时喂狗处理
-- 如果脚本程序死循环卡死,就会无法及时喂狗,最终会自动重启
if wdt then
--配置喂狗超时时间为9秒钟
wdt.init(9000)
--启动一个循环定时器,每隔3秒钟喂一次狗
sys.timerLoopStart(wdt.feed, 3000)
end
-- 如果内核固件支持errDump功能,此处进行配置,【强烈建议打开此处的注释】
-- 因为此功能模块可以记录并且上传脚本在运行过程中出现的语法错误或者其他自定义的错误信息,可以初步分析一些设备运行异常的问题
-- 以下代码是最基本的用法,更复杂的用法可以详细阅读API说明文档
-- 启动errDump日志存储并且上传功能,600秒上传一次
-- if errDump then
-- errDump.config(true, 600)
-- end
-- 使用LuatOS开发的任何一个项目,都强烈建议使用远程升级FOTA功能
-- 可以使用合宙的iot.openluat.com平台进行远程升级
-- 也可以使用客户自己搭建的平台进行远程升级
-- 远程升级的详细用法,可以参考fota的demo进行使用
-- 启动一个循环定时器
-- 每隔3秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况
-- 方便分析内存使用是否有异常
sys.timerLoopStart(function()
log.info("mem.lua", rtos.meminfo())
log.info("mem.sys", rtos.meminfo("sys"))
end, 3000)
-- 加载spi测试模块
--引入rc522测试demo
require "rc522_test"
-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后不要加任何语句!!!!!因为添加的任何语句都不会被执行
--[[
本demo演示的功能为:
使用Air780EGH开发板通过spi接口驱动RC522传感器读取ic数据卡数据
通过spi0通道
cs片选脚接gpio8
rst接gpio16
]]
local rc522 = require "rc522" --引入rc522驱动模块
function rc522_test()
spi_rc522 = spi.setup(0,8,0,0,8,10*1000*1000,spi.MSB,1,0) --初始化spi接口
rc522.init(0,8,16) --初始化rc522相关接口
wdata = {0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} --测试写入数据
while 1 do
rc522.write_datablock(7,wdata) --测试ic卡写入
for i=0,63 do
local a,b = rc522.read_datablock(i) --测试ic卡读取
if a then
print("read",i,b:toHex()) --打印读取的数据
end
end
sys.wait(500)
end
end
sys.taskInit(rc522_test)
七、功能验证
7.1 RC522初始化成功
RC522初始化成功日志。
7.2 打印读卡信息
通过 luatools 打印日志可以看到成功读写 ic 卡
八、总结
至此,我们已使用 Air780EHV 核心板的 SPI 接口完成了 rc522 传感器的驱动,并读取了 ic 卡的数据。