RK3568笔记五十:SPI通信-回环测试

embedded/2024/10/18 10:16:32/

若该文为原创文章,转载请注明原文出处。

一、SPI引脚关系

其中SPI1的引脚关系如下表所示

SPI

引脚

功能

MOSI

GPIO3_C1

主设备输出/从设备输入

MISO

GPIO3_C2

主设备输入/从设备输出

CLOCK

CPIO3_C3

时钟信号线

CS0

GPIO3_A1

片选信号线0

CS1

NC

片选信号线1

二、内核和设备树配置

正点原子的内核已经配置了SPI设备驱动,可以不在配置内核但需要配置设备树。

为了学习和了解,还是要知道SPI设备驱动内核是如何配置的。

1、内核支持

进入kenel目录,make menuconfig

具体路径如下所示:

> Device Drivers

 > SPI support

2、设备树配置

修改/home/alientek/rk3568_linux_sdk/kernel/arch/arm64/boot/dts/rockchip/目录下的rk3568-atk-evb1-ddr4-v10.dtsi文件,在文件末添加代码,在spi1设备树下添加w25q64节点。

&spi1 {status = "okay";pinctrl-0 = <&spi1m1_cs0 &spi1m1_pins>;pinctrl-1 = <&spi1m1_cs0 &spi1m1_pins_hs>;// 向 spi1 节点追加 w25q64 设备节点w25q64: w25q64@0 {compatible = "rockchip,spidev";reg = <0>;  // 设置 reg 属性为 0, 表示 spi 连接到 spi1 的通道 0spi-max-frequency = <24000000>;  // 设置 SPI 传输的最大频率status = "okay";};
};

和上一篇有点区别,上一篇的compatible是自己写的,驱动需要自己编写,这里使用内核自带的,所以改成内核支持的,在linux/drivers/spi/spidev.c 可以看出是rockchip,spidev.

修改完成以后,重新编译一下内核,并烧写boot.img文件

重启板子后,查询,可以看到spidev1.0,其中1是spi1,0是cs0

三、回环测试

1、接线

根据ioctl相关参数即可编写spi相关测试程序,为了简单仅做回环测试实验, 只需要将SPI1的 MIOS与MOSI引脚使用跳线帽短接即可。即7和9短路。

2、测试程序

#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <linux/spi/spidev.h>#define SPI_DEV_PATH "/dev/spidev1.0"/*SPI 接收 、发送 缓冲区*/
unsigned char tx_buffer[100] = "hello the world !";
unsigned char rx_buffer[100];int fd;                  					// SPI 控制引脚的设备文件描述符
static unsigned  mode = SPI_MODE_2;         //用于保存 SPI 工作模式
static uint8_t bits = 8;        			// 接收、发送数据位数
static uint32_t speed = 10000000; 			// 发送速度
static uint16_t delay;          			//保存延时时间void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{int ret;struct spi_ioc_transfer tr = {.tx_buf = (unsigned long)tx,.rx_buf = (unsigned long)rx,.len = len,.delay_usecs = delay,.speed_hz = speed,.bits_per_word = bits,.tx_nbits = 1,.rx_nbits = 1};ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);if (ret < 1)printf("can't send spi message\n");
}void spi_init(int fd)
{int ret = 0;// spi mode 设置SPI 工作模式ret = ioctl(fd, SPI_IOC_WR_MODE32, &mode);if (ret == -1)printf("can't set spi mode\n");//  bits per word  设置一个字节的位数ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);if (ret == -1)printf("can't set bits per word\n");//  max speed hz  设置SPI 最高工作频率ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);if (ret == -1)printf("can't set max speed hz\n");// 打印printf("spi mode: 0x%x\n", mode);printf("bits per word: %d\n", bits);printf("max speed: %d Hz (%d KHz)\n", speed, speed / 1000);
}int main(int argc, char *argv[])
{int fd;if(argc < 2){printf("Wrong use !!!!\n");printf("Usage: %s [dev]\n",argv[0]);return -1;}/*打开 SPI 设备*/fd = open(argv[1], O_RDWR); // open file and enable read and  writeif (fd < 0){printf("Can't open %s \n",argv[1]); // open i2c dev file failexit(1);}/*初始化SPI */spi_init(fd);/*执行发送*/transfer(fd, tx_buffer, rx_buffer, sizeof(tx_buffer));/*打印 tx_buffer 和 rx_buffer*/printf("tx_buffer: \n %s\n ", tx_buffer);printf("rx_buffer: \n %s\n ", rx_buffer);close(fd);return 0;
}

