ad7606bstz芯片資料
由于訓(xùn)練電賽,需要選取一塊測量速度快,精度更高速度更快的外部ADC,所以選了一塊AD7606。
AD7606是一塊八通道,雙極性輸入,同步采樣16位ADC。內(nèi)置2.5V基準(zhǔn)電壓。由于AD7606沒有內(nèi)部的寄存器,需要直接利用引腳配置ADC的模式,所以AD7606的控制原理也是很簡單,但是需要占用的I/O口的資源很多。
AD7606接線圖
AD7606 SPI的串行接口接線圖:
AD7606 16位并口接線圖:
由這兩張圖可見除了必須要連接的一些控制線一樣之外不同的是數(shù)據(jù)線的連接,SPI串行通訊用的數(shù)據(jù)總線的數(shù)量只需要一根,而并行通訊的數(shù)據(jù)總線的數(shù)量為16根,對于I/O口不是非常多的單片機(jī)還是推薦使用串行通訊。(注:根據(jù)數(shù)據(jù)手冊需要把芯片的6腳SER接到高電平上,選擇芯片工作在串口模式)
AD7606SPI通訊接口說明
AD7606 必須使用單5V供電。
AD7606 和MCU之間的通信接口電平由VIO引腳控制。也就是說 VIO必須接單片機(jī)的電源,可以是3.3V也可以是5V。
OS2 OS1 OS2 : 的組合狀態(tài)選擇過采樣模式。
000表示無過采樣,最大200Ksps采樣速率。
001表示2倍過采樣, 也就是硬件內(nèi)部采集2個(gè)樣本求平均
010表示4倍過采樣, 也就是硬件內(nèi)部采集4個(gè)樣本求平均
011表示8倍過采樣, 也就是硬件內(nèi)部采集8個(gè)樣本求平均
100表示16倍過采樣, 也就是硬件內(nèi)部采集16個(gè)樣本求平均
101表示32倍過采樣, 也就是硬件內(nèi)部采集32個(gè)樣本求平均
110表示64倍過采樣, 也就是硬件內(nèi)部采集64個(gè)樣本求平均
(注:過采樣倍率越高,ADC轉(zhuǎn)換時(shí)間越長,可得到的最大采樣頻率就越低。)
CVA,CVB : 啟動AD轉(zhuǎn)換的控制信號。CVA決定1-4通道,CVB決定5-8通道??梢詫VA和CVB接到一起用同一個(gè)引腳控制。(若想控制轉(zhuǎn)換速率可以將引腳設(shè)置為PWM輸出的模式以控制轉(zhuǎn)換速率)
RAGE : 量程范圍選擇。0表示正負(fù)5V, 1表示正負(fù)10V.
RD : SPI總線時(shí)鐘信號
RST : 復(fù)位信號
BUSY : 忙信號
CS : 片選信號
FRST : 第1個(gè)通道樣本的指示信號(可不接)
VIO : 通信接口電平
DB7 : 數(shù)據(jù)總線
DB15:接地
AD7606時(shí)序圖
圖一圖二
圖三
(個(gè)人認(rèn)為只需要這三張圖就可以完全利用SPI總線將AD7606用起來)
AD7606時(shí)序圖講解
圖一是整體的一個(gè)時(shí)序框圖,大體的邏輯就是在使用AD7606之前要先復(fù)位一下,復(fù)位信號是高電平有效,時(shí)間至少為50ns。然后就是對采樣速率和量程的配置,也就是對OS0,OS1,OS2和RANGE腳的配置,然后再對一些引腳進(jìn)行一些初始化(也可以直接在GPIO配置的時(shí)候進(jìn)行初始化)。之后就是發(fā)送啟動信號,也就是將CVA,CVB拉低至少25ns后再拉高(啟動信號上升沿有效)。之后AD7606開始轉(zhuǎn)換,BUSY信號線拉高,如果BUSY信號線拉低則表明轉(zhuǎn)換已經(jīng)完成。轉(zhuǎn)換完成后將CS片選信號線拉低才可以進(jìn)行數(shù)據(jù)讀取,讀取完成后將CS片選信號線拉高即可。(還有一種是在轉(zhuǎn)換時(shí)進(jìn)行數(shù)據(jù)讀取的,由于對于采樣速率要求并不是特別的高,所以也沒有深入研究)
圖二是串行通訊對數(shù)據(jù)進(jìn)行讀取的時(shí)序框圖,講的是在AD7606轉(zhuǎn)換完成后將CS片選信號拉低后的操作。轉(zhuǎn)換完成后CS片選信號拉低,開始讀取數(shù)據(jù)。由于是16位8通道ADC,一次讀取一個(gè)字節(jié),所以一個(gè)通道需要讀取兩次數(shù)據(jù)。因?yàn)槭歉呶辉谇暗臀辉诤笏跃褪窍茸x取的是MSB,后讀取的LSB,數(shù)據(jù)需要SCLK下降沿有效。經(jīng)過16*8 = 128個(gè)SCLK讀取后已經(jīng)全部將ADC轉(zhuǎn)換的數(shù)據(jù)全部讀取完了,之后就可以將CS片選信號拉高了(由于串行通訊FRSTDATA數(shù)據(jù)線可以不接,所以并沒有用到這個(gè)腳)。
圖三是對一個(gè)字節(jié)的讀取,順序也就是現(xiàn)將時(shí)鐘線拉高后拉低然后讀取一下當(dāng)前的值然后拉高,重復(fù)八次就是一個(gè)字節(jié)的讀取。(MSB的最高位為符號位,若為1則數(shù)據(jù)為負(fù)數(shù),若為0則數(shù)據(jù)為正數(shù))
AD7606 STM32引腳配置
用的MCU是STM32F103ZET6,系統(tǒng)時(shí)鐘是72MHz。
RANGE,OS0,OS1,OS2若是需要選擇量程和速率的話可以接到單片機(jī)引腳上,要是不需要的話可以直接接到地或VCC上(自己選擇)。RST,RD,CVA, CVB,CS需要設(shè)置為OUTPUT輸出模式,GPIO電平和模式默認(rèn)就可以(我在AD7606初始化的時(shí)候?qū)O口也進(jìn)行了初始化),DB7數(shù)據(jù)線接的INPUT腳要設(shè)為INPUT模式,需要內(nèi)設(shè)上拉電阻。BUSY信號腳就設(shè)置為外部中斷,下降沿觸發(fā),一定要把中斷使能(下降沿觸發(fā)說明ADC轉(zhuǎn)換已經(jīng)結(jié)束)。
AD7606 程序模塊
程序我也是根據(jù)提供的例程進(jìn)行的修改。
我對所有需要調(diào)用的函數(shù)都進(jìn)行了宏定義,以方便在程序中調(diào)用
#define OS0_1 HAL_GPIO_WritePin(OS0_GPIO_Port,OS0_Pin,GPIO_PIN_SET);//AD速率控制引腳
#define OS0_0 HAL_GPIO_WritePin(OS0_GPIO_Port,OS0_Pin,GPIO_PIN_RESET);
#define OS1_1 HAL_GPIO_WritePin(OS1_GPIO_Port,OS1_Pin,GPIO_PIN_SET);
#define OS1_0 HAL_GPIO_WritePin(OS1_GPIO_Port,OS1_Pin,GPIO_PIN_RESET);
#define OS2_1 HAL_GPIO_WritePin(OS2_GPIO_Port,OS2_Pin,GPIO_PIN_SET);
#define OS2_0 HAL_GPIO_WritePin(OS2_GPIO_Port,OS2_Pin,GPIO_PIN_RESET);
#define RAGE_1 HAL_GPIO_WritePin(RAGE_GPIO_Port,RAGE_Pin,GPIO_PIN_SET);//量程選擇
#define RAGE_0 HAL_GPIO_WritePin(RAGE_GPIO_Port,RAGE_Pin,GPIO_PIN_RESET);//0為+-5 1為+-10
#define CVB_1 HAL_GPIO_WritePin(CVB_GPIO_Port,CVB_Pin,GPIO_PIN_SET);
#define CVB_0 HAL_GPIO_WritePin(CVB_GPIO_Port,CVB_Pin,GPIO_PIN_RESET);
#define CVA_1 HAL_GPIO_WritePin(CVA_GPIO_Port,CVA_Pin,GPIO_PIN_SET);//啟動AD轉(zhuǎn)換的控制信號
#define CVA_0 HAL_GPIO_WritePin(CVA_GPIO_Port,CVA_Pin,GPIO_PIN_RESET);//CVA決定1-4通道 CVB決定5-8通道
#define RD_1 HAL_GPIO_WritePin(RD_GPIO_Port,RD_Pin,GPIO_PIN_SET);//時(shí)鐘線
#define RD_0 HAL_GPIO_WritePin(RD_GPIO_Port,RD_Pin,GPIO_PIN_RESET);
#define RST_1 HAL_GPIO_WritePin(RST_GPIO_Port,RST_Pin,GPIO_PIN_SET);//復(fù)位信號
#define RST_0 HAL_GPIO_WritePin(RST_GPIO_Port,RST_Pin,GPIO_PIN_RESET);
#define CS_1 HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_SET);//片選信號
#define CS_0 HAL_GPIO_WritePin(CS_GPIO_Port,CS_Pin,GPIO_PIN_RESET);
#define More_Rst RST_1;RST_1;RST_1;RST_1;RST_1;RST_1;//持續(xù)最少25ns高電平復(fù)位信號
#define Read_Dat HAL_GPIO_ReadPin(INPUT_GPIO_Port,INPUT_Pin)//讀取數(shù)據(jù)引腳狀態(tài)
對速度進(jìn)行選擇的函數(shù)
void AD7606_SetSpeed(uint8_t mode)//AD7606過采樣選擇
{
switch(mode)
{
case 0: OS0_0 OS1_0 OS2_0;
case 2: OS0_0 OS1_0 OS2_1;
case 4: OS0_0 OS1_1 OS2_0;
case 8: OS0_0 OS1_1 OS2_1;
case 16: OS0_1 OS1_0 OS2_0;
case 32: OS0_1 OS1_0 OS2_1;
case 64: OS0_1 OS1_1 OS2_0;
default: OS0_0 OS1_0 OS2_0;
}
}
量程進(jìn)行選擇的函數(shù)
void AD7606_SetRange(uint8_t range)//設(shè)置量程
{
if(range == 1)
{
RAGE_1;
}
else RAGE_0;
}
復(fù)位信號函數(shù)
void AD7606_Reset()//AD7606復(fù)位
{
RST_0;
More_Rst;
RST_0;
}
1
2
3
4
5
6
初始化函數(shù)
void AD7606_Init()//AD7606初始化
{
AD7606_SetRange(0);
AD7606_Speed_Set(0);
AD7606_Reset();
CVA_1;
CVB_1;
CS_1;
AD7606_ReadData();
}
起始信號函數(shù)
void AD7606_Init()//AD7606初始化
{
AD7606_SetRange(0);//設(shè)置采樣量程
AD7606_SetSpeed(0);//設(shè)置采樣速度
AD7606_Reset();
CVA_1;
CVB_1;
CS_1;
AD7606_ReadData();
}
讀單個(gè)字節(jié)函數(shù)
uint8_t AD7606_ReadByte(void)//讀一個(gè)字節(jié)
{
uint8_t usData = 0;
uint8_t i;
for (i = 0; i < 8; i++)
{
RD_0;
AD7606_Delay();
usData = usData << 1;
if(Read_Dat)
{
usData++;
}
RD_1;
AD7606_Delay();
}
return usData;
}
讀八個(gè)通道數(shù)據(jù)函數(shù)(BUSY拉低后進(jìn)中斷,進(jìn)中斷后就開始讀取數(shù)據(jù))
void AD7606_ReadData()//讀八個(gè)通道的數(shù)據(jù)
{
CS_0;
for (uint8_t i = 0; i < 8; i++)
{
adc_now[i] = AD7606_ReadByte();
adc_now[i] <<= 8;
adc_now[i] = adc_now[i] | AD7606_ReadByte();
}
CS_1;
AD7606_Start();//讀取數(shù)據(jù)結(jié)束后立馬開始下一次轉(zhuǎn)換
}
量程轉(zhuǎn)換和數(shù)據(jù)處理函數(shù)
for(uint8_t i=0;i<8;i++)
{
if(adc_now[i] >> 15 == 1)//判斷最高位是否為1
{
fushu_flag = 1;//負(fù)數(shù)標(biāo)志位置1
}
adc_now[i] &= 0x7fff;//將最高位屏蔽掉
s_volt[i] = (adc_now[i] * 5.0) / 32767;//5V量程 將數(shù)據(jù)轉(zhuǎn)換為電壓
if(fushu_flag == 1)//對正負(fù)數(shù)進(jìn)行判斷
{
fushu_flag = 0;
s_volt[i] = -s_volt[i];
}
}
遇到的問題以及總結(jié)
在調(diào)試過程中我發(fā)現(xiàn)和AGND連接在一起的腳一直都在0XFFFC到0X0001之間浮動,轉(zhuǎn)換成十進(jìn)制數(shù)也就是在0的上下浮動,所以我剛開始一直以為是錯(cuò)誤的,所以就一直在對著一個(gè)正確的程序找錯(cuò)誤,直到后來我接往引腳上接了一個(gè)3.3V的電壓,它返回回來的數(shù)據(jù)不再是這個(gè)范圍內(nèi)的值,并經(jīng)過換算是一個(gè)正確的電壓值。后來才知道這個(gè)浮動是正常的,是AGND和采樣時(shí)有的一點(diǎn)干擾使他有一些小范圍的浮動,對于ADC來說這些都是正常的。
在測量過程中,由于AD7606的模擬電壓參考點(diǎn)是2.5V,所以我輸入3.3V的電壓經(jīng)過換算后得到的電壓值為0.8V,所以這個(gè)需要雙極性輸入測電壓,也就是一個(gè)通道接地,另一個(gè)通道測待測點(diǎn)電壓,之后待測點(diǎn)電壓就是被測電壓值與地的被測電壓值之間的差值,也稱偽差分輸入,雙極性輸入。