0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

淺談SPI驅(qū)動API的使用方法

英創(chuàng)信息技術(shù) ? 作者:英創(chuàng)信息技術(shù) ? 2019-10-12 11:42 ? 次閱讀

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

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

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

操作SPI設(shè)備的基本步驟

1、打開SPI設(shè)備文件,其設(shè)備文件名為“SPI1:”
2、根據(jù)應(yīng)用需求,設(shè)置SPI數(shù)據(jù)幀的基本參數(shù),包括數(shù)據(jù)長度、波特率、時鐘極性等參數(shù)。
3、若需要用到外部中斷觸發(fā)SPI讀取操作,則需要設(shè)置外部GPIO中斷管腳,及中斷后的讀取數(shù)據(jù)的長度。
4、設(shè)置完成后,對常規(guī)操作,即可使用標準的ReadFile函數(shù)接收SPI數(shù)據(jù)、使用WriteFile發(fā)送SPI數(shù)據(jù)。
5、對需要讀寫混合操作的,則需要調(diào)用DeviceIoControl來實現(xiàn)。
6、當啟動了外部中斷,則通過調(diào)用DeviceIoControl來等待外部事件,然后再調(diào)用ReadFile函數(shù)來讀取已緩沖在驅(qū)動程序內(nèi)部的SPI數(shù)據(jù)。
7、調(diào)用CloseHandle將關(guān)閉SPI接口并清除相關(guān)設(shè)置。即使重新打開SPI設(shè)備文件,需重新設(shè)置SPI的參數(shù),才能進行讀寫。

SPI數(shù)據(jù)幀參數(shù)設(shè)置

初始化SPI,需要用到下面這個數(shù)據(jù)結(jié)構(gòu):
typedef struct _SPIFrame
{
UCHAR ucBitLength; //SPI數(shù)據(jù)bit長度,= 4、8、16
DWORD dwBitRate; //SPI波特率,20000000對應(yīng)20Mbps
BOOL bPhase; //時鐘相位
BOOL bPolarity; //時鐘極性
} SPIFrame , *PSPIFrame;

該數(shù)據(jù)結(jié)構(gòu)在hw_spi.h頭文件中進行的定義,數(shù)據(jù)結(jié)構(gòu)中的變量說明:
ucBitLength:SPI通訊的數(shù)據(jù)位長,EM9280/EM9287支持4bit、8bit、16bit三種數(shù)據(jù)位長格式,在hw_spi.h中定義了這三種數(shù)據(jù)位長的常量。
dwBitRate:SPI時鐘速率,為每秒傳輸?shù)腷it數(shù),參數(shù)20000000表示20Mbps,
bPhase:SPI時序相位設(shè)置(如下圖所示)
bPolarity:SPI時序極性設(shè)置(如下圖所示)

bPhase=0 , bPolarity=0

bPhase=1 , bPolarity=0

bPhase=0 , bPolarity=1

bPhase=1 , bPolarity=1

SPI設(shè)備的初始化例子

HANDLE hSPI;
SPIFrame ConfigSPI;
//打開設(shè)備驅(qū)動文件
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參數(shù)
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就可實現(xiàn)常規(guī)的SPI數(shù)據(jù)接收(讀)或發(fā)送(寫)。

SPI數(shù)據(jù)接收的函數(shù)調(diào)用:
ReadFile(hSPI, //設(shè)備驅(qū)動文件句柄
pDatBuf, //數(shù)據(jù)buffer指針,注意指針類型!
dwBufLength, //數(shù)據(jù)buffer的字節(jié)長度
pdwBytesRead, //實際讀取的SPI數(shù)據(jù)字節(jié)數(shù)
NULL)

pDatBuf:數(shù)據(jù)BUFF指針。需要注意的是SPI數(shù)據(jù)幀長度若為4-bit或8-bit,則每個SPI數(shù)據(jù)占用一個字節(jié),而對16-bit的SPI數(shù)據(jù),則占用2個字節(jié)。一般來說,對4-bit或8-bit的SPI傳輸,其數(shù)據(jù)buffer應(yīng)當是BYTE類型的;對16-bit的SPI傳輸,數(shù)據(jù)buffer則為WORD類型的。

dwBufLength:需要傳輸?shù)臄?shù)據(jù)字節(jié)長度。該參數(shù)是以字節(jié)為單位,其涵義也與SPI數(shù)據(jù)長度有關(guān),對16-bit的SPI傳輸,dwBufLength應(yīng)為2的倍數(shù)。

