外設驅動庫開發筆記7:LTC2400系列ADC驅動

有些時候我們需要對高精度的ADC來處理一些要求較高的模擬量採集。在處理溫控器的過程中我們就使用到了LTC2400這款ADC。接下來我們就來設計並實現LTC2400的驅動。

1、功能概述

LTC2400是一個供電電壓2.7V5.5V的微功率24位轉換器,集成了振盪器、4ppm INL0.3ppm RMS噪聲。所需外接基準電壓源的電壓範圍爲0.1VVCC;模擬信號輸入VIN的輸入電壓範圍爲-0.125VREF1.125VREF

1.1、硬件結構

LTC2400模數轉換器採用與SPI接口兼容的3線數字接口,可應用於高分辨率和低頻應用場合,如稱重、溫度測量、氣體分析、應變儀,數據採集,工業控制等方面。它採用8SO-8封裝,其引腳排列如圖所示。

LTC2400內部已集成了高精度的振盪器,因此採用片內振盪器時不需要外接任何元件。通過一個引腳,LTC2400可以配置爲在50Hz60Hz±2%時優於110dB的抑制,也可以由外部振盪器驅動,用戶定義的抑制頻率在1Hz120Hz之間。當芯片的F0腳接VCC時,使用內部振盪器可對輸入信號中的50Hz干擾進行大於110dB的抑制,其AD轉換時間爲160ms;F0腳接GND時,使用內部振盪器可對輸入信號中的60Hz干擾進行大於110dB的抑制,AD轉換時間爲133ms;F0腳接外部振盪器fEOSC時,其抑制的頻率爲fEOSC/2560AD轉換時間爲2048/fEOSC

LTC2400轉換器接受任何外部參考電壓從0.1VVCCLTC2400以其擴展的輸入轉換範圍-12.5% VREF112.5% VREF,平穩地解決了先前傳感器或信號調理電路的偏移和超量程問題。

1.2、通訊接口

通過對CSSCK的控制,LTC2400可以提供幾種靈活的接口模式(內部或外部的SCK模式)。不同轉換模式的選擇無需對LTC2400的寄存器進行設置,並且不影響數據轉換週期。使用時鐘信號SCK(PIN7)控制轉換數據的輸出時,轉換結果將在時鐘CLK的下降沿由SDO腳輸出。在內部時鐘模式,SCK信號由LTC2400產生輸出在外部SCK模式,SCKLTC2400外部輸入的時鐘信號。下面詳細介紹外部串行時鐘的三線接口方法。

LTC2400上電時,如果SCK爲低電平,轉換進入外部串行模式;CS信號的下降沿,SCK信號必須爲低電平。

CS爲高電平時,SDO爲高阻態,此時,SDO連接的接口線可以作爲其它應用。如果LTC2400在轉換和睡眠時CS爲低電平,那麼,SDO的輸出狀態將用於指示EOC。在AD轉換階段,SDO的輸出狀態EOC將變爲高電平,而一旦轉換完成,EOC又變爲低電平。在LTC2400處於睡眠狀態時,如果CS爲低電平,系統會在SCK的上升沿將其喚醒。LTC2400的外部串行時鐘接口時序圖如下:

CS信號除用來檢測LTC2400的狀態和輸出AD轉換數據外,還可用來控制全部串行數據輸出之前進行的新一次AD轉換。在LTC2400處於數據輸出狀態時,CS由低變高以停止串行輸出,同時開始新的AD轉換。

由於在CS爲高電平時,數據輸出端SDO爲高阻態,因此,在LTC2400的轉換過程中,可通過將CS變爲低電平來檢測轉換狀態。當CS爲低電平時,SDO腳輸出的EOC信號爲1,表示轉換正在進行;EOC0表示轉換完成,系統處於睡眠狀態。當LTC2400處於睡眠狀態時,其轉換結果將保存在內部移位寄存器中。CS爲低可在SCK的上升沿喚醒LTC2400,此時轉換數據將在SCK的下降沿串行輸出。EOC通常在SCK的第一個上升沿被鎖存,直到第32個上升沿鎖存結束,同時,系統將在第32個下降沿開始的新一輪轉換。

一般情況下,在數據輸出過程中,如果CS爲低電平,那麼,系統將在SCK的第一個上升沿和第32個下降沿中間將CS變高以停止數據輸出。

1.3、工作過程

