news 2026/6/15 19:28:39

瑞芯微(EASY EAI)RV1126B SPI使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
瑞芯微(EASY EAI)RV1126B SPI使用

1. SPI简介

SPI是串行外设接口(Serial Peripheral Interface)的缩写,是 Motorola 公司推出的一种同步串行接口技术,是一种高速、全双工、同步的通信总线在用户空间的应用程序中,完全可以不必理会SPI协议的详细规定。只需要按照驱动层提供给我们的操作SPI外设的操作接口函数就可以像操作linux中其他普通设备文件那样轻松的操作SPI外设了。

EASY EAI Nano-TB的SPI接口分布如下图所示:

1.1 SPI参数配置解析

设备文件格式:/dev/spidev(bus.select)

bus:代表SPI总线号,即一组SCLK、MOSI、MISO

select:代表SPI设备号,同一条总线上用不同的片选信号区分:CSN0、CSN1等

以Orin-Nano默认SPI资源为例:启用SPI功能后,会出现下面4个设备节点(即有两条总线,四个设备)。

/dev/spidev0.0

/dev/spidev0.1

/dev/spidev3.0

/dev/spidev3.1

SPI通信有4种不同的模式,不同的从设备在出厂时配置模式已经固定,这是不能改变的,但通信双方设备必须工作在同一模式下,所以可以对主设备的SPI模式进行配置,通过CPOL(时钟极性)和CPHA(时钟相位)来控制主设备的通信模式。

时钟极性CPOL是用来配置SCLK电平的有效态的;

时钟相位CPHA是用来配置数据采样是发生在第几个边沿的。

CPOL=0表示当SCLK=0时处于空闲态,所以SCLK处于高电平时有效;

CPOL=1表示当SCLK=1时处于空闲态,所以SCLK处于低电平时有效;

CPHA=0表示数据采样是在第1个边沿,数据发送在第2个边沿;

CPHA=1表示数据采样是在第2个边沿,数据发送在第1个边沿;

【*】SPI主模块和与之通信的外设通信时,两者的时钟相位和极性应该保持一致。

其余的参数如:speed:通信的比特率,delay:设置通信的时间延迟,bits通信所占的位数。

1.2 硬件连接

本示例采用RFID读卡模块:RC522进行辅助演示。

RC522模块与EASY EAI Nano-TB的接线原理图如下所示:

2. 快速上手

2.1 开发环境准备

如果您初次阅读此文档,请阅读《入门指南/开发环境准备/Easy-Eai编译环境准备与更新》,并按照其相关的操作,进行编译环境的部署

在PC端Ubuntu系统中执行run脚本,进入EASY-EAI编译环境,具体如下所示。

cd ~/develop_environment ./run.sh

2.2 源码下载以及例程编译

首先,在虚拟机后台终端,执行以下命令,创建外设单例源码管理目录:

cd /opt mkdir -p EASY-EAI-Nano-TB/demo

首先,到【百度网盘】上下载相关的单例程序:

链接:https://pan.baidu.com/s/1Br608Hiff2Xs65PzWO_qWQ?pwd=1234

提取码:1234

比如把单例程序下载到:此电脑\D:\BaiduNetdisk(无规定,用户可自主选择),如下图所示。

再将下载好的单例复制进入虚拟机的文件系统,过程如下图所示。

最后,进入到对应的例程目录执行编译操作,具体命令如下所示:

cd EASY-EAI-Nano-TB/demo/07_SPI ./build.sh

注:

* 由于依赖库部署在板卡上,因此交叉编译过程中必须保持/mnt挂载。

编译成功后,会根据源码输出3个示例程序:test-rfid、test-fram、test-spidev,并会自动部署到开发板的/userdata/目录中。

本文档用到的辅助示例是test-rfid。其它示例用在别的应用场景里,此处的代码仅供参考。

2.3 例程运行

通过串口调试或ssh调试,进入板卡后台,定位到例程部署的位置,如下所示:

cd /userdata

执行下方例程命令如下所示:

sudo ./test-rfid

执行效果如下所示。

API的详细说明,以及API的调用(本例程源码),详细信息见下方说明。

3. RFID读取ID例程

RFID例程源码位于:

07_SPI/rfid.c

07_SPI/dev/rc522.c

07_SPI/include/rc522.h

利用了RC522芯片进行实现及讲解,操作流程如下。

参考例程如下所示。

