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时会返回非零值提示操作错误。

SPI 通信的更多相关文章

  1. 理解一下单片机的I2C和SPI通信

    应某位网友要求,今天说一下单片机的I2C SPI通信,可能说不清楚,因为这毕竟要做实验才可完全理解. I2C和SPI是两种不同的通信协议. 听到协议,似乎高不可攀,其实协议就是人们定义的一个标准而已, ...

  2. SPI通信实验---verilog(FPGA作为从机,使用可读可写)

    本实验讲究实用性,故设计思想为:主机先向从机发送地址,若是向从机写入数据,则向从机发送数据,若是读取从机数据,则向从机发送时钟,然后在时钟下降沿读取数据即可.cs信号上升沿作为SPI通信的结束信号.r ...

  3. SPI通信

    SPI是由Motorola公司提出的一种同步串行外围接口:它在速度要求不高,低功耗,需要保存少量参数的智能化传感系统中得到了广泛应用: SPI是一个全双工的同步串行接口,在数据传输过程中,总线上只能是 ...

  4. 关于SPI通信原理与程序实现

    第一次接触SPI是因为当时用到NRF24L01,需要用SPI进行通信.因为2401上面写着MOSI.MISO.SS.RST,当时以为只要用到SPI就肯定有这几个引脚,以至于限制了自己的思维.只认识MI ...

  5. [转]SPI通信原理简介

    [转自]http://www.cnblogs.com/deng-tao/p/6004280.html 1.前言 SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 ...

  6. linux 下SPI通信注意事项(待续)

    一.2台Linux设备之间使用SPI通信 1.标准Linux只支持Master 模式.但是可以在驱动中修改为Slave模式: 2.硬件SPI可能支持Slave模式,也可能不支持.这个要提前确认好: 3 ...

  7. ESP8266开发之旅 基础篇⑤ ESP8266 SPI通信和I2C通信

        设备与设备之间的通信往往都伴随着总线的使用,而用得比较多的就当属于SPI总线和I2C总线,而恰巧NodeMcu也支持这两种总线通信,所以本章的主要内容就是讲解ESP8266 SPI和I2C总线 ...

  8. ESP8266 SPI通信

    设备与设备之间的通信往往都伴随着总线的使用,而用得比较多的就当属于SPI总线和I2C总线,而恰巧NodeMcu也支持这两种总线通信 1. SPI总线——SPI类库的使用 SPI是串行外设接口(Seri ...

  9. 工作笔记——CPLD与MCU通过SPI通信

    一.需求描述 MCU需要接收来自CPLD的升级固件数据 CPLD对MCU只进行发送数据,不接收MCU的数据 CPLD无法告知数据传输的开始和结束,需要MCU自行判断(CPLD只是数据透传,不做数据判断 ...

  10. OLED的波形曲线、进度条、图片显示(STM32 HAL库 模拟SPI通信 5线OLED屏幕)详细篇

    少废话,先上效果图 屏幕显示效果         全家福 一.基础认识及引脚介绍 屏幕参数: 尺寸:0.96英寸 分辨率:128*64 驱动芯片:SSD1306 驱动接口协议:SPI 引脚说明: 二. ...

随机推荐

  1. vue2 核心概念

    一.vue变量 所有的 vue变量 ,必须在data:中有注册(哪怕内容是空,相当于声明这个是变量,是vue变量而不是js变量).这里的变量也可以运算.(注意:所有的框架一定要注意js变量和框架的变量 ...

  2. [bzoj3033]太鼓达人 题解(搜索)

    Description 七夕祭上,Vani牵着cl的手,在明亮的灯光和欢乐的气氛中愉快地穿行.这时,在前面忽然出现了一台太鼓达人机台,而在机台前坐着的是刚刚被精英队伍成员XLk.Poet_shy和ly ...

  3. (转)OpenFire源码学习之二十七:Smack源码解析

    转:http://blog.csdn.net/huwenfeng_2011/article/details/43484199 Smack Smack是一个用于和XMPP服务器通信的类库,由此可以实现即 ...

  4. 介绍Win7 win8 上Java环境的配置

    ① windows 上的 java 环境搭建:(同时适合xp,vasta,win7,win8,win8.1) ② linux 上的java环境搭建(同时适合linux,unix,mac): 本文主要适 ...

  5. Android逆向之smali语法宝典

    0x01.前言 Android采用的是java语言进行开发,但是Android系统有自己的虚拟机Dalvik,代码编译最终不是采用的java的class,而是使用的smali.我们反编译得到的代码,j ...

  6. 文本表征:SoW、BoW、TF-IDF、Hash Trick、doc2vec、DBoW、DM

    原文地址:https://www.jianshu.com/p/2f2d5d5e03f8 一.文本特征 (一)基本文本特征提取 词语数量 常,负面情绪评论含有的词语数量比正面情绪评论更多. 字符数量 常 ...

  7. 洛谷 P2756 飞行员配对方案问题 (二分图匹配)

    题目链接:P2756 飞行员配对方案问题 题意 给定 \(m\) 个外籍飞行员和 \(n - m\) 个英国飞行员,每一架飞机需要一名英国飞行员和一名外籍飞行员,求最多能派出几架飞机. 思路 最大流 ...

  8. 错误 1 error C4996: 'getcwd': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getcwd. See online help for details.

    解决办法: 属性>C/C++>预处理定义>编辑>添加_CRT_NONSTDC_NO_DEPRECATE>应用

  9. VC++ 2010 创建高级Ribbon界面详解(3)

    3.工具栏 在传统的菜单式界面中,工具栏作为菜单的有益补充,被广泛使用.我们通过将一些常用命令放置到工具栏上,可以让用户直观而快速地访问到常用功能,提高了效率.在Ribbon界面中,工具栏得到了进一步 ...

  10. Ubuntu12.04下安装sourcenavigator-NG4.5阅读源代码

    大家知道Windows下有一个很好的查看源代码的软件sourceinsight,使用sourceinsight查看Linux内核代码.嵌入式软件开发中的C语言项目源代码.驱动程序代码很是方便.在Lin ...