pdwBytesRead:SPI數(shù)據(jù)實際接收的字節(jié)數(shù)。一個正確的SPI數(shù)據(jù)接收調(diào)用后,指針pdwByteRead所包含的數(shù)據(jù)應(yīng)等于dwBufLength,才能表示SPI數(shù)據(jù)接收執(zhí)行完全正確。

SPI數(shù)據(jù)發(fā)送的函數(shù)調(diào)用:
WriteFile(hSPI, //設(shè)備驅(qū)動文件句柄
pDatBuf, //數(shù)據(jù)buffer指針,事先應(yīng)把數(shù)據(jù)填入
dwBufLength, //數(shù)據(jù)buffer的字節(jié)長度
pdwBytesWritten, //實際發(fā)送的SPI數(shù)據(jù)字節(jié)數(shù)
NULL)

發(fā)送函數(shù)的參數(shù)定義與接收函數(shù)的參數(shù)定義是一致的。特別的,一個正確的SPI數(shù)據(jù)發(fā)送調(diào)用后,指針pdwByteWritten所包含的數(shù)據(jù)應(yīng)等于dwBufLength。

讀寫混合型的SPI操作

在SPI的實際應(yīng)用,有時需要在一個連續(xù)的片選過程中,既有讀操作,也有寫操作。這時間需要用到所謂的混合型SPI操作。

混合型SPI操作需要用到以下數(shù)據(jù)結(jié)構(gòu):
typedef struct _SPITransfer
{
LPVOID pTxBuff; //SPI發(fā)送buffer指針
LPVOID pRxBuff; //SPI接收buffer指針
DWORD dwBufLength; //本次SPI傳輸?shù)淖止?jié)數(shù)
} SPITransfer;

pTxBuff:SPI輸出數(shù)據(jù)BUFF指針
pRxBuff:SPI讀入數(shù)據(jù)BUFF指針
dwBufLength:SPI數(shù)據(jù)傳輸長度,以字節(jié)為單位

注意,EM9280的SPI接口僅支持半雙工操作,因此在上述結(jié)構(gòu)中,只能有一個buffer指針為有效指針,另一個必須為NULL。dwBufLength的定義與單向讀寫的定義一致。具體的傳輸是通過DeviceIoControl來實現(xiàn)的,舉例說明,本例首先進行發(fā)送1個字節(jié)(8-bit SPI),然后接收2個字節(jié)。

SPITransfer Trans[2];
BYTE Tx[16], Rx[16]; //buffer足夠大
Tx[0] = 0xE5; //發(fā)送的字節(jié)
Trans[0].pTxBuf = Tx;
Trans[0].pRxBuf = NULL;
Trans[0].dwBufLength = 1; //要發(fā)送1字節(jié)
Trans[1].pTxBuf = NULL;
Trans[1].pRxBuf = Rx;
Trans[1].dwBufLength = 2; //要接收2字節(jié)
DeviceIoControl(hSPI,
SPI_IOCTL_EXCHANGE,
Trans, //in buffer
sizeof(Trans) , //in buffer size
NULL,
0,
NULL,
NULL))

在上述調(diào)用中需要注意的是,DeviceIoControl()輸入?yún)?shù)中的buffer長度必須是數(shù)據(jù)結(jié)構(gòu)SPITransfer大小的整倍數(shù),否則將被視作無效參數(shù)。

外部中斷觸發(fā)的SPI操作

外部中斷觸發(fā)的SPI操作,主要是利用SPI的高速特性,進行實時的大數(shù)據(jù)量讀取。因為SPI的接線非常簡單,作為一種高效低成本的接口模式在工業(yè)控制領(lǐng)域有廣泛的應(yīng)用。使用這種SPI操作方式,需要用到以下數(shù)據(jù)結(jié)構(gòu):
typedef struct _SPI_IrqTransfer
{
DWORD dwGpioPin; //外部中斷管腳,上升沿觸發(fā)中斷
DWORD dwBufLength; //中斷觸發(fā)的SPI傳輸?shù)淖止?jié)數(shù),小于64KB
DWORD dwRVSD; //保留,必須設(shè)置為0
} SPI_IrqTransfer;

dwGpioPin:要用作外部中斷源的GPIO引腳
dwBufLength:要讀取的數(shù)據(jù)字節(jié)長度
dwRVSD:系統(tǒng)保留,必須設(shè)置為0

在上述結(jié)構(gòu)中,dwBufLength的定義與單向讀寫的定義一致,如果dwGpioPin與dwBufLength同時設(shè)置為0,則將關(guān)閉已打開的GPIO中斷資源并禁止該功能啟動。dwGpioPin為EM9280主板的GPIO引腳編號,與GPIO操作時的引腳數(shù)據(jù)一致。注意:由于系統(tǒng)功能的占用,不是所有的GPIO引腳都可以用作外部中斷觸發(fā)源。

?EM9280可以使用的GPIO引腳有:GPIO0、GPIO1、GPIO6、GPIO7、GPIO10、GPIO11、GPIO20、GPIO21、GPIO22、GPIO23。

?EM9287和EM9281可以使用的GPIO引腳有:GPIO0 - GPIO23。

該操作的具體的設(shè)置操作仍然需要調(diào)用DeviceIoControl()來實現(xiàn)。
SPI_IrqTransfer irq_transfer;
irq_transfer. dwGpioPin=GPIO0; //使用GPIO0作為SPI的外部中斷源
irq_transfer. dwBufLength=1024; //中斷產(chǎn)生后需要讀取1024字節(jié)的數(shù)據(jù)
irq_transfer. dwRVSD=0;
DeviceIoControl(hSPI,
SPI_IOCTL_SSP_IRQTransfer,
& irq_transfer, //輸入?yún)?shù)
sizeof(SPI_IrqTransfer), //輸入?yún)?shù)字節(jié)數(shù)
NULL,
0,
NULL,
NULL);

設(shè)置完成即啟動外部中斷自動觸發(fā)SPI操作,一旦中斷產(chǎn)生,驅(qū)動程序?qū)⒆詣咏邮誨wBufLength長度的數(shù)據(jù),存儲在驅(qū)動程序的內(nèi)部緩沖區(qū)中。數(shù)據(jù)接收完成后,將發(fā)送事件通知應(yīng)用層。應(yīng)用程序可通過DeviceIoControl()調(diào)用來等待該事件,得到事件后再調(diào)用ReadFile讀取數(shù)據(jù)。通過調(diào)用DeviceIOControl()等待SPI事件,可以給定一個時間參數(shù)作為等待超時的條件,以ms為單位。成功等到SPI執(zhí)行完成的消息時,DeviceIoControl會返回TRUE,否則返回FALSE。SPI事件等待的調(diào)用方法如下:
DeviceIoControl(hSPI,
SPI_IOCTL_SSP_WaitSPIEvent,
&DelayTime, //等待超時,時間為ms
Sizeof(DWORD),
NULL,
0,
NULL,
NULL)

調(diào)用上述方法啟動了外部中斷觸發(fā)SPI讀取數(shù)據(jù)的功能后,該功能將一直存在,即每次在所設(shè)置的GPIO引腳上產(chǎn)生中斷信號,都會執(zhí)行一次SPI讀取操作,直到應(yīng)用程序關(guān)閉該中斷,即設(shè)置dwGpioPin和dwBufLength等于0,再調(diào)用DeviceIoControl()進行設(shè)置操作。

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1461

    瀏覽量

    61492
  • SPI
    SPI
    +關(guān)注

    關(guān)注

    17

    文章

    1669

    瀏覽量

    90735
  • 嵌入式主板
    +關(guān)注

    關(guān)注

    7

    文章

    6081

    瀏覽量

    34942
