EM9170 SPI接口用户指南

 2011-8-26          [nemail]    
[lablebox]

1、功能描述

 

        EM9170提供了一路硬件4线制SPI接口供用户使用,它的4条信号线与系统的GPIO复用,系统上电后,对应管脚默认为GPIO状态(详见《EM9170工控主板数据手册 》),当在应用程序中打开SPI接口后,对应的信号线将自动切换到SPI状态。EM9170 SPI接口支持以下特性:

        · 4线制全双工同步串行接口
        · 主控(Master)工作模式 
        · 可以配置SPI时钟信号(SPI_SCLK)的相位和极性 
        · 支持1至32-bit可配置的数据通讯位宽 
        · 支持DMA操作方式 
        · 最高波特率16Mbps

 

        SPI通讯的时序简单,主要是在SPI时钟(SCLK)的同步下,在两个设备的移位寄存器间进行数据通讯。EM9170的SPI接口可以配置SCLK的极性(POL)和相位(PHA),图1为设置不同的相位和极性配置时,时钟信号的输出波形。

图1:SPI总线SCLK和MOSI,MISO之间的关系

 

        图1中的时钟极性(POL)决定了SPI串行时钟信号线(SCLK)空闲时的电平,如果POL=0,串行时钟空闲时为低电平,POL=1串行时钟空闲时为高电平。时钟相位(PHA) 用来决定数据在什么时刻输出和锁存输入。如果 PHA=0,SPI控制器在SCLK的下降沿输出数据,在SCLK上升沿锁存输入的数据。当PHA=1时,将在SCLK上升沿输出数据,而在SCLK下降沿锁存输入数据。SPI线上的主从设备必须根据具体情况设置匹配的传输时序模式,时序只有匹配,数据才能正常通讯。

 

2、操作说明

 

2.1  打开SPI端口
        通过调用CreateFile( )函数来打开系统的SPI设备,设备名称为“SPI1:”如下所示:


// Open the SPI port.
hSPI = CreateFile (TEXT”SPI1:”, // name of device
        GENERIC_READ | GENERIC_WRITE, // access (read-write) mode
        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)

 

2.2  数据通讯
        在进行SPI数据通讯前,需要调用SPIConfig()函数对SPI总线做相应的配置,函数申明如下:

 

BOOL SPIConfig( HANDLE hCSPI, PCSPI_BUSCONFIG_T pCspiConfig );

 

        其中参数pCspiConfig为SPI总线配置结构体,其定义如下:

 

typedef struct
{ // CSPI bus configuration
        UINT32 freq; // SPI波特率:<=16Mbps
        UINT8 bitcount; // 数据位宽:1~32bit
        BOOL pol; // 设置时钟极性
        BOOL pha; // 设置时钟相位
} CSPI_BUSCONFIG_T, *PCSPI_BUSCONFIG_T;

 

        用户调用SPIExchange()函数来完成一次数据收发,函数申明如下:

 

BOOL SPIExchange(
        HANDLE hCSPI, // 由CreateFile创建的HANDLE
        PVOID pTxBuf, // 发送数据缓存
        PVOID pRxBuf, // 接收数据缓存
        UINT32 xchCnt ); // 传输的数据个数

 

        需要注意的是,参数pTxBuf和pRxBuf是LPVOID型指针变量,当设置SPI通讯位宽(CSPI_BUSCONFIG_T的bitcount成员)为1~8时,数据收发缓存(pTxBuf和pRxBuf)需要定义为UNIT8数据类型,当SPI通讯位宽为9~16时,数据收发缓存需要定义为UINT16类型,当SPI通讯位数为17~32时,数据收发缓存要定义成UINT32数据类型。

 

        下面是示例程序片断:

 

HANDLE hSPI; // 定义SPI操作HANDLE
DWORD dwXchCnt; // 定义传输字节个数
CSPI_BUSCONFIG_T spiConfig; // 定义SPI总线配置数据结构体

spiConfig.bitcount = 8; // bit count=8
spiConfig.freq = 16000000; // XCH speed = 16M
spiConfig.pha = FALSE; // Phase 0 operation
spiConfig.pol = FALSE; // Active high operation

// if 1<=cspiConfig.bitcount<=8 收发缓存需要定义为UINT8类型
UINT8 TxData[1024] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
UINT8 RxData[1024];

// if 9<=cspiConfig.bitcount<=16 收发缓存需要定义为UINT16类型
// UINT16 TxData[1024] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
// UINT16 RxData[1024];

// if 17<=cspiConfig.bitcount<=32 收发缓存需要定义为UINT32类型
// UINT32 TxData[1024] = { 0x01, 0x02, 0x03, 0x04, 0x05 };
// UINT32 RxData[1024];

// 打开SPI总线 (SPIOpen( )内部调用了CreateFile()函数)
hSPI = SPIOpen( TEXT(“SPI1:”) );
SPIConfig( hSPI, &spiConfig ); // 设置SPI总线配置信息
dwXchCnt = 5; // 传输5个数据
SPIExchange( hSPI, TxData, RxData, dwXchCnt ); // 进行SPI数据传输,传输5个数据

 

2.3  关闭SPI
        调用CloseHandle函数关闭由CreateFile创建的HANDLE即可关闭SPI端口。

 

CloseHandle( hSPI);

[lablebox]