SPI 通信

Frm: http://www.wzaobao.com/p/l5079K.html
http://blog.csdn.net/xqmoo8/article/details/8043474
http://www.cnblogs.com/sky-heaven/p/5736638.html
http://www.cnblogs.com/sankye/p/3955630.html

15.3 用户态SPI编程

 

Linux的SPI总线设备文件名通常为/dev/spidevN.P(N=0、1、2……,P=0、1、2……),其中N表示第几路SPI总线,而P表示在该路SPI总线中使用哪个CS信号线。

 

EasyARM-i.MX283A提供了1路SPI总线,在该总线中只有1个CS信号线,其设备文件名为/dev/spidev1.0。

 

15.3.1 SPI编程接口

 

1、打开设备

在使用SPI设备时,需要调用open()函数打开设备文件,获得文件描述符,如程序清单15.3所示。

 

程序清单15.3打开SPI设备文件

 

fd = open(“/dev/spidev1.0”, O_RDWR);

if (fd < 0) {

perror(“can not open SPI device\n”);

}

 

2、关闭设备

设备使用完成后,调用close()函数关闭设备,如下所示:

 

close(fd);

 

3、总线控制

通过调用ioctl()函数使用不同的命令,应用程序可以配置SPI总线的极性和相位、设置总线速率、数据字长度以及实现数据收/发。

 

  • 设置总线极性和相位

设置SPI总线极性及相位是使用SPI_IOC_WR_MODE命令实现,该命令的用法参考表15.5。

 

表15.5SPI_IOC_WR_MODE命令

 

命令

SPI_IOC_WR_MODE

调用方式

ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);

功能描述

设置SPI总线的极性和相位

输入参数说明

mode的可选值为:SPI_MODE_0、SPI_MODE_1、SPI_MODE_2、SPI_MODE_3,这些值的说明参考下面内容。

返回值说明

0:设置成功

1:设置不成功

 

SPI_MODE_0定义的模式为POLARITY(极性)=0、PHASE(相位)=0,时序如图15.4所示。

 

图15.4 POLARITY=0、PHASE=0的时序

 

SPI_MODE_1定义的模式为POLARITY=0、PHASE=1,时序如图15.5所示。

 

图15.5 POLARITY=0、PHASE=1的时序

 

SPI_MODE_2定义的模式为POLARITY=0、PHASE=1,时序如图15.6所示。

 

图15.6 POLARITY=0、PHASE=1的时序

 

SPI_MODE_3定义的模式为POLARITY=1、PHASE=1,时序如图15.7所示。

 

图15.7 POLARITY=1、PHASE=1的时序

 

设置SPI总线极性和相位为SPI_MODE_0模式的方法可以参考如程序清单15.4所示的代码。

 

程序清单15.4设置SPI总线极性和相位示例

 

int mode = SPI_MODE_0

ret = ioctl(fd_spi, SPI_IOC_WR_MODE, &mode);

if (ret == -1) {

printf("can't set wr spi mode\n");

return -1;

}

 

  • 设置每字的数据位长度

 

设置SPI总线上每字的数据位长度是使用SPI_IOC_WR_BITS_PER_WORD命令实现,该命令的用法参考表15.6。

 

表15.6SPI_IOC_WR_BITS_PER_WORD命令

 

命令

SPI_IOC_WR_BITS_PER_WORD

调用方式

ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);

功能描述

设置SPI总线上每字的数据位长度

输入参数说明

bits为每字的二制位数,取值

返回值说明

0为成功,其它值为失败

 

设置SPI总线的每字数据位长为8位的方法可以参考如程序清单15.5所示的代码。

 

程序清单15.5设置SPI数据位的示例代码

 

ret = ioctl(fd_spi, SPI_IOC_WR_BITS_PER_WORD, &bits); /* 设置SPI的数据位 */

if (ret == -1) {

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

return -1;

}

 

  • 设置最大总线速率

设置SPI总线的最大速率是通过使用SPI_IOC_WR_MAX_SPEED_HZ命令实现,该命令用法参考表15.7。

 

表15.7SPI_IOC_WR_MAX_SPEED_HZ

 

命令

SPI_IOC_WR_MAX_SPEED_HZ

调用方式

ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

功能描述

设置SPI总线的最大速率

输入参数说明

speed为需要设置的SPI总线的最大频率,单位为Hz

返回值说明

恒为0:设置成功

 

SPI总线的最大速率设置后,在使用过程并不是只能使用该频率收/发数据,而仅仅约束收/发数据时的最大频率。

 

  • 数据接收/发送命令

在SPI总线实现数据收/发是使用SPI_IOC_MESSAGE(n)命令实现,该命令用法参考表15.8。

 

表15.8SPI_IOC_MESSAGE(n)命令

 

命令

SPI_IOC_MESSAGE(n)

调用方式

ret = ioctl(fd, SPI_IOC_MESSAGE(n), &tr);

功能描述

实现在SPI总线接收/发送数据操作,其中n的值可变

输入/输出参数说明

struct spi_ioc_transfer结构体用于封装要收/发的数据。tr参数指定向struct spi_ioc_transfer结构体的数组,数组长度为n

返回值说明

0:操作成功

1:操作失败

 

使用SPI_IOC_MESSAGE(n)命令收/发的数据都需要使用struct spi_ioc_transfer结构体封装,该结构体的定义如程序清单15.6所示。

 

程序清单15.6struct spi_ioc_transfer结构体的定义

 

struct spi_ioc_transfer {

__u64 tx_buf; /* 指向发送数据的缓冲区 */

__u64 rx_buf; /* 指向接收数据的缓冲区 */

 

__u32 len; /* 收/发缓冲区中数据的长度 */

__u32 speed_hz; /* 总线速率 */

 

__u16 delay_usecs;

__u8 bits_per_word; /* 收/发数据的二进制位数 */

__u8 cs_change;

__u32 pad;

}

 

speed_hz不能大于在SPI_IOC_WR_MAX_SPEED_HZ命令中设置的总线速率。

由于iMX28xx处理器的SPI控制器只支持半双工,因此struct spi_ioc_transfer 结构体中的tx_buf和rx_buf只能设置一个有效,另一个必须设置为0,否则调用ioctl时会返回非零值提示操作错误。

posted @ 2017-02-19 23:30  QIYUEXIN  阅读(2737)  评论(0编辑  收藏  举报