编译

/opt/atk-dlrk356x-toolchain/bin/aarch64-buildroot-linux-gnu-gcc spi_selftest.c -o spi_selftest

在板子上运行测试:

 ./spi_selftest /dev/spidev1.0

此实验弥补了上一篇的遗憾,接下来编写W25Q64的测试程序,使用SPI测试,另GPIO模拟SPI要怎么处理?

如有侵权,或需要完整代码,请及时联系博主。


http://www.ppmy.cn/embedded/88954.html

相关文章

每天一个数据分析题(四百六十一)- AR模型

AR模型平稳性的判别方法有&#xff1f; A. 散点图 B. 单位根判别法 C. 平稳域判别法 D. 时序图 数据分析认证考试介绍&#xff1a;点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项练习题库 内容涵盖Python&#xff0c;SQL&#xff0c;统计学&#xff0…

【C++】入门基础知识

河流之所以能够到达目的地&#xff0c;是因为它懂得怎样避开障碍。&#x1f493;&#x1f493;&#x1f493; ✨说在前面 亲爱的读者们大家好&#xff01;&#x1f496;&#x1f496;&#x1f496;&#xff0c;我们又见面了&#xff0c;上一篇目我们已经完结了初阶数据结构部分…

JS 原型和原型链

构造函数 封装是面向对象思想中比较重要的一部分&#xff0c;js 面向对象可以通过构造函数实现的封装。 同样的将变量和函数组合到了一起并能通过 this 实现数据的共享&#xff0c;所不同的是 JS 借助构造函数创建出来的实例对象之间是彼此不影响的 存在浪费内存的问题&#…

OpenAI 发布全新 GPT-4o mini 模型用于取代 GPT-3.5

OpenAI已经弃用 GPT-3.5 模型&#xff0c;将使用 GPT-4o mini 模型取代它&#xff0c;这款模型如何&#xff1f;下面一起来了解一下。 GPT-4o mini 有消息称 OpenAI 准备放弃 GPT-3.5 模型转而使用 GPT-4o mini 模型取代&#xff0c;就在今天早上打开 ChatGPT 之后看&#xf…

24.8.1数据结构|单链表

主要部分&#xff1a; 1、定义&#xff1a;定义带链表的结构体&#xff0c;数据域和指针域 2、初始化&#xff1a;创建一个含有N个元素的带头结点的单链表head &#xff08;申请空间&#xff0c;给链表赋值&#xff09; 3、求表长&#xff1a;返回head的长度&#xff08;遍历&a…

C#中多线程编程中的同步、异步、串行、并行及并发及死锁

在C#中&#xff0c;多线程编程是一个强大的功能&#xff0c;它允许程序同时执行多个任务。然而&#xff0c;这也带来了复杂性&#xff0c;特别是在处理同步、异步、串行、并行、并发以及死锁等问题时。下面我将详细解释这些概念&#xff0c;并给出一些C#中的示例和注意事项。 …

使用Openvino部署C++的Yolov5时类别信息混乱问题记录

使用Openvino部署C的Yolov5时类别信息混乱问题记录 简单记录一下。 一、问题描述 问题描述&#xff1a;在使用Yolov5的onnx格式模型进行C的Openvino进行模型部署时&#xff0c;通过读取classes.txt获得类别信息时&#xff0c;出现模型类别混乱&#xff0c;或者说根本就不给图…

PHP教育培训小程序系统源码

&#x1f680;【学习新纪元】解锁教育培训小程序的无限可能✨ &#x1f4da; 引言&#xff1a;教育培训新风尚&#xff0c;小程序来引领&#xff01; Hey小伙伴们&#xff0c;是不是还在为找不到合适的学习资源而烦恼&#xff1f;或是厌倦了传统教育模式的单调&#xff1f;今…