在基于工控主板em9160的嵌入式应用中,经常需要与具有spi接口的芯片或电路单元,进行数据通讯。通常情况下,我们建议采用基于gpio的spi通讯协议实现方案,其优点是灵活性,客户可使用任意的gpio管脚来实现spi通讯,有关这方面的技术方案的实现,可参考英创网站的《使用gpio控制spi接口的ad芯片》一文。在spi通讯中,还有一类应用需要进行大数据量的传输,且要求尽可能高的波特率,这时若采用基于gpio的方案,就可能造成占用过多的cpu资源。因此需要使用em9160的硬件spi接口。
em9160的硬件spi接口为4线制spi,其管脚与gpio12–gpio15复用:
gpio管脚
spi接口信号
简要说明
gpio12
spi_din
串行数据输入
gpio13
spi_dout
串行数据输出
gpio14
spi_clk
串行数据同步时钟输出
gpio15
spi_cs#
片选控制输出,低电平有效
为了操作硬件spi接口,应用程序需要打开“spi1:”的设备文件:
handlehdevice;
hdevice = createfile( _t('spi1:'),
generic_read | generic_write,
0, null, open_existing, 0, null);
if (hdevice == invalid_handle_value)
{
return -1;
}
获得有效的文件句柄后,就可通过deviceiocontrol(…)函数来操作spi接口了。在em9160的sdk中已封装了相应的api函数,以方便应用程序的使用。相关的数据结构和函数定义,包括在“spi_api.h”中:
// 定义spi通讯参数结构
typedef struct
{
dword dwclkpolarity; // spi时钟极性:=0 或者 =1
dword dwclkphase; // spi时钟相位:=0 或者 =1
dword dwdatabitsize; // spi通讯数据帧的位数:8bit-16bit
dword dwbaudrate; // spi通讯波特率:最高波特率为10mbps
} spistate;
尽管em9160的硬件波特率可以高达100mbps,但为了保证可靠传输,建议应用程序把波特率控制在10mbps以下。spi时钟极性dwclkpolarity,在数据手册中通常记为cpol,= 0表示在没有数据传输时为低电平,= 1表示没有数据传输时为高电平。spi时钟相位dwclkphase,在数据手册中通常记为cpha,= 0表示时钟的第一个沿更新数据、第二个沿锁存数据,= 1表示时钟的第一个沿锁存数据、第二个沿更新数据。下面的事宜图,以8-bit数据为例:
cpha = 0的spi时序
cpha = 1的spi时序
spi通讯参数设置,通过以下两个函数实现:
// 功能描述:设置spi通讯参数。
// 输入参数 handle hdevice: 运行createfile( _t('spi1:'),....)函数返回的有效句柄
// spistate *pspistate: spi通讯参数
// 返回值 = true: spi通讯参数成功。
// = false: spi通讯参数失败。
bool setspistate( handle hdevice, spistate *pspistate );
// 功能描述:获取spi通讯参数。
// 输入参数 handle hdevice: 运行createfile( _t('spi1:'),....)函数返回的有效句柄
// 输出 spistate *pspistate: 获取的spi通讯参数
// 返回值 = true: spi通讯参数成功。
// = false: spi通讯参数失败。
bool getspistate( handle hdevice, spistate *pspistate );
在调用上述函数时,注意指针pspistate需要初始化分配空间。在设置好spi参数后,就可调用下面的函数进行具体的数据通讯了
// 功能描述:全双工收发spi数据
// 输入参数:
// handle hdevice: 运行createfile( _t('spi1:'),....)函数返回的有效句柄
// dword datlength: 需收发的数据样点长度, (datlength * 字节数/样点) < 1024。
// pvoid ptxbuf: 需发送的数据buffer,注意一个数据样点可能占用2个字节。
// pvoid prxbuf: 需接收的数据buffer,注意一个数据样点可能占用2个字节。
// 返回值 = true: spi数据通讯成功。
// = false: spi数据通讯失败。
bool spi_fullduplex( handle hdevice,
pvoid ptxbuf,
pvoid prxbuf,
dword datlength );
在调用上述spi函数,需要注意以下事宜:
1、spi设备驱动程序的内部buffer缺省设置为1k字节,因此每次通讯的字节数不能超过1k字节,对大于8-bit的数据,每个数据均按2个字节计算。
2、对8-bit的spi传输,收发数据buffer的类型应设置为uchar;而对9-bit – 16-bit的数据传输,其收发数据buffer的类型应设置为word。
3、参数datlength是以数据为单位计算的,所以若传输8-bit数据,其最大值为1024,若传输8-bit以上数据,其最大值为512。
4、对传输长度超过spi设备驱动程序的内部buffer长度的应用,可通过循环多次调用来实现数据通讯。
人工智能在视频时代能做些什么
LogiCORE IP JESD204内核概述
双绕组变压器差动保护中电流互感器的接线知识
新基建浪潮下,光网络发展面临哪些机遇与挑战?
Wind River推出物联网软件平台
英创信息技术工控主板EM9160介绍
区块链技术碰上音乐会发生什么
传感器检测精度再度提高,检测精度和分辨率提升了2个数量级
DySC 如何助力制造业高质量供电
UWB技术的主要特点及应用领域
三相稳压器的作用与功效是什么?三相稳压器的主要用途有哪些?
浅显易懂地讲清楚什么是电磁兼容
荷兰国际集团ING正在探索各种利用区块链的方式
一种权电阻网络参考正弦发生器
德科技公司支持用户在蜂窝车联网(C-V2X)和 LTE 信令的测试
欧瑞博全自动可视猫眼智能门锁P20震撼上市,小猫眼,大世界
开源赋能 普惠未来|统信软件寄语2023开放原子全球开源峰会
三大算法模型引领,突围复杂网络语言分析困境
仓库巡检无人机,沃尔玛、亚马逊、京东的最爱!
5G产业发展和商用问题探讨