前面我們討論了AD7705這種ADC器件的驅(qū)動開發(fā),在實際中我們使用更多的是AD719x系列的ADC芯片、包括有AD7191、AD7192和AD7193等。接下來我們就來設(shè)計并開發(fā)AD719x的驅(qū)動程序。
1 、功能概述
AD7192是一款適合高精密測量應(yīng)用的低噪聲完整模擬前端,內(nèi)置一個低噪聲、 24 位Σ-Δ型模數(shù)轉(zhuǎn)換器 (ADC)。片內(nèi)低噪聲增益級意味著可直接輸入小信號。
1.1 、硬件結(jié)構(gòu)
AD7192可配置為兩路差分輸入或四路偽差分輸入。片內(nèi)通道序列器可以使能多個通道,AD7192 按順序在各使能通道上執(zhí)行轉(zhuǎn)換,這可以簡化與器件的通信。 片內(nèi) 4.92 MHz時鐘可以用作 ADC 的時鐘源; 或者也可以使用外部時鐘或晶振。 該器件的輸出數(shù)據(jù)速率可在 4.7 Hz 至 4.8 kHz 的范圍內(nèi)變化。
AD7192提供兩種數(shù)字濾波器選項。 濾波器的選擇會影響以編程輸出數(shù)據(jù)速率工作時的均方根噪聲和無噪聲分辨率、建立時間以及 50 Hz/60 Hz 抑制。 針對要求所有轉(zhuǎn)換均需建立的應(yīng)用, AD7192 具有零延遲特性。
其功能結(jié)構(gòu)圖如下:
1.2 、內(nèi)部寄存器
AD7192內(nèi)部具有多個寄存器,對AD7192的操作就是通過這些片內(nèi)寄存器進(jìn)行控制和數(shù)據(jù)寄存器/數(shù)據(jù)寄存器加狀態(tài)信息配置。這些寄存器包括:通信寄存器、狀態(tài)寄存器、模式寄存器、配置寄存器、ID寄存器、GPOCON寄存器、失調(diào)寄存器以及滿量程寄存器。其中通信寄存器和狀態(tài)寄存器共享地址,讀操作時針對的是狀態(tài)寄存器,寫操作時針對的是通訊寄存器。對任何寄存器的操作都是從寫通訊寄存器開始。
1.2.1 、通信寄存器
通信寄存器是一個 8 位只寫寄存器。與該器件的所有通信均必須以對通信寄存器的寫操作開始。寫入通信寄存器的數(shù)據(jù)決定下一個操作是讀操作還是寫操作,以及此操作發(fā)生在哪一個寄存器。通訊寄存器的格式如下:
其中RS2、RS1、RS0這些位用于指示下一次操作的寄存器是哪一個寄存器,具體如下:
我們使用比較多的就是狀態(tài)寄存器、模式寄存器、配置寄存器以及數(shù)據(jù)寄存器。后續(xù)會進(jìn)一步了解這些寄存器。
1.2.2 、狀態(tài)寄存器
狀態(tài)寄存器是一個8位只讀寄存器。要訪問ADC狀態(tài)寄存器,用戶必須寫入通信寄存器,選擇下一個操作為讀操作,并將 0 載入位RS2、位RS1 和位RS0。狀態(tài)寄存器的格式如下:
CHD0、CHD1、CHD2這些位指示哪一通道對應(yīng)數(shù)據(jù)寄存器的內(nèi)容。這些位不是指示目前正在轉(zhuǎn)換哪一通道,而是指示產(chǎn)生數(shù)據(jù)寄存器所含轉(zhuǎn)換結(jié)果時選定了哪一通道。
1.2.3 、模式寄存器
模式寄存器是一個24位寄存器,可以從中讀取數(shù)據(jù),也可以將數(shù)據(jù)寫入其中。此寄存器用來選擇工作模式、輸出數(shù)據(jù)速率和時鐘源。模式寄存器的格式如下:
AD7192的工作模式有模式寄存器的MD2、MD1、MD0這幾位來決定。具體的配置如下:
我們配置什么樣的工作模式?jīng)Q定了后續(xù)的操作。默認(rèn)情況下為連續(xù)模式,應(yīng)用比較多的有單次模式、校準(zhǔn)模式等。
1.2.4 、配置寄存器
配置寄存器是一個 24 位寄存器,可以從中讀取數(shù)據(jù),也可以將數(shù)據(jù)寫入其中。此寄存器用來配置 ADC 的單極性或雙極性模式,使能或禁用緩沖器,使能或禁用激勵電流,選擇增益,以及選擇模擬輸入通道。
其中G2、G1、G0等位用于配置通道的增益??梢詫崿F(xiàn)1倍、8倍、16倍、32倍、64倍、128倍等增益,輸入的范圍也對應(yīng)調(diào)整,具體如下:
位CH7、CH6、CH5、CH4、CH3、CH2、CH1、CH0用于設(shè)置使用的通道。每一位對應(yīng)一個通道,具體配置方式如下:
其中CH0與CH4、CH5不可同時使用,CH1與CH6、CH7不能同時使用。CH0和CH1是差分輸入,CH4、CH5、CH6、CH7是單端輸入。
余下的ID寄存器、GPOCON寄存器、失調(diào)寄存器以及滿量程寄存器比較容易理解不再說明。
2 、驅(qū)動設(shè)計與實現(xiàn)
我們已經(jīng)了解AD7192的基本情況,接下來我們將據(jù)此來開發(fā)AD7192的驅(qū)動程序。
2.1 、對象設(shè)計
我們的驅(qū)動程序依然設(shè)計為基于對象的操作。所以首先我們需要先設(shè)計對象。而關(guān)于對象的設(shè)計過程包括兩方面內(nèi)容:對象類型的定義;對象的初始化。
2.1.1 、抽象對象類型
對于一個AD7192對象,我們首先考慮到它有8個寄存器,這些寄存器決定了它的操作特性,所以我們記錄這些寄存器的值用以標(biāo)識它的狀態(tài)。此外增益與極性雖然存在于配置寄存器中,但我們希望在初始化的時候明確的指定它,所以我們也將其作為屬性以標(biāo)識AD7192對象的配置狀態(tài)。
而對于片選信號的控制、轉(zhuǎn)換就緒信號的讀取,總線數(shù)據(jù)的輸入輸出這些依賴于硬件電路的操作,我們都將其作為對象的操作來實現(xiàn)。此外,延時操作在不同的硬件平臺、有無操作系統(tǒng)的情況下,實現(xiàn)方式大相徑庭,因此我們也將其作為對象的操作以便靈活處理。
據(jù)此我們可以抽象得AD7192對象類型為:
1 /*定義用于操作的結(jié)構(gòu)體*/
2 typedef struct Ad7192Object {
3 uint32_t polar; //通道的極性
4 uint32_t gain; //通道增益
5 uint32_t Registers[8]; //存放寄存器值的數(shù)組
6 void (*ReadWrite)(uint8_t *wData,uint8_t *rData,uint16_t size); //實現(xiàn)讀寫操作
7 void (*ChipSelect)(AD7192CSType cs); //實現(xiàn)片選
8 uint16_t (*GetReadyInput)(void); //實現(xiàn)Ready狀態(tài)監(jiān)視
9 void (*Delay)(volatile uint32_t nTime); //實現(xiàn)ms延時操作
10 }Ad7192ObjectType;
2.1.2 、初始化函數(shù)
在使用AD7192前先對其實行初始化,所以我們需要一個對象初始化函數(shù)。初始化函數(shù)主要包括三個方面的內(nèi)容:檢查對象即各種初始輸入是否有效;為對象的屬性賦初值以及為操作指定函數(shù)指針;對AD7192做前期配置。
關(guān)于AD7192的前期配置,首先是軟件復(fù)位,連續(xù)寫入40個1就可對AD7192實現(xiàn)復(fù)位。復(fù)位完成后,對零點和量程進(jìn)行校準(zhǔn)。而后獲取各寄存器的當(dāng)前狀態(tài)。初始化函數(shù)的具體實現(xiàn)代碼如下:
1 /*AD7192初始化配置*/
2 AD7192ErrorType AD7192Initialization(Ad7192ObjectType *adObj,
3 uint32_t Channels,
4 AD7192PolarType polar,
5 AD7192GainType gain,
6 AD7192ReadWriteType readWrite,
7 AD7192ChipSelectType cs,
8 AD7192GetReadyInputType ready,
9 AD7192DelaymsType delayms)
10 {
11 uint32_t polarity[]={UB_UNI,UB_BI};
12 uint32_t gains[]={GAIN_1,GAIN_8,GAIN_16,GAIN_32,GAIN_64,GAIN_128};
13
14 if((adObj==NULL)||(readWrite==NULL)||(ready==NULL)||(delayms==NULL))
15 {
16 return AD7192_InitError;
17 }
18
19 if(cs==NULL)
20 {
21 adObj->ChipSelect=AD719xChipSelect;
22 }
23 else
24 {
25 adObj->ChipSelect=cs;
26 }
27
28 adObj->polar=polarity[polar];
29 adObj->gain=gains[gain];
30
31 adObj->Registers[REG_COM_STA]=0x00;
32 adObj->Registers[REG_MODE]=0x00;
33 adObj->Registers[REG_CONF]=0x00;
34 adObj->Registers[REG_DATA]=0x00;
35 adObj->Registers[REG_ID]=0x00;
36 adObj->Registers[REG_GPOCON]=0x00;
37 adObj->Registers[REG_OFFSET]=0x00;
38 adObj->Registers[REG_FS]=0x00;
39
40 adObj->ReadWrite=readWrite;
41 adObj->GetReadyInput=ready;
42 adObj->Delay=delayms;
43
44 AD7192SoftwareReset(adObj);
45 adObj->Delay(1);
46 AD7192InternalZeroScaleCalibration(adObj,Channels);
47 adObj->Delay(1);
48 AD7192InternalFullScaleCalibration(adObj,Channels);
49
50 /*讀取并存儲全部寄存器的值*/
51 ReadAD7192Register(adObj,REG_COM_STA, 8, REG_COM_STA);
52
53 return AD7192_OK;
54 }
2.2 、對象操作
對象初始化后就可對其進(jìn)行操作。我們無論對AD7192進(jìn)行何種操作,其目的都是為了得到我們想要的數(shù)據(jù)。而從AD7192讀取轉(zhuǎn)換的結(jié)果有2種方式:單次獲取和連續(xù)獲取。接下來我們就按此來說明AD7192的驅(qū)動設(shè)計。
2.2.1 、實現(xiàn)單次數(shù)據(jù)轉(zhuǎn)換
單次轉(zhuǎn)換模式下,AD7192 在完成轉(zhuǎn)換后處于關(guān)斷模式。 將模式寄存器中的MD2、MD1和MD0分別設(shè)置為0、0、1,便可啟動單次轉(zhuǎn)換,此時AD7192將上電,執(zhí)行單次轉(zhuǎn)換,然后返回關(guān)斷模式。時序圖如下所示:
單次轉(zhuǎn)換數(shù)據(jù)獲取具體實現(xiàn)代碼如下:
1 /*單次轉(zhuǎn)換數(shù)據(jù)獲取*/
2 uint32_t GetSingleConvertionValue(Ad7192ObjectType *adObj,uint32_t Channels)
3 {
4 uint32_t dataCode=0;
5 AD7192StartSingleConvertion(adObj,Channels);
6
7 adObj->Delay(1);
8
9 dataCode = AD7192ReadConvertingData(adObj);
10 dataCode =dataCode & 0x00FFFFFF;
11
12 ReadAD7192Register(adObj,REG_DATA, 1,REG_DATA);
13
14 return dataCode;
15 }
2.2.2 、實現(xiàn)連續(xù)數(shù)據(jù)轉(zhuǎn)換
連續(xù)轉(zhuǎn)換模式是上電后的默認(rèn)轉(zhuǎn)換模式。AD7192連續(xù)轉(zhuǎn)換,每次完成轉(zhuǎn)換后,狀態(tài)寄存器中的RDY位變?yōu)榈碗娖健H绻鸆S為低電平,則完成一次轉(zhuǎn)換時,DOUT/RDY 線路也會變?yōu)榈碗娖?。若要讀取轉(zhuǎn)換結(jié)果,用戶需要寫入通信寄存器,指示下一操作為讀取數(shù)據(jù)寄存器。從數(shù)據(jù)寄存器中讀取數(shù)據(jù)字后,DOUT/RDY變?yōu)楦唠娖?。時序圖如下所示:
連續(xù)轉(zhuǎn)換數(shù)據(jù)獲取具體實現(xiàn)代碼如下:
1 /*連續(xù)轉(zhuǎn)換數(shù)據(jù)獲取,dataCodes為8個元素的數(shù)組對應(yīng)8個通道*/
2 void GettContinuousConvertionValue(Ad7192ObjectType *adObj,uint32_t Channels,uint32_t *dataCodes,int number)
3 {
4 uint32_t dataCode=0;
5 uint8_t status=255;
6 AD7192StartContinuousConvertion(adObj,Channels);
7
8 for(int i=0;i9 {
10 dataCode = AD7192ReadConvertingData(adObj);
11 status=((uint8_t)dataCode)&0x07;
12 dataCode =(dataCode>>8) & 0x00FFFFFF;
13 dataCodes[status]=dataCode;
14 }
15 }
2.2.3 、零點和量程校準(zhǔn)
零點和量程校準(zhǔn)包括內(nèi)部校準(zhǔn)和外部校準(zhǔn),我們這里使用內(nèi)部校準(zhǔn)。
1 /*內(nèi)部零點校準(zhǔn)*/
2 static void AD7192InternalZeroScaleCalibration(Ad7192ObjectType *adObj,uint32_t Channels)
3 {
4 //配置寄存器:斬波禁用,基準(zhǔn)電壓1,AI1-AI4單通道4路,禁用激勵電流,禁用基準(zhǔn)電壓檢測,禁用緩沖器
5 adObj->Registers[REG_CONF] = 0;
6 adObj->Registers[REG_CONF] = CHOP_DIS|REF_IN1|Channels|BURN_DIS|REFDET_DIS|BUF_DIS|adObj->polar|adObj->gain;
7 WriteAD7192Register(adObj,REG_CONF,1);
8
9 //模式寄存器:內(nèi)部零點校準(zhǔn),禁用狀態(tài)同傳,內(nèi)部時鐘輸出,斬波4,使能奇偶校驗,不分頻,僅用單周期轉(zhuǎn)換使能,禁用60Hz陷波,F(xiàn)S=128
10 adObj->Registers[REG_MODE] = 0;
11 adObj->Registers[REG_MODE] = MODE_INZCL|DAT_STA_DIS|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x080;
12 WriteAD7192Register(adObj,REG_MODE, 1);
13
14 adObj->ChipSelect(AD7192CS_Enable);
15 while(adObj->GetReadyInput()== 1){;} //等待RDY為0;
16 adObj->ChipSelect(AD7192CS_Disable);
17 }
18
19 /*內(nèi)部量程校準(zhǔn)*/
20 static void AD7192InternalFullScaleCalibration(Ad7192ObjectType *adObj,uint32_t Channels)
21 {
22
23 //配置寄存器:斬波禁用,基準(zhǔn)電壓1,AI1-AI4單通道4路,禁用激勵電流,禁用基準(zhǔn)電壓檢測,禁用緩沖器
24 adObj->Registers[REG_CONF] = 0;
25 adObj->Registers[REG_CONF] = CHOP_DIS|REF_IN1|Channels|BURN_DIS|REFDET_DIS|BUF_DIS|adObj->polar|adObj->gain;
26 WriteAD7192Register(adObj,REG_CONF, 1);
27
28 //模式寄存器:內(nèi)部量程校準(zhǔn),禁用狀態(tài)同傳,內(nèi)部時鐘輸出,斬波4,使能奇偶校驗,不分頻,禁用單周期轉(zhuǎn)換使能,禁用60Hz陷波,F(xiàn)S=128
29 adObj->Registers[REG_MODE] = 0;
30 adObj->Registers[REG_MODE] = MODE_INFCL|DAT_STA_DIS|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_2|SINGLECYCLE_DIS|REJ60_DIS|0x080;
31 WriteAD7192Register(adObj,REG_MODE, 1);
32
33 adObj->ChipSelect(AD7192CS_Enable);
34 while(adObj->GetReadyInput()== 1){;} //等待RDY為0;
35 adObj->ChipSelect(AD7192CS_Disable);
36 }
2.2.4 、實現(xiàn)內(nèi)部溫度轉(zhuǎn)換
AD7192內(nèi)置一個溫度傳感器。利用配置寄存器中的CH2位可以選擇溫度傳感器。如果CH2位設(shè)置為1,就會使能溫度傳感器。使用溫度傳感器并選擇雙極性模式時,如果溫度為0K,器件應(yīng)返回0x800000碼。為使傳感器發(fā)揮最佳性能,需要執(zhí)行單點校準(zhǔn)。因此,應(yīng)記錄25°C 時的轉(zhuǎn)換結(jié)果并計算靈敏度。 靈敏度約為2815碼 /°C。溫度傳感器的計算公式為 :
溫度 (K) = ( 轉(zhuǎn)換結(jié)果 – 0x800000)/2815 K
溫度 (°C) = 溫度 (K) – 273
單點校準(zhǔn)之后,內(nèi)部溫度傳感器的精度典型值為 ±2°C。具體的實現(xiàn)代碼如下:
1 /*讀取內(nèi)部溫度數(shù)據(jù),返回攝氏度溫度*/
2 float GetTemperatureValue(Ad7192ObjectType *adObj)
3 {
4 uint32_t temperatureCode=0;
5 float temp = 0.0;
6 //模式寄存器:單次轉(zhuǎn)換模式,禁用狀態(tài)同傳,內(nèi)部時鐘輸出,斬波4,使能奇偶校驗,不分頻,禁用單周期轉(zhuǎn)換使能,禁用60Hz陷波,F(xiàn)S=128
7 adObj->Registers[REG_MODE] = 0;
8 adObj->Registers[REG_MODE] = MODE_SING|DAT_STA_DIS|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x080;
9 WriteAD7192Register(adObj,REG_MODE, 1);
10 //配置寄存器:斬波禁用,基準(zhǔn)電壓1,內(nèi)部溫度,禁用激勵電流,禁用基準(zhǔn)電壓檢測,禁用緩沖器
11 adObj->Registers[REG_CONF] = 0;
12 adObj->Registers[REG_CONF] = CHOP_DIS|REF_IN1|TEMP|BURN_DIS|REFDET_DIS|BUF_DIS|UB_BI|GAIN_1;
13 WriteAD7192Register(adObj,REG_CONF, 1);
14
15 temperatureCode = AD7192ReadConvertingData(adObj);
16 temp = (temperatureCode-0x800000)/2815.0-273;
17 return temp;
18 }
3 、驅(qū)動的使用
我們已經(jīng)設(shè)計并實現(xiàn)了AD7192模數(shù)轉(zhuǎn)換器的驅(qū)動。現(xiàn)在我們將考慮如何使用這一驅(qū)動實現(xiàn)基于AD7192模數(shù)轉(zhuǎn)換器的簡單應(yīng)用。
3.1 、聲明并初始化對象
使用基于對象的操作我們需要先得到這個對象,所以我們先要使用前面定義的AD7192模數(shù)轉(zhuǎn)換器對象類型聲明一個AD7192模數(shù)轉(zhuǎn)換器對象變量,具體操作格式如下:
Ad7192ObjectType ad7192;
聲明了這個對象變量并不能立即使用,我們還需要使用驅(qū)動中定義的初始化函數(shù)對這個變量進(jìn)行初始化。這個初始化函數(shù)所需要的輸入參數(shù)如下:
Ad7192ObjectType *adObj,所要初始化的對象變量
uint32_t Channels,需要初始化的通道
AD7192PolarType polar,通道初始化的極性
AD7192GainType gain,通道的增益
AD7192ReadWriteType readWrite,讀寫操作函數(shù)
AD7192ChipSelectType cs,片選信號操作函數(shù)
AD7192GetReadyInputType ready,就緒信號檢測函數(shù)
AD7192DelaymsType delayms,毫秒延時函數(shù)
對于這些參數(shù),對象變量我們已經(jīng)定義了。所需要初始化的通道、通道的信號極性、采用的增益倍數(shù)根據(jù)實際情況選擇,通道為宏定義、極性和增益為枚舉。主要的是我們需要定義幾個函數(shù),并將函數(shù)指針作為參數(shù)。這幾個函數(shù)的類型如下:
1 *定義讀寫操作函數(shù)指針類型*/
2 typedef void (*AD7192ReadWriteType)(uint8_t *wData,uint8_t *rData,uint16_t size);
3
4 /*實現(xiàn)片選*/
5 typedef void (*AD7192ChipSelectType)(AD7192CSType cs);
6
7 /*實現(xiàn)Ready狀態(tài)監(jiān)視*/
8 typedef uint16_t (*AD7192GetReadyInputType)(void);
9
10 /*實現(xiàn)ms延時操作*/
11 typedef void (*AD7192DelaymsType)(volatile uint32_t nTime);
對于這幾個函數(shù)我們根據(jù)樣式定義就可以了,具體的操作可能與使用的硬件平臺有關(guān)系。片選操作函數(shù)用于多設(shè)備需要軟件操作時,如采用硬件片選可以傳入NULL即可。具體函數(shù)定義如下:
1 /*定義讀寫操作函數(shù)指針類型*/
2 void AD7192ReadWrite(uint8_t *wData,uint8_t *rData,uint16_t size)
3 {
4 HAL_SPI_TransmitReceive(&ad77192hspi,wData,rData,size,1000);
5 }
6
7 /*實現(xiàn)片選*/
8 void AD7192ChipSelect(AD7192CSType cs)
9 {
10 if(AD7192CS_Enable==cs)
11 {
12 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_RESET);
13 }
14 else
15 {
16 HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_SET);
17 }
18 }
19
20 /*實現(xiàn)Ready狀態(tài)監(jiān)視*/
21 uint16_t AD7192GetReadyInput(void)
22 {
23 return HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_0);
24 }
對于延時函數(shù)我們可以采用各種方法實現(xiàn)。我們采用的STM32平臺和HAL庫則可以直接使用HAL_Delay()函數(shù)。于是我們可以調(diào)用初始化函數(shù)如下:
AD7192Initialization(&ad7192,AIN1_AIN2|AIN3_AIN4,AD7192_Unipolar,AD7192Gain1,AD7192ReadWrite,AD7192ChipSelect,AD7192GetReadyInput,HAL_Delay);
3.2 、基于對象進(jìn)行操作
我們定義了對象變量并使用初始化函數(shù)給其作了初始化。接著我們就來考慮操作這一對象獲取我們想要的數(shù)據(jù)。在驅(qū)動中我們已經(jīng)封裝了單次或是連續(xù)獲取某一通道模數(shù)轉(zhuǎn)換數(shù)據(jù)的函數(shù)。接下來我們就采用我們封裝的AD7192數(shù)模轉(zhuǎn)換其的驅(qū)動獲取通道的數(shù)據(jù)。
1 /* 單次獲取兩個差分通道的值 */
2 void GetDifferentialData(void)
3 {
4 uint16_t dataCode[2];
5
6 dataCode[0]=GetSingleConvertionValue(&ad7192,AIN1_AIN2);
7
8 dataCode[1]=GetSingleConvertionValue(&ad7192,AIN3_AIN4);
9 }
因為初始化函數(shù)初始化為兩個差分通道,所以我們的函數(shù)就是獲取了兩個差分通道的轉(zhuǎn)換值。獲取了ADC的數(shù)據(jù)后就可以根據(jù)每個通道所對應(yīng)的物理量量程范圍計算得到物理量值。
4 、應(yīng)用總結(jié)
在這一篇中我們設(shè)計并實現(xiàn)了AD7192數(shù)模轉(zhuǎn)換器的驅(qū)動程序。并使用這一驅(qū)動程序?qū)崿F(xiàn)了單次獲取兩個差分通道轉(zhuǎn)換數(shù)據(jù)的簡單應(yīng)用。得到了我們想要的結(jié)果,這說明我們的驅(qū)動設(shè)計是正確的。
在使用驅(qū)動時需要注意。選擇通道時,由于可以是2個差分通道和4個單端通道,所以差分通道一不可以與AIN1、AIN2同時使用,同樣的差分通道二不能與AIN3、AIN4同時使用。
在使用驅(qū)動時需注意,采用SPI接口的器件需要考慮片選操作的問題。如果片選信號是通過硬件電路來實現(xiàn)的,我們在初始化時給其傳遞NULL值。如果是軟件操作片選則傳遞我們編寫的片選操作函數(shù)。
完整的源代碼可在GitHub下載:https://github.com/foxclever/ExPeriphDriver
評論