飞凌嵌入式ElfBoard-spi编程示例之spi通信编程示例

|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| #include <sys/types.h> #include <sys/stat.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> /*PPSIX 终端控制定义*/ #include <sys/ioctl.h> #include <linux/types.h> #include <linux/spi/spidev.h> // ***第一部分*** typedef struct { unsigned long speed; /*最大速率 */ unsigned char set_mode; /*模式 0 : CPOL=0,CPHA=0 1 : CPOL=0,CPHA=1 2 : CPOL=1,CPHA=0 3 : CPOL=1,CPHA=1 */ unsigned char data_bit; /*8位、16位 */ unsigned char lsb_first; /*低位先发 msb是高位先发*/ unsigned char cs_high; /*片选高有效*/ unsigned char no_cs; /*不使用片选*/ unsigned char delay; /*延时*/ unsigned char loop; /*loopback模式*/ unsigned char dual_spi; /*半双工 两线制 */ unsigned char quad_spi; /*半双工 四线制*/ } struct_spi_param; struct_spi_param spi_param = {500000, 0, 8, 0, 0, 0, 0, 0, 0, 0}; /*外设参数初始化*/ // ***第二部分*** /* * 初始化SPI */ int func_set_opt(int fd, struct_spi_param param) { int ret = 0; /*设置工作模式为CPHA=0 CPOL=0;*/ param.set_mode |= SPI_MODE_0; /*设置每字8位*/ param.data_bit = 8; /*设置工作频率 hz*/ param.speed = 500000; /*spi mode 设置SPI 工作模式*/ ret = ioctl(fd, SPI_IOC_WR_MODE, ¶m.set_mode); if (ret == -1) printf("can't set spi mode"); ret = ioctl(fd, SPI_IOC_RD_MODE, ¶m.set_mode); if (ret == -1) printf("can't get spi mode"); /*bits per word 设置一个字节的位数*/ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, ¶m.data_bit); if (ret == -1) printf("can't set bits per word"); ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, ¶m.data_bit); if (ret == -1) printf("can't get bits per word"); /*max speed hz 设置SPI 最高工作频率*/ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, ¶m.speed); if (ret == -1) printf("can't set max speed hz"); return 0; } // ***第三部分*** int func_transfer(int fd, unsigned char *tx, unsigned char *rx, unsigned int lens, struct_spi_param param) { int ret; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, .len = lens, .delay_usecs = param.delay, .speed_hz = param.speed, .bits_per_word = param.data_bit, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) printf("can't send spi message"); } // ***第四部分*** int main() { /*SPI 接收 、发送 缓冲区*/ unsigned char transfer_tx3 = {0x01, 0x02, 0x03}; unsigned char transfer_rx3 = {0}; int fd = open("/dev/spidev4.0", O_RDWR); /*初始化SPI */ func_set_opt(fd, spi_param); /*执行发送*/ func_transfer(fd, transfer_tx, transfer_rx, sizeof(transfer_tx), spi_param); /*打印 tx_buffer 和 rx_buffer*/ printf("Sent: "); for (int i = 0; i < sizeof(transfer_tx); i++) { printf("0x%02X ", transfer_txi); } printf("\nReceived: "); for (int i = 0; i < sizeof(transfer_rx); i++) { printf("0x%02X ", transfer_rxi); } printf("\n"); close(fd); return 0; } |

这段代码是用SPI进行回环测试的程序。让我们分解代码的每个部分:

第一部分:在这部分,包含了一些必要的头文件,并定义了一些全局变量和结构体。具体来说,`struct_spi_param`是一个结构体,用于保存与SPI通信相关的各种参数。

第二部分:这部分包含了`func_set_opt`函数的实现,该函数负责初始化SPI设备。它使用`ioctl`系统调用来设置各种SPI参数。

第三部分:这部分包含了`func_transfer`函数的实现,该函数负责通过SPI总线传输数据。它使用`ioctl`系统调用和`SPI_IOC_MESSAGE`命令来执行SPI数据传输。

第四部分:`main`函数是程序的入口点。它将设置发送接收缓冲区,然后调用`func_set_opt`来配置SPI设备。接着,它调用`func_transfer`来发送和接收数据,并使用预定义的`transfer_tx`和`transfer_rx`缓冲区。最后,它打印接收到的数据长度,并关闭SPI设备。

下面是代码的大致执行过程:

1.定义了`struct_spi_param`结构体,用于保存SPI参数,并用默认值初始化一个实例(`spi_param`)。

2.定义了两个函数:`func_set_opt`和`func_transfer`。

`func_set_opt`函数初始化SPI设备,它打开设备文件并设置SPI模式、数据位数和速率。

`func_transfer`函数通过SPI总线传输数据,使用`ioctl`系统调用和`SPI_IOC_MESSAGE`命令来执行SPI数据传输。

`main`函数设置发送接收缓冲区内容,并调用`func_set_opt`来配置SPI设备。

`main`函数接着调用`func_transfer`来发送和接收数据,使用预定义的`transfer_tx`和`transfer_rx`缓冲区。

最后,`main`函数打印发送和接收的数据内容,并关闭SPI设备。

相关推荐
小白学大数据4 小时前
Codex 里的 GPT 6 Astra、GPT 5.6 Sol、Terra、Luna 怎么选
开发语言·gpt·microsoft
l1t5 小时前
DeepSeek 4.1总结的Tom Lane 谈塑造 Postgres 三十年历程的架构决策
开发语言·数据库·postgresql·架构
djarmy11 小时前
MAIN.c(1): warning C318: can’t open file ‘STC8G.H’ 报错 解决 分析
c语言·开发语言·mongodb
HEJOO912 小时前
深入理解 Java volatile 关键字:原理、用法与常见误区
java·开发语言·spring
曹牧12 小时前
Java:no content to map due to end of input
java·开发语言
梦梦代码精12 小时前
《回收租赁系统技术选型避坑指南:业务闭环与二开自由度详解》
开发语言·低代码·docker·开源·代码规范
隔窗听雨眠12 小时前
记一次SQL Server数据库性能分析:从CPU100%到单配置修复的完整诊断
开发语言·数据库·php
David猪大卫12 小时前
【C++修炼】智能指针使用及原理
开发语言·c++·经验分享·笔记·学习·考研·面试
charlie11451419112 小时前
现代Qt开发之图像处理进阶:像素操作与格式转换
开发语言·图像处理·qt
李永奉12 小时前
中科蓝讯SDK开发-BT893x 面条耳机连接vivo手机后连接APP端,最后手机端设置页面手动断开蓝牙连接,此时耳机端假断开
c语言·开发语言·嵌入式硬件·物联网·智能手机·电脑