激情综合丁香-激情综合六月-激情综合婷婷亚洲图片-激情综合图区-激情综合网五月

EM9280系列SPI接口應用方案

 2014-7-28             

  EM9280系列產品包括EM9280、EM9287和EM9281,是英創公司新一代的低成本嵌入式主板產品。該主板的SPI接口,在內部DMA(Direct Memory Access直接內存存取)機制的驅動下,其最高數據傳輸速度可達20Mbps。另外SPI接口可支持4bit、8bit、16bit位長的數據通訊;也可對SPI時序的極性及相位進行設置。

 

  針對SPI接口的應用特點,EM9280的SPI的驅動進行了專門的優化,不僅可支持常規的SPI讀、寫操作,還可支持外部中斷觸發的讀寫操作。中斷觸發的讀寫操作,主要應用于工業控制的高速數據采集。另一方面,針對AD芯片控制需求,SPI驅動還支持混合讀寫模式的數據傳輸操作。

 

  本文以下部分重點介紹SPI驅動API的使用方法。

 

操作SPI設備的基本步驟

 

  1、打開SPI設備文件,其設備文件名為“SPI1:”
  2、根據應用需求,設置SPI數據幀的基本參數,包括數據長度、波特率、時鐘極性等參數。
  3、若需要用到外部中斷觸發SPI讀取操作,則需要設置外部GPIO中斷管腳,及中斷后的讀取數據的長度。
  4、設置完成后,對常規操作,即可使用標準的ReadFile函數接收SPI數據、使用WriteFile發送SPI數據。
  5、對需要讀寫混合操作的,則需要調用DeviceIoControl來實現。
  6、當啟動了外部中斷,則通過調用DeviceIoControl來等待外部事件,然后再調用ReadFile函數來讀取已緩沖在驅動程序內部的SPI數據。
  7、調用CloseHandle將關閉SPI接口并清除相關設置。即使重新打開SPI設備文件,需重新設置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操作,一旦中斷產生,驅動程序將自動接收dwBufLength長度的數據,存儲在驅動程序的內部緩沖區中。數據接收完成后,將發送事件通知應用層。應用程序可通過DeviceIoControl()調用來等待該事件,得到事件后再調用ReadFile讀取數據。通過調用DeviceIOControl()等待SPI事件,可以給定一個時間參數作為等待超時的條件,以ms為單位。成功等到SPI執行完成的消息時,DeviceIoControl會返回TRUE,否則返回FALSE。SPI事件等待的調用方法如下:
  DeviceIoControl(hSPI,
    SPI_IOCTL_SSP_WaitSPIEvent,
    &DelayTime, // 等待超時,時間為ms
    Sizeof(DWORD),
    NULL,
    0,
    NULL,
    NULL)

 

  調用上述方法啟動了外部中斷觸發SPI讀取數據的功能后,該功能將一直存在,即每次在所設置的GPIO引腳上產生中斷信號,都會執行一次SPI讀取操作,直到應用程序關閉該中斷,即設置dwGpioPin和dwBufLength等于0,再調用DeviceIoControl()進行設置操作。

 

  SPI操作相關的范例代碼請參考光盤中的EM9280_SPIDemo,或來郵件索取或咨詢。

主站蜘蛛池模板: 国产精品主播| 免费一级成人免费观看| 啪一啪在线| 精品久久不卡| 日韩高清性爽一级毛片免费| 欧美一级网址| 国产成人一区二区三区高清| 黄色大片免费在线观看| 国产二级毛片| 久草国产视频| 日韩小视频在线播放| 亚洲午夜精品一级在线| 一区二区网站在线观看| 日本一级毛片免费播放| 亚洲国产一区在线二区三区| 男人看片网址| 欧美zzzz| 欧美美女一区二区三区| 国产成人精品免费视频软件| 特级aa毛片在线播放| 精品夜夜春夜夜爽久久| 丁香六月色婷婷| 国产亚洲欧美一区二区| 免费人成在线观看视频不卡| 特级生活片| 亚洲精品久久久久中文字小说| 91福利网址| aaaa一级片| 一区二区视频在线观看免费的 | 亚洲高清视频一区| 免费在线黄网站| 国外成人免费视频| 国产日产欧美精品一区二区三区| 国产精品亚洲欧美日韩区| 涩涩国产精品福利在线观看| 国产呦精品一区二区三区网站| 欧美另类69xxxxx免费| 日本精品中文字幕有码| 色综合国产| 日韩美女中文字幕| 善良的翁熄日本中文字幕1|