java系统找不到指定文件怎么解决
405
2022-10-23
浅谈SPI驱动API的使用方法
本文以下部分重点介绍SPI驱动API的使用方法。
操作SPI设备的基本步骤
SPI数据帧参数设置
初始化SPI,需要用到下面这个数据结构: typedef struct _SPIFrame { UCHAR ucBitLength; //SPI数据bit长度,= 4、8、16 DWORD dwBitRate; //SPI波特率,20000000对应20Mbps BOOL bPhase; //时钟相位 BOOL bPolarity; //时钟极性 } SPIFrame , *PSPIFrame;
该数据结构在hw_spi.h头文件中进行的定义,数据结构中的变量说明: ucBitLength:SPI通讯的数据位长,EM9280/EM9287支持4bit、8bit、16bit三种数据位长格式,在hw_spi.h中定义了这三种数据位长的常量。 dwBitRate:SPI时钟速率,为每秒传输的bit数,参数20000000表示20Mbps, bPhase:SPI时序相位设置(如下图所示) bPolarity:SPI时序极性设置(如下图所示)
bPhase=0 , bPolarity=0
bPhase=1 , bPolarity=0
bPhase=0 , bPolarity=1
bPhase=1 , bPolarity=1
SPI设备的初始化例子
HANDLE hSPI; SPIFrame ConfigSPI; //打开设备驱动文件 hSPI = CreateFile(L”SPI1:”, //name of device GENERIC_READ|GENERIC_WRITE, //desired access FILE_SHARE_READ|FILE_SHARE_WRITE, //sharing mode NULL, //security attributes (ignored) OPEN_EXISTING, //creation disposition FILE_FLAG_RANDOM_ACCESS, //flags/attributes NULL); //template file (ignored) if(hSPI == FALSE ) { printf('SPI Open False!!!\r\n'); return 0; } //配置SPI参数 ConfigSPI.ucBitLength=SSP_WORD_LENGTH_8BITS; //Len_8BITS ConfigSPI.dwBitRate=10000000; //10Mbps ConfigSPI.bPhase=0; ConfigSPI.bPolarity=0; DeviceIoControl(hSPI, //file handle to the driver SPI_IOCTL_SSPCONFIGURE, //I/O control code &ConfigSPI, //in buffer sizeof(ConfigSPI), //in buffer size NULL, 0, NULL, NULL)
SPI接口的单向读写操作
用标准的ReadFile和WriteFile就可实现常规的SPI数据接收(读)或发送(写)。
SPI数据接收的函数调用: ReadFile(hSPI, //设备驱动文件句柄 pDatBuf, //数据buffer指针,注意指针类型! dwBufLength, //数据buffer的字节长度 pdwBytesRead, //实际读取的SPI数据字节数 NULL)
pDatBuf:数据BUFF指针。需要注意的是SPI数据帧长度若为4-bit或8-bit,则每个SPI数据占用一个字节,而对16-bit的SPI数据,则占用2个字节。一般来说,对4-bit或8-bit的SPI传输,其数据buffer应当是BYTE类型的;对16-bit的SPI传输,数据buffer则为WORD类型的。
dwBufLength:需要传输的数据字节长度。该参数是以字节为单位,其涵义也与SPI数据长度有关,对16-bit的SPI传输,dwBufLength应为2的倍数。
pdwBytesRead:SPI数据实际接收的字节数。一个正确的SPI数据接收调用后,指针pdwByteRead所包含的数据应等于dwBufLength,才能表示SPI数据接收执行完全正确。
SPI数据发送的函数调用: WriteFile(hSPI, //设备驱动文件句柄 pDatBuf, //数据buffer指针,事先应把数据填入 dwBufLength, //数据buffer的字节长度 pdwBytesWritten, //实际发送的SPI数据字节数 NULL)
发送函数的参数定义与接收函数的参数定义是一致的。特别的,一个正确的SPI数据发送调用后,指针pdwByteWritten所包含的数据应等于dwBufLength。
读写混合型的SPI操作
在SPI的实际应用,有时需要在一个连续的片选过程中,既有读操作,也有写操作。这时间需要用到所谓的混合型SPI操作。
混合型SPI操作需要用到以下数据结构: typedef struct _SPITransfer { LPVOID pTxBuff; //SPI发送buffer指针 LPVOID pRxBuff; //SPI接收buffer指针 DWORD dwBufLength; //本次SPI传输的字节数 } SPITransfer;
pTxBuff:SPI输出数据BUFF指针 pRxBuff:SPI读入数据BUFF指针 dwBufLength:SPI数据传输长度,以字节为单位
注意,EM9280的SPI接口仅支持半双工操作,因此在上述结构中,只能有一个buffer指针为有效指针,另一个必须为NULL。dwBufLength的定义与单向读写的定义一致。具体的传输是通过DeviceIoControl来实现的,举例说明,本例首先进行发送1个字节(8-bit SPI),然后接收2个字节。
SPITransfer Trans[2]; BYTE Tx[16], Rx[16]; //buffer足够大 Tx[0] = 0xE5; //发送的字节 Trans[0].pTxBuf = Tx; Trans[0].pRxBuf = NULL; Trans[0].dwBufLength = 1; //要发送1字节 Trans[1].pTxBuf = NULL; Trans[1].pRxBuf = Rx; Trans[1].dwBufLength = 2; //要接收2字节 DeviceIoControl(hSPI, SPI_IOCTL_EXCHANGE, Trans, //in buffer sizeof(Trans) , //in buffer size NULL, 0, NULL, NULL))
在上述调用中需要注意的是,DeviceIoControl()输入参数中的buffer长度必须是数据结构SPITransfer大小的整倍数,否则将被视作无效参数。
外部中断触发的SPI操作
外部中断触发的SPI操作,主要是利用SPI的高速特性,进行实时的大数据量读取。因为SPI的接线非常简单,作为一种高效低成本的接口模式在工业控制领域有广泛的应用。使用这种SPI操作方式,需要用到以下数据结构: typedef struct _SPI_IrqTransfer { DWORD dwGpioPin; //外部中断管脚,上升沿触发中断 DWORD dwBufLength; //中断触发的SPI传输的字节数,小于64KB DWORD dwRVSD; //保留,必须设置为0 } SPI_IrqTransfer;
dwGpioPin:要用作外部中断源的GPIO引脚 dwBufLength:要读取的数据字节长度 dwRVSD:系统保留,必须设置为0
在上述结构中,dwBufLength的定义与单向读写的定义一致,如果dwGpioPin与dwBufLength同时设置为0,则将关闭已打开的GPIO中断资源并禁止该功能启动。dwGpioPin为EM9280主板的GPIO引脚编号,与GPIO操作时的引脚数据一致。注意:由于系统功能的占用,不是所有的GPIO引脚都可以用作外部中断触发源。
•EM9280可以使用的GPIO引脚有:GPIO0、GPIO1、GPIO6、GPIO7、GPIO10、GPIO11、GPIO20、GPIO21、GPIO22、GPIO23。
•EM9287和EM9281可以使用的GPIO引脚有:GPIO0 - GPIO23。
该操作的具体的设置操作仍然需要调用DeviceIoControl()来实现。 SPI_IrqTransfer irq_transfer; irq_transfer. dwGpioPin=GPIO0; //使用GPIO0作为SPI的外部中断源 irq_transfer. dwBufLength=1024; //中断产生后需要读取1024字节的数据 irq_transfer. dwRVSD=0; DeviceIoControl(hSPI, SPI_IOCTL_SSP_IRQTransfer, & irq_transfer, //输入参数 sizeof(SPI_IrqTransfer), //输入参数字节数 NULL, 0, NULL, NULL);
调用上述方法启动了外部中断触发SPI读取数据的功能后,该功能将一直存在,即每次在所设置的GPIO引脚上产生中断信号,都会执行一次SPI读取操作,直到应用程序关闭该中断,即设置dwGpioPin和dwBufLength等于0,再调用DeviceIoControl()进行设置操作。
SPI操作相关的范例代码请参考光盘中的EM9280_SPIDemo,或来邮件索取或咨询。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~