static unsigned char flag = 0; static unsigned char bits = 8; static unsigned int speed = 100000; static uint16_t delay = 0; unsigned char card_rev_buf[16] = { 0 }; /* *扇区密码:A,扇区数:16,每个扇区 *密码字节数:16Byte */ unsigned char sector_key_a[16][16]; unsigned char data_buf[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10}; int main (int argc, char **argv) { memset(data_buf, 0x00, sizeof data_buf); int status = MI_ERR; int numAtempt = 1; int fd = spi_init(dev_spi_bus, dev_spi_select, mode, bits, speed, delay); rfid_init(dev_spi_bus ,dev_spi_select , fd); flag = MI_GET_ID; while(1) { while(rfid_request(PICC_REQIDL, &card_rev_buf[0]) != MI_OK && numAtempt-- >= 0) { usleep(500); } if(rfid_anticoll(&card_rev_buf[2]) == MI_OK) { status = rfid_select(&card_rev_buf[2]); if(status != MI_ERR) { if(flag == MI_GET_ID) { printf("Card ID:%02x%02x%02x%02x\n", card_rev_buf[2], card_rev_buf[3],card_rev_buf[4], card_rev_buf[5]); } else if (flag == MI_READ) { memset(sector_key_a, 0xff, 256); memset(data_buf, 0x00, sizeof data_buf); status = rfid_auth_state(PICC_AUTHENT1A, addr, sector_key_a[addr/4], &card_rev_buf[2]); if(status == MI_OK) { status = rfid_read(addr, data_buf); if(status == MI_OK) { print_buff(data_buf, 16); } } else { printf("Error reading"); close(fd); exit(1); } } else if (flag == MI_WRITE) { memset(sector_key_a, 0xff, 256); if(addr == 0 || addr % 4 == 3) { close(fd); exit(1); } status = rfid_auth_state(PICC_AUTHENT1A, addr, sector_key_a[addr/4], &card_rev_buf[2]); if(status == MI_OK) { status = rfid_write(addr, data_buf); if(status != MI_OK) { printf("rfid write failure!\n"); close(fd); exit(1); } } else { printf("Error writing"); close(fd); exit(1); } } else { printf("Not implemented\n"); } status = rfid_halt(); if(status != MI_OK) { //printf ("rfid halt failure! [ERROR %d]\n", status); } } else { // printf("None\n"); } } else { // printf("None\n"); } } spi_exit(dev_spi_bus , dev_spi_select); return 0; } /* ----- End of main() ----- */

此外,spi接口的铁电存储器通信源码位于:

07_SPI/fram.c

07_SPI/mb85rs64.c

07_SPI/mb85rs64.h

spi接口的读写通信源码位于:

07_SPI/spidev_test.c

4. 注意事项

RC522主要为辅助SPI的API使用说明,对于此模块的资料及使用说明请跳转:

http://www.xxx.com(官网的模块网址)

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 19:22:56

爆肝整理!2025年十大企业级Agent应用案例,看完我直接原地封神

在2025年的全球技术语境下,生成式人工智能(Generative AI)已正式跨越了简单的对话式交互阶段,进入了以自主代理(Autonomous Agents)为核心的生产力变革元年。本文旨在通过对全球领先企业的十大生产级应用案…

作者头像 李华
网站建设 2026/6/15 7:23:07

提示工程架构师必知:AI提示设计的常见挑战与对策

提示工程架构师必知:AI提示设计的常见挑战与对策 1. 引入与连接:你是否也曾被AI“误解”? 清晨8点,你急着给客户写一封产品推广邮件,于是给AI发了条提示: “写一封关于我们新推出的智能手表的推广邮件&…

作者头像 李华
网站建设 2026/6/15 13:53:23

RAG的一点思考

RAG有一个很典型的模块叫文本切块,然后检索。切块部分可以按window窗口切,检索部分也可以多路径检索,兼具稀疏检索,稠密检索和数据流检索。 这个流程和token化,然后embedding很像,所以我今天就陷入了迷茫?…

作者头像 李华
网站建设 2026/6/15 13:17:32

你真的了解cogagent和Open-AutoGLM吗:5大常见误解与真相解析

第一章:你真的了解cogagent和Open-AutoGLM吗:5大常见误解与真相解析在人工智能工程快速演进的当下,cogagent 与 Open-AutoGLM 作为新兴的智能体框架与开源语言模型工具链,正受到广泛关注。然而,伴随热度而来的是一系列…

作者头像 李华
网站建设 2026/6/15 13:19:26

Open-AutoGLM无法接入微信?5大核心技术瓶颈全解析

第一章:Open-AutoGLM无法接入微信?5大核心技术瓶颈全解析在将 Open-AutoGLM 接入微信生态的过程中,开发者普遍遭遇连接失败、消息延迟或认证超时等问题。这些问题背后,往往源于五大核心技术瓶颈,涉及协议兼容性、身份验…

作者头像 李华
网站建设 2026/6/10 18:12:58

【AI工程化核心突破】:cogagent如何驱动Open-AutoGLM实现端到端AutoGLM?

第一章:AI工程化背景下的AutoGLM演进随着人工智能技术从实验室研究逐步走向工业级应用,AI工程化已成为推动大模型落地的核心驱动力。在这一背景下,AutoGLM作为面向通用语言模型的自动化训练与推理框架,经历了从实验原型到生产就绪…

作者头像 李华