• 正文
  • 相关推荐
申请入驻 产业图谱

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

08/01 15:32
138
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
#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, &param.set_mode);

if (ret == -1)

printf("can't set spi mode");

ret = ioctl(fd, SPI_IOC_RD_MODE, &param.set_mode);

if (ret == -1)

printf("can't get spi mode");

/*bits per word  设置一个字节的位数*/

ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &param.data_bit);

if (ret == -1)

printf("can't set bits per word");

ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &param.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, &param.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_tx[3] = {0x01, 0x02, 0x03};

unsigned char transfer_rx[3] = {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_tx[i]);

}

printf("\nReceived: ");

for (int i = 0; i < sizeof(transfer_rx); i++) {

printf("0x%02X ", transfer_rx[i]);

}

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设备。

相关推荐