LTC2400是一種低功耗、採用Δ-Σ技術且具有3線串行接口的AD轉換器,而且在AD轉換完成後將直接進入睡眠狀態。LTC2400的三線接口線分別是數據輸出(SDO)、時鐘(SCK)和片選(CS)。其工作流程如圖所示:

LTC2400完成轉換就進入睡眠狀態。睡眠狀態的供電電流僅爲20μA。若CS一直爲高電平,芯片將保持睡眠狀態。進入睡眠狀態時,數據最後的轉換結果將保存在芯片內部的靜態移位寄存器中。

CS變爲低電平時,LTC2400開始輸出轉換結果,此時數據轉換沒有等待時間,輸出數據即爲剛進行的轉換結果。該轉換結果是在串行時鐘SCK的控制下由SDO輸出的,並在SCK的下降沿更新,而在SCK的上升沿可靠讀取。當32位數據從LTC2400讀出或當CS被拉高時,數據輸出結束。此後LTC2400將自動開始新的數據轉換和重複週期。

2、驅動設計與實現

我們已經瞭解了LTC2400模數轉換器的基本情況,接下來我們將設計並實現LTC2400模數轉換器的驅動程序。

2.1、對象定義

首先我們需要抽象出LTC2400模數轉換器的對象類型。作爲一個對象最起碼包括量方面的內容:屬性和操作。關於LTC2400模數轉換器的屬性我們簡單分析一下。LTC2400模數轉換器是一個主動發送數據的器件,並沒有需要配置的地方,僅有一個時鐘通過外部引腳設置,所以爲了應用更清楚我們將其時鐘引腳的配置作爲其屬性記錄下來。另一個其返回的數據帶有狀態標識,我們將其作爲另一個屬性以記錄當前的狀態。

至於操作也很簡單,首先我們要從LTC2400接收數據,而這個與具體的平臺聯繫緊密,所以我們將從LTC2400接收數據作爲對象的一個操作。LTC2400模數轉換器採用SPI通訊接口,有時需要在軟件中對片選信號進行操作,所以我們將片選型號的操作作爲對象的另一個操作。在一些情況下,有些針對對象的活動需要延時進行,而在不同的平臺中採取的延時方式不盡相同,爲了操作方便我們將延時操作作爲對象的一個操作。於是我們可抽象的LTC2400的對象類型如下:

/* 定義LTC2400對象類型 */
typedef struct Ltc2400Object {
       LTC2400ClockType clock;                     //使用的時鐘
       uint32_t dataCode;                          //數據編碼
       void (*Receive)(uint8_t *rData);            //接收數據
       void (*ChipSelect)(LTC2400CSType cs);       //實現片選
       void (*Delayms)(volatile uint32_t nTime);   //實現ms延時操作
}Ltc2400ObjectType;

定義了LTC2400模數轉換器的對象類型,我們還需要設計對象的初始化函數,因爲對象必須初始化後才能使用。初始化函數至少包含有2方面內容:一是爲對象變量賦必要的初值;二是檢查這些初值是否是有效的。特別是一些操作指針錯誤的話可能產生嚴重的後果。基於這一原則,我們設計LTC2400模數轉換器的對象初始化函數如下:

/* LTC2400對象初始化函數 */
void LTC2400Initialization(Ltc2400ObjectType *ltc,
                           LTC2400ClockType clock,
                           LTC2400Receive receive,
                           LTC2400ChipSelect cs,
                           LTC2400Delay msDelay)
{
       if((ltc==NULL)||(receive==NULL)||(msDelay==NULL))
       {
              return;
       }
      
       ltc->dataCode=0;
       ltc->clock=clock;
      
       if(cs==NULL)     //硬件電路實現片選
       {
              ltc->ChipSelect=DefaultChipSelect;
       }
       else
       {
              ltc->ChipSelect=cs;
       }
      
       ltc->Receive=receive;
       ltc->Delayms=msDelay;
}

至此關於LTC2400模數轉換器的對象定義纔算完成。在使用初始化函數時,需要注意片選操作函數,如果是採用硬件電路選中則可使用NULL作爲參數。

2.2、對象操作

我們獲取對象的目的就是希望通過對象來得到我們想要的數據。對於LTC2400模數轉器來說,就是從其接收ADC轉換數據。所以我們封裝LTC2400的操作函數如下:

/* 獲取LTC2400轉換數據,返回量程數據的比例值 */
float GetLtc2400Data(Ltc2400ObjectType *ltc)
{
       uint8_t rData[4];
      
       ltc->ChipSelect(LTC2400CS_Enable);
       ltc->Delayms(1);
      
       ltc->Receive(rData);
      
       ltc->Delayms(1);
       ltc->ChipSelect(LTC2400CS_Disable);
      
       return CompoundLTC2400Data(ltc,rData);
}

函數的返回值是轉換結果的比例值,是一個浮點數,使用這一返回結果結合具體浮點數的量成範圍就可以得到物理量值。

3、驅動的使用

我們已經開發了LTC2400模數轉換器的驅動程序,接下來我們用一個簡單的實例驗證這一驅動。

3.1、聲明並初始化對象

使用基於對象的操作我們需要先得到這個對象,所以我們先要使用前面定義的LTC2400模數轉換器對象類型聲明一個LTC2400模數轉換器對象變量,具體操作格式如下:

Ltc2400ObjectType ltc2400;

聲明瞭這個對象變量並不能立即使用,我們還需要使用驅動中定義的初始化函數對這個變量進行初始化。這個初始化函數所需要的輸入參數如下:

Ltc2400ObjectType *ltc,所要初始化的對象

LTC2400ClockType clock,採用時鐘方式

LTC2400Receive receive,接收數據函數指針

LTC2400ChipSelect cs,片選操作函數指針

LTC2400Delay msDelay,延時函數指針

對於這些參數,對象變量我們已經定義了。所使用的時鐘方式爲枚舉,根據實際情況選擇就好了。主要的是我們需要定義幾個函數,並將函數指針作爲參數。這幾個函數的類型如下:

/*定義接收數據函數指針類型*/
typedef void (*LTC2400Receive)(uint8_t *rData);
/*定義片選信號函數指針類型*/
typedef void (*LTC2400ChipSelect)(LTC2400CSType cs);
/*定義延時操作函數指針類型*/
typedef void (*LTC2400Delay)(volatile uint32_t nTime);

對於這幾個函數我們根據樣式定義就可以了,具體的操作可能與使用的硬件平臺有關係。片選操作函數用於多設備需要軟件操作時,如採用硬件片選可以傳入NULL即可。具體函數定義如下:

/*定義讀寫操作函數指針類型*/
void LTC2400Recieve(uint8_t *rData)
{
       HAL_SPI_Receive(&ltc2400hspi,rData,4,1000);
}

/*實現片選*/
void LTC2400ChipSelected(LTC2400CSType cs)
{
       if(LTC2400CS_Enable==cs)
       {
              HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_RESET);
       }
       else
       {
              HAL_GPIO_WritePin(GPIOF, GPIO_PIN_4, GPIO_PIN_SET);
       }
}

對於延時函數我們可以採用各種方法實現。我們採用的STM32平臺和HAL庫則可以直接使用HAL_Delay()函數。於是我們可以調用初始化函數如下:

LTC2400Initialization(&ltc2400INTERNAL_CLOCK50HzLTC2400RecieveLTC2400ChipSelectedHAL_Delay);

這裏我們將其初始化爲使用改了內部時鐘,採用軟件控制片選信號。

3.2、基於對象進行操作

我們定義了對象變量並使用初始化函數給其作了初始化。接着我們就來考慮操作這一對象獲取我們想要的數據。我們在驅動中已經將獲取數據並轉換爲轉換值的比例值,接下來我們使用這一驅動開發我們的應用實例。

/* 獲取LTC2400測量的物理量值 */
void GetLTC2400Value(void)
{
       float ratio;
       float phyValue;
       float range=100.0;
       float zero=0.0;
      
       ratio=GetLtc2400Data(&ltc2400);
      
       phyValue=(range-zero)*ratio+zero;
}

在這一例中,我們計算了一個量程範圍爲0100的物理量的值,如果檢測的物理量不同,我們根據實際修改即可。

4、應用總結

這一篇中,我們設計並實現了LTC2400模數轉換器的驅動程序,並使用這一驅動開發了獲取一個量程範圍爲0100的溫度信號的簡單應用,得到的結果與我們預期一致,因此我們的驅動符合要求。

在使用驅動時需注意,採用SPI接口的器件需要考慮片選操作的問題。如果片選信號是通過硬件電路來實現的,我們在初始化時給其傳遞NULL值。如果是軟件操作片選則傳遞我們編寫的片選操作函數。

完整的源代碼可在GitHub下載:https://github.com/foxclever/ExPeriphDriver

歡迎關注:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章