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