一些時候我們需要在系統使用過程中改變某些電路電阻值以達到改變設定的目的,這時候我們就會使用電位器。在我們使用數字控制電路時多選擇數字電位器。在這一篇我們就來設計AD8400系列數字電位器的驅動。
1、功能概述
AD8400/AD8402/AD8403分別是單通道/雙通道/四通道、256位、數字控制可變電阻(VR)器件,可實現與機械電位計或可變電阻相同的電子調整功能。AD8400內置一個可變電阻,采用緊湊的SOIC-8封裝。AD8402內置兩個獨立的可變電阻,采用節省空間的SOIC-14表面貼裝封裝。AD8403內置四個獨立的可變電阻,提供24引腳PDIP、SOIC和TSSOP三種封裝。各器件均內置一個帶游標觸點的固定電阻,該游標觸點在載入控制串行輸入寄存器的數字碼所確定的數字碼分接該固定電阻值。游標與固定電阻任一端點之間的電阻值,隨傳輸至VR鎖存器中的數字碼呈線性變化。在A端與游標或B端與游標之間,各可變電阻提供一個完全可編程電阻值。A至B固定端接電阻(1 kΩ、10 kΩ、50 kΩ或100 kΩ)的通道間匹配容差為±1%,標稱溫度系數為500 ppm/°C。借助獨特的開關電路,可將傳統開關電阻設計中固有的高脈沖干擾降至最低,從而避免任何先合后開或先開后合操作。

每個VR均有各自的VR鎖存器,用來保存其編程電阻值。這些VR鎖存器由一個SPI兼容型串行至並行移位寄存器更新,該移位寄存器從一個標准三線式串行輸入數字接口加載數據。由10個數據位構成的數據字傳輸至串行輸入寄存器。