收藏 人收藏

    評論

    相關(guān)推薦

    LED驅(qū)動電源灌封膠的使用方法

    LED驅(qū)動電源灌封膠的使用方法LED驅(qū)動電源灌封膠適用于一般電子元器件、電源模塊和線路板的灌封保護,以及各種電子電器的灌封,如開關(guān)電源、驅(qū)動電源、汽車HID燈模塊電源、汽車點火系統(tǒng)模塊
    發(fā)表于 02-15 10:22

    MLDL之API:關(guān)于各國內(nèi)外大平臺API簡介、使用方法之詳細攻略

    MLDL之API:關(guān)于各國內(nèi)外大平臺API簡介、使用方法之詳細攻略
    發(fā)表于 12-19 17:00

    串行通信基礎(chǔ)知識與UART驅(qū)動構(gòu)件使用方法

    慕課蘇州大學(xué).嵌入式開發(fā)及應(yīng)用.第二章.入門與軟件框架.串行通信基礎(chǔ)知識與UART驅(qū)動構(gòu)件使用方法0 目錄2 入門與軟件框架2.1 串行通信基礎(chǔ)知識與UART驅(qū)動構(gòu)件使用方法2.1.1
    發(fā)表于 12-20 06:21

    介紹SPI使用方法

    ,這篇介紹SPI使用方法,流程與TIM類似。大致總結(jié)為以下幾個步驟:在RT-thread settings中使能對應(yīng)的驅(qū)動框架在stm32f4xx_hal_conf.h中使能對應(yīng)的模塊(HAL_XX_MODULE_ENABLE
    發(fā)表于 02-17 06:32

    IGBT驅(qū)動模塊EXB841使用方法的改進

    IGBT驅(qū)動模塊EXB841使用方法的改進 摘要: 本文對目前在電力電子技術(shù)中廣泛使用的IGBT驅(qū)動模塊EXB841的使用方法進行了改進,克服了EXB841本身的缺陷,提高了保護
    發(fā)表于 05-08 15:11 ?84次下載

    淺談電腦燈控制臺的基本使用方法

    淺談電腦燈控制臺的基本使用方法 電腦燈自1981年問世以來,就在各類演出、演播室的節(jié)目制作中得到應(yīng)用??梢哉f電腦燈的出現(xiàn)是舞
    發(fā)表于 12-12 10:18 ?4249次閱讀

    對高級驅(qū)動輔助系統(tǒng)的傳感器的使用方法

    本文檔介紹了對高級驅(qū)動輔助系統(tǒng)的傳感器的使用方法,供網(wǎng)友參考。
    發(fā)表于 09-13 18:37 ?1次下載

    淺談光耦的使用方法_章圣焰

    淺談光耦的使用方法及設(shè)計電路的分析技巧
    發(fā)表于 10-16 13:44 ?6次下載

    LUA腳本的繪圖API函數(shù)的使用方法及使用函數(shù)的注意事項

    物聯(lián)型串口屏通過 LUA 腳本配合工程可以完成大部分的內(nèi)部邏輯處理,可以做到讓 MCU 只參與數(shù)據(jù)處理,不參與屏的邏輯處理。本文將介紹大彩 LUA 腳本 API 函數(shù)中的繪圖 API 函數(shù)使用方法,以及使用函數(shù)的注意事項。
    發(fā)表于 10-17 08:00 ?9次下載
    LUA腳本的繪圖<b class='flag-5'>API</b>函數(shù)的<b class='flag-5'>使用方法</b>及使用函數(shù)的注意事項

    LUA腳本API函數(shù)中的回調(diào)函數(shù)使用方法和注意事項資料和程序免費下載

    本文檔的主要內(nèi)容詳細介紹的是LUA腳本API函數(shù)中的回調(diào)函數(shù)使用方法和注意事項資料和程序免費下載。
    發(fā)表于 10-17 08:00 ?5次下載
    LUA腳本<b class='flag-5'>API</b>函數(shù)中的回調(diào)函數(shù)<b class='flag-5'>使用方法</b>和注意事項資料和程序免費下載

    淺談keil軟件的使用方法

    Keil的使用方法 - 常用功能(三)
    的頭像 發(fā)表于 04-07 14:50 ?4697次閱讀
    <b class='flag-5'>淺談</b>keil軟件的<b class='flag-5'>使用方法</b>

    淺談壓力傳感器的使用方法及注意事項

    淺談壓力傳感器的使用方法及注意事項
    發(fā)表于 03-10 17:36 ?14次下載
    <b class='flag-5'>淺談</b>壓力傳感器的<b class='flag-5'>使用方法</b>及注意事項

    Compose中的動畫API概覽及使用方法

    我們將通過本文介紹 Compose 中的一些動畫 API,并探討如何有效地使用它們。Compose 中的動畫 API 是我們構(gòu)想的全新 API,這些 API 中有許多是聲明式的,您可以
    的頭像 發(fā)表于 06-06 17:48 ?2229次閱讀

    Linux驅(qū)動-spidev驅(qū)動使用方法

    Linux內(nèi)核集成了spidev驅(qū)動,提供了SPI設(shè)備的用戶空間API,支持用于半雙工通信的read()和write()訪問接口以及用于全雙工通信和I/O配置的ioctl()接口;使用時,只需
    的頭像 發(fā)表于 04-07 10:22 ?4328次閱讀

    淺談錫膏的儲存及使用方法

    錫膏(焊錫膏)是電子組裝過程中常用的材料,它的儲存和使用方法對保證焊接質(zhì)量和性能至關(guān)重要。以下是詳細的儲存及使用方法
    的頭像 發(fā)表于 06-27 10:02 ?481次閱讀