在基于工控主板EM9160的嵌入式應(yīng)用中,經(jīng)常需要與具有SPI接口的芯片或電路單元,進(jìn)行數(shù)據(jù)通訊。通常情況下,我們建議采用基于GPIO的SPI通訊協(xié)議實(shí)現(xiàn)方案,其優(yōu)點(diǎn)是靈活性,客戶可使用任意的GPIO管腳來實(shí)現(xiàn)SPI通訊,有關(guān)這方面的技術(shù)方案的實(shí)現(xiàn),可參考英創(chuàng)網(wǎng)站的《使用GPIO控制SPI接口的AD芯片》一文。在SPI通訊中,還有一類應(yīng)用需要進(jìn)行大數(shù)據(jù)量的傳輸,且要求盡可能高的波特率,這時(shí)若采用基于GPIO的方案,就可能造成占用過多的CPU資源。因此需要使用EM9160的硬件SPI接口。
EM9160的硬件SPI接口為4線制SPI,其管腳與GPIO12–GPIO15復(fù)用:
GPIO管腳 | SPI接口信號(hào) | 簡(jiǎn)要說明 |
GPIO12 | SPI_DIN | 串行數(shù)據(jù)輸入 |
GPIO13 | SPI_DOUT | 串行數(shù)據(jù)輸出 |
GPIO14 | SPI_CLK | 串行數(shù)據(jù)同步時(shí)鐘輸出 |
GPIO15 | SPI_CS# | 片選控制輸出,低電平有效 |
為了操作硬件SPI接口,應(yīng)用程序需要打開“SPI1:”的設(shè)備文件:
HANDLEhDevice;
hDevice = CreateFile( _T('SPI1:'),
GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
return -1;
}
獲得有效的文件句柄后,就可通過DeviceIoControl(…)函數(shù)來操作SPI接口了。在EM9160的SDK中已封裝了相應(yīng)的API函數(shù),以方便應(yīng)用程序的使用。相關(guān)的數(shù)據(jù)結(jié)構(gòu)和函數(shù)定義,包括在“SPI_API.h”中:
// 定義SPI通訊參數(shù)結(jié)構(gòu)
typedef struct
{
DWORD dwCLKPolarity; // SPI時(shí)鐘極性:=0 或者 =1
DWORD dwCLKPhase; // SPI時(shí)鐘相位:=0 或者 =1
DWORD dwDataBitSize; // SPI通訊數(shù)據(jù)幀的位數(shù):8bit-16bit
DWORD dwBaudRate; // SPI通訊波特率:最高波特率為10Mbps
} SPISTATE;
盡管EM9160的硬件波特率可以高達(dá)100Mbps,但為了保證可靠傳輸,建議應(yīng)用程序把波特率控制在10Mbps以下。SPI時(shí)鐘極性dwCLKPolarity,在數(shù)據(jù)手冊(cè)中通常記為CPOL,= 0表示在沒有數(shù)據(jù)傳輸時(shí)為低電平,= 1表示沒有數(shù)據(jù)傳輸時(shí)為高電平。SPI時(shí)鐘相位dwCLKPhase,在數(shù)據(jù)手冊(cè)中通常記為CPHA,= 0表示時(shí)鐘的第一個(gè)沿更新數(shù)據(jù)、第二個(gè)沿鎖存數(shù)據(jù),= 1表示時(shí)鐘的第一個(gè)沿鎖存數(shù)據(jù)、第二個(gè)沿更新數(shù)據(jù)。下面的事宜圖,以8-bit數(shù)據(jù)為例:
CPHA = 0的SPI時(shí)序
CPHA = 1的SPI時(shí)序
SPI通訊參數(shù)設(shè)置,通過以下兩個(gè)函數(shù)實(shí)現(xiàn):
// 功能描述:設(shè)置SPI通訊參數(shù)。
// 輸入?yún)?shù) HANDLE hDevice: 運(yùn)行CreateFile( _T('SPI1:'),....)函數(shù)返回的有效句柄
// SPISTATE *pSPIState: SPI通訊參數(shù)
// 返回值 = TRUE: SPI通訊參數(shù)成功。
// = FALSE: SPI通訊參數(shù)失敗。
BOOL SetSPIState( HANDLE hDevice, SPISTATE *pSPIState );
// 功能描述:獲取SPI通訊參數(shù)。
// 輸入?yún)?shù) HANDLE hDevice: 運(yùn)行CreateFile( _T('SPI1:'),....)函數(shù)返回的有效句柄
// 輸出 SPISTATE *pSPIState: 獲取的SPI通訊參數(shù)
// 返回值 = TRUE: SPI通訊參數(shù)成功。
// = FALSE: SPI通訊參數(shù)失敗。
BOOL GetSPIState( HANDLE hDevice, SPISTATE *pSPIState );
在調(diào)用上述函數(shù)時(shí),注意指針pSPIState需要初始化分配空間。在設(shè)置好SPI參數(shù)后,就可調(diào)用下面的函數(shù)進(jìn)行具體的數(shù)據(jù)通訊了
// 功能描述:全雙工收發(fā)SPI數(shù)據(jù)
// 輸入?yún)?shù):
// HANDLE hDevice: 運(yùn)行CreateFile( _T('SPI1:'),....)函數(shù)返回的有效句柄
// DWORD DatLength: 需收發(fā)的數(shù)據(jù)樣點(diǎn)長(zhǎng)度, (DatLength * 字節(jié)數(shù)/樣點(diǎn)) < 1024。
// PVOID pTxBuf: 需發(fā)送的數(shù)據(jù)BUFFER,注意一個(gè)數(shù)據(jù)樣點(diǎn)可能占用2個(gè)字節(jié)。
// PVOID pRxBuf: 需接收的數(shù)據(jù)BUFFER,注意一個(gè)數(shù)據(jù)樣點(diǎn)可能占用2個(gè)字節(jié)。
// 返回值 = TRUE: SPI數(shù)據(jù)通訊成功。
// = FALSE: SPI數(shù)據(jù)通訊失敗。
BOOL SPI_FullDuplex( HANDLE hDevice,
PVOID pTxBuf,
PVOID pRxBuf,
DWORD DatLength );
在調(diào)用上述SPI函數(shù),需要注意以下事宜:
1、SPI設(shè)備驅(qū)動(dòng)程序的內(nèi)部buffer缺省設(shè)置為1K字節(jié),因此每次通訊的字節(jié)數(shù)不能超過1K字節(jié),對(duì)大于8-bit的數(shù)據(jù),每個(gè)數(shù)據(jù)均按2個(gè)字節(jié)計(jì)算。
2、對(duì)8-bit的SPI傳輸,收發(fā)數(shù)據(jù)buffer的類型應(yīng)設(shè)置為UCHAR;而對(duì)9-bit – 16-bit的數(shù)據(jù)傳輸,其收發(fā)數(shù)據(jù)buffer的類型應(yīng)設(shè)置為WORD。
3、參數(shù)DatLength是以數(shù)據(jù)為單位計(jì)算的,所以若傳輸8-bit數(shù)據(jù),其最大值為1024,若傳輸8-bit以上數(shù)據(jù),其最大值為512。
4、對(duì)傳輸長(zhǎng)度超過SPI設(shè)備驅(qū)動(dòng)程序的內(nèi)部buffer長(zhǎng)度的應(yīng)用,可通過循環(huán)多次調(diào)用來實(shí)現(xiàn)數(shù)據(jù)通訊。
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6092瀏覽量
35838
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
工控主板特點(diǎn)與應(yīng)用場(chǎng)景介紹

工控主板在數(shù)控機(jī)床設(shè)備中的應(yīng)用
國(guó)產(chǎn)工控主板有什么優(yōu)勢(shì)、特點(diǎn)?
?什么是國(guó)產(chǎn)工控主板,國(guó)產(chǎn)工控主板的特點(diǎn)有哪些?
國(guó)產(chǎn)工控主板,信創(chuàng)產(chǎn)業(yè)發(fā)展新引擎
中科創(chuàng)達(dá)榮獲2024年軟件和信息技術(shù)服務(wù)優(yōu)秀企業(yè)
工控主板有哪些特點(diǎn)?
信創(chuàng)國(guó)產(chǎn)化背景下的工控主板發(fā)展現(xiàn)狀
使用工控主板時(shí)該注意哪些事項(xiàng)?

工控主板容易出現(xiàn)故障的原因有哪些?
工控主板的性能指標(biāo)有哪些?

工控主板和普通主板的區(qū)別有哪些

評(píng)論