該數據字經過解碼,前2位確定需要載入的VR鎖存器地址,后8位是數據。利用串行寄存器相對端的串行數據輸出引腳,就可以簡單的菊花鏈形式將多個VR連接,而無需額外的外部解碼邏輯。
復位(RS)引腳通過將80H載入VR鎖存器來迫使游標移到中間電平。SHDN引腳則迫使A端的電阻變為端到端開路狀態,並使游標與B端短路,從而實現毫瓦級功耗的關斷狀態。當SHDN回到邏輯高電平時,先前的鎖存器設置將使游標處於關斷前的電阻值設置。數字接口在關斷期間仍有效,以便更改代碼,當器件脫離關斷狀態時,游標將處於新的位置。
2、驅動設計與實現
我們已經了解了AD840x系列數字電位器的基本情況,接下來我們將基於此實現AD840x系列數字電位器的驅動。
2.1、對象定義
我們的的驅動設計都是基於對象的操作,所以我們先要抽象出AD840x系列數字電位器的對象類型。這是一個系列對象所以有不同的類型,每種類型又有不同的標稱電阻值。這些都可以區別不同的對象,我們將其抽象為AD840x對象的屬性。而對於操作則相對簡單,我們只需要向AD840x對象寫數據,所以將寫數據作為它的操作。具體定義如下:
1 /* 定義AD840x類型枚舉 */ 2 typedef enum AD840x{ 3 AD8400, 4 AD8402, 5 AD8403 6 }AD840xType; 7 8 /* 定義AD840x通道選擇枚舉 */ 9 typedef enum AD840xLdac{ 10 AD840x_VR1=0x00, 11 AD840x_VR2=0x01, 12 AD840x_VR3=0x02, 13 AD840x_VR4=0x03 14 }AD840xLdacType; 15 16 /* 定義AD840x標稱電阻枚舉 */ 17 typedef enum AD840xNR{ 18 AD840x_NR1k, //標稱電阻為1K 19 AD840x_NR10k, //標稱電阻為10K 20 AD840x_NR50k, //標稱電阻為50K 21 AD840x_NR100k //標稱電阻為100K 22 }AD840xNRType; 23 24 /* 定義AD840x對象類型 */ 25 typedef struct AD840xObject{ 26 AD840xType type; //AD840x對象類型 27 float nominalValue; //標稱電阻值 28 void (*Write)(uint8_t rdac); //寫數據操作函數指針 29 }AD840xObjectType;
有操作對象后,還需要對該對象變量作初始化才可使用,所以我們還需要定義一個初始化函數用於對象的初始化。AD840x對象的初始化函數如下:
1 /* 初始化AD840x對象 */ 2 void AD840xInitialization(AD840xObjectType *vr,AD840xType type,AD840xWriteByte write,AD840xNRType nr) 3 { 4 float nValue[4]={1000,10000,50000,100000}; 5 6 if((vr==NULL)||(write==NULL)) 7 { 8 return; 9 } 10 11 vr->type=type; 12 13 vr->Write=write; 14 15 vr->nominalValue=nValue[nr]; 16 }
2.2、對象操作
AD8400/AD8402/AD8403分別是單通道/雙通道/四通道、256位、數字控制可變電阻(VR)器件。更改VR編程設置是通過將10位串行數據字送入SDI引腳來實現。此數據字由2個地址位(MSB優先)和8個數據位(也是MSB優先)組成。串行寄存器數據字格式如下:

AD840x的地址分配,由ADDR解碼器解碼,確定接收位B7至B0中的串行寄存器數據的VR鎖存器的位置。位置的計算公式如下:
VR#=A1*2+A0+1
單通道AD8400要求A1 = A0 = 0。雙通道AD8402要求A1 = 0。A1、A0的取值方式如下:

關於AD840x對象設置游標的位置與電阻的關系:


根據上述兩個公式,當我們需要某一阻值的電阻時,只需要設置響應的D值就看可以了。具體的操作函數如下:
1 /*設置AD8400游標的位置*/ 2 void SetAD8400ResistorValue(AD840xObjectType *vr,uint16_t resistorValue,AD840xLdacType ldac) 3 { 4 float mValue=0.0; 5 uint16_t sendValue=0; 6 uint8_t txData[2]; 7 8 if((resistorValue<50)||(resistorValue>vr->nominalValue)) 9 { 10 return; 11 } 12 13 if((vr->type==AD8400)&&(ldac!=AD840x_VR1)) 14 { 15 return; 16 } 17 18 if((vr->type==AD8402)&&(ldac>AD840x_VR2)) 19 { 20 return; 21 } 22 23 mValue=((float)resistorValue-(float)RESISTANCEINITIAL)/(float)vr->nominalValue; 24 sendValue=(uint8_t)(mValue*RESISTANCEINDEX); 25 26 sendValue=sendValue||(ldac<<8); 27 28 txData[0]=(sendValue>>2); 29 txData[1]=(sendValue<<6); 30 vr->Write(txData[0]); 31 vr->Write(txData[1]); 32 }
第三個參數通道選擇,如前面所述由A1、A0決定。對於AD8400是單通道,直接指定第一通道即可。而AD8402對應第一、第二通道。
3、驅動的使用
我們實現了AD840x系列數字電位器的驅動,接下來我們需要來討論一下它的應用,及如何使用我們開發的驅動實現我們的應用。
3.1、聲明並初始化對象
首先我們依然是需要聲明AD840x對象變量。我們在驅動設計時已經定義了AD840xObjectType對象類型,所以我們就是用這個對象類型聲明AD840x對象變量。具體操作如下:
AD840xObjectType ad840x;
對於定義的這一對象變量尚不能直接使用,必須先對其初始化。我們在驅動中也設計了初始化函數:void AD840xInitialization(AD840xObjectType *vr,AD840xType type,AD840xWriteByte write,AD840xNRType nr)。它的四個參數分別是:AD840x對象指針、AD840x的類型、寫AD840x對象函數指針、AD840x的標稱電阻值。
AD840x對象指針指向的就是我們所要初始化的對象變量。AD840x的類型就是源自AD840xType枚舉。AD840x的標稱電阻值則源自AD840xNRType枚舉。關於寫AD840x對象函數指針則是與具體硬件平台和接口相關的數據發送函數。在這里就是指SPI對口的數據發送函數。具體類型如下:
typedef void (*AD840xWriteByte)(uint8_t rdac);
如我們可聲明為:void WriteAD8400bySPI(uint8_t rdac);
有了這些參數我們就可以使用初始化函數來初始化我們前面聲明的對象變量了。具體形式如下:
AD840xInitialization(&ad840x, AD8400, WriteAD8400bySPI, AD840x_NR10k);
我們就將對象變量ad840x初始化為AD8400類型的標稱電阻為10K的可變電阻對象,且向對象寫數據的函數為WriteAD8400bySPI。
3.2、基於對象進行操作
我們聲明並初始化完成對象變量后。就可以調用操作函數來實現我們想要對AD840x對象進行的操作了。使用電阻設置函數即可:
void SetAD8400ResistorValue(AD840xObjectType *vr,uint16_t resistorValue,AD840xLdacType ldac)
其3個參數,第一個是我們要操作的對象的指針;第二個是我們想要設置的電阻值;第三個參數是通道選擇。
4、應用總結
我們已經實現了AD840x的驅動及應用。AD840x的應用並不復雜,我們只需要設定我們想要的電阻就可以了。在我們的應用中得到的結果與我們預期的完全一致。
在使用驅動時我們應該注意。AD8402與AD8403均為多通道的可變電阻。在使用時需要注意通道選擇。通道選擇由下發數據的A1、A0位決定。驅動中已定義為枚舉,選擇即可。
源碼發布到Github:https://github.com/foxclever/ExPeriphDriver
歡迎關注:

