美國國家半導(dǎo)體公司生產(chǎn)的ADC0832是廣泛應(yīng)用的8 位分辨率、雙通道A/D轉(zhuǎn)換芯片。ADC0832是雙通道輸入,并且可以軟件配置成單端或差分輸入,其串行輸出可以方便的和標(biāo)準(zhǔn)的移位寄存器及微處理器接口。 由于它體積小,兼容性,性價比高而深受單片機(jī)愛好者及企業(yè)歡迎,其目前已經(jīng)有很高的普及率。
ADC0832的工作原理
正常情況下ADC0832 與單片機(jī)的接口應(yīng)為4條數(shù)據(jù)線,分別是CS、CLK、DO、DI。但由于DO端與DI端在通信時并未同時使用并與單片機(jī)的接口是雙向的,所以在I/O口資源緊張時可以將DO和DI并聯(lián)在一根數(shù)據(jù)線上使用。當(dāng)ADC0832未工作時其CS輸入端應(yīng)為高電平,此時芯片禁用,CLK 和DO/DI 的電平可任意。當(dāng)要進(jìn)行A/D轉(zhuǎn)換時,須先將CS使能端置于低電平并且保持低電平直到轉(zhuǎn)換完全結(jié)束。此時芯片開始轉(zhuǎn)換工作,同時由處理器向芯片時鐘(CLK)輸入端輸入時鐘脈沖,DO/DI端則使用DI端輸入通道功能選擇的數(shù)據(jù)信號。在第一個時鐘脈沖的下沉之前DI端必須是高電平,表示啟始信號。在第二、三個脈沖下沉之前DI端應(yīng)輸入兩位數(shù)據(jù)用于選擇通道功能。
表1:通道地址設(shè)置表
如表1所示,當(dāng)此兩位數(shù)據(jù)為“1”、“0”時,只對CH0 進(jìn)行單通道轉(zhuǎn)換。當(dāng)2位數(shù)據(jù)為“1”、“1”時,只對CH1進(jìn)行單通道轉(zhuǎn)換。當(dāng)兩位數(shù)據(jù)為“0”、“0”時,將CH0作為正輸入端IN+,CH1作為負(fù)輸入端IN-進(jìn)行輸入。當(dāng)兩位數(shù)據(jù)為“0”、“1”時,將CH0作為負(fù)輸入端IN-,CH1 作為正輸入端IN+進(jìn)行輸入。到第三個脈沖的下降之后DI端的輸入電平就失去輸入作用,此后DO/DI端則開始利用數(shù)據(jù)輸出DO進(jìn)行轉(zhuǎn)換數(shù)據(jù)的讀取。從第4個脈沖下降沿開始由DO端輸出轉(zhuǎn)換數(shù)據(jù)最高位Data7,隨后每一個脈沖的下降沿DO端輸出下一位數(shù)據(jù)。直到第11個脈沖時發(fā)出最低位數(shù)據(jù)Data0,一個字節(jié)的數(shù)據(jù)輸出完成。也正是從此位開始輸出下一個相反字節(jié)的數(shù)據(jù),即從第11個字節(jié)的下降沿輸出Data0。隨后輸出8位數(shù)據(jù),到第19 個脈沖時數(shù)據(jù)輸出完成,也標(biāo)志著一次A/D轉(zhuǎn)換的結(jié)束。最后將CS置高電平禁用芯片,直接將轉(zhuǎn)換后的數(shù)據(jù)進(jìn)行處理就可以了。時序說明請參照圖1。
作為單通道模擬信號輸入時ADC0832的輸入電壓是0—5V且8位分辨率時的電壓精度為19.53mV,即(5/256)V。如果作為由IN+與IN-輸入的輸入時,可是將電壓值設(shè)定在某一個較大范圍之內(nèi),從而提高轉(zhuǎn)換的寬度。但值得注意的是,在進(jìn)行IN+與IN-的輸入時,如果IN-的電壓大于IN+的電壓則轉(zhuǎn)換后的數(shù)據(jù)結(jié)果始終為00H。
圖1 ADC0832工作時序
ADC0832的引腳圖及功能
ADC0832的特點是
· 輸入輸出電平與TTL/CMOS相兼容;
· 工作頻率為250KHZ,轉(zhuǎn)換時間為32μS;
· 一般功耗僅為15mW;
· 8P、14P—DIP(雙列直插)、PICC 多種封裝;
· 商用級芯片溫寬為0°C to +70°C,工業(yè)級芯片溫寬為?40°C to +85°C;
芯片接口說明:
· CS_ 片選使能,低電平芯片使能。
· CH0 模擬輸入通道0,或作為IN+/-使用。
· CH1 模擬輸入通道1,或作為IN+/-使用。
· GND 芯片參考0 電位(地)。
· DI 數(shù)據(jù)信號輸入,選擇通道控制。
· DO 數(shù)據(jù)信號輸出,轉(zhuǎn)換 數(shù)據(jù)輸出。
· CLK 芯片時鐘輸入。
· Vcc/REF 電源輸入及參考電壓輸入(復(fù)用)。
圖3 ADC0832引腳圖
ADC0832 為8 位分辨率A/D轉(zhuǎn)換芯片,其最高分辨可達(dá)256級,可以適應(yīng)一般的模擬量轉(zhuǎn)換要求。其內(nèi)部電源輸入與參考電壓的復(fù)用,使得芯片的模擬電壓輸入在0~5V之間。芯片轉(zhuǎn)換時間僅為32μS,據(jù)有雙 數(shù)據(jù)輸出可作為數(shù)據(jù)校驗,以減少數(shù)據(jù)誤差,轉(zhuǎn)換速度快且穩(wěn)定性能強(qiáng)。獨立的芯片使能輸入,使多器件掛接和處理器控制變的更加方便。通過DI 數(shù)據(jù)輸入端,可以輕易的實現(xiàn)通道功能的選擇。
adc0832內(nèi)部結(jié)構(gòu)及應(yīng)用電路
adc0832內(nèi)部結(jié)構(gòu)圖
以下是基于stc89c51和ADC0832的函數(shù)信號發(fā)生器
仿真電路及調(diào)試圖
頭文件
adc0832.h
#ifndef __ADC0832_H__
#define __ADC0832_H__
#define DAdata P1//DA數(shù)據(jù)端口
uchar wavecount; //‘抽點’計數(shù)
uchar THtemp,TLtemp;//傳遞頻率的中間變量
uchar judge=1; //在方波輸出函數(shù)中用于簡單判別作用
uchar waveform; //當(dāng)其為0、1、2時,分別代表三種波
uchar code freq_unit[3]={5,25,100}; //三種波的頻率單位
uchar idata wavefreq[3]={1,1,1}; //給每種波定義一個數(shù)組單元,用于存放單位頻率的個數(shù)
sbit DA_S1= P2^7; // 控制DAC0832的8位輸入寄存器,僅當(dāng)都為0時,可以輸出數(shù)據(jù)(處于直通狀態(tài)),否則,輸出將被鎖存
void triangle_out()//三角波輸出
{
DAdata=triangle_tab[wavecount++];
if(wavecount》64) wavecount=0;
DA_S1=0; //打開8位輸入寄存器
DA_S1=1; //關(guān)閉8位輸入寄存器
}
void sine_out() //正弦波輸出
{
DAdata=sine_tab[wavecount++];
DA_S1=0; //打開8位輸入寄存器
DA_S1=1; //關(guān)閉8位輸入寄存器
}
void square_out() //方波輸出
{
judge=~judge;
if(judge==1) DAdata=0xff;
else DAdata=0x00;
DA_S1=0; //打開8位輸入寄存器
DA_S1=1; //關(guān)閉8位輸入寄存器
}
#endif
key.h
#ifndef __KEY_h__
#define __KEY_h__
#include “adc0832.h”
#include “delay.h”
bit ST=0;
bit DUQU=0;
sbit key=P3^2;
unsigned char keytemp;
unsigned int total_freq; //總頻率
void key_int0() interrupt 0
{
EA=0; TR0=0; //關(guān)總中斷與定時器
delay(50); //延時夠嗎
if(key==0) //確實有按鍵按下而引發(fā)中斷
{delay(50);
if (key==0)
{
keytemp=P3&0xf8;
switch(keytemp)
{
case 0xf0://選擇波形
waveform++;
if(waveform》2) waveform=0;
break;
case 0xe8: //頻率按規(guī)定單位依次增加
wavefreq[waveform]++;
if(wavefreq[waveform]》10) wavefreq[waveform]=1;
break;
case 0xd8: //頻率按規(guī)定單位依次衰減
wavefreq[waveform]--;
if(wavefreq[waveform]《1) wavefreq[waveform]=10;
break;
}
}
THtemp=waveTH[waveform*10+(wavefreq[waveform]-1)]; //方括號中選取第幾個數(shù)后,并把該值賦給T_temp
TLtemp=waveTL[waveform*10+(wavefreq[waveform]-1)];
total_freq= wavefreq[waveform] * freq_unit[waveform]; //求輸出頻率(個數(shù)*單位)
lcd_hang2[5]=total_freq%10+0x30;lcd_hang3[5]=total_freq%10+0x30; //在液晶中顯示個位,(0x30 在液晶顯示中表示數(shù)字0)
total_freq/=10; lcd_hang2[4]=total_freq%10+0x30;lcd_hang3[4]=total_freq%10+0x30; //在液晶中顯示時十位
total_freq/=10; lcd_hang2[3]=total_freq%10+0x30;lcd_hang3[3]=total_freq%10+0x30; //在液晶中顯示時百位
total_freq/=10; lcd_hang2[2]=total_freq%10+0x30; lcd_hang3[2]=total_freq%10+0x30;//在液晶中顯示時千位
disp_lcd(0x80,&lcd_hang1[waveform*16]); //在第一行顯示
disp_lcd(0xc0,lcd_hang2); //在第二行顯示
}
wavecount=0; //‘抽點’計數(shù)清零
while(!key);
EA=1; TR0=1; //開啟總中斷與定時器
}
#endif
pltable.h
#ifndef __PLTABLE_h__
#define __PLTABLE_h__
/***********這兩組數(shù)組很重要,需要根據(jù)波形來調(diào)試,選擇合適的值,使輸出波形達(dá)到頻率要求************/
uchar code waveTH[]={
0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xec,0xf6,0xf9,0xfb,0xfc,0xfc,0xfd,0xfd,0xfd,0xfe};
uchar code waveTL[]={
0x16,0x9a,0x20,0x5e,0x88,0xa3,0xb8,0xc3,0xce,0xd6, //正弦波頻率調(diào)整中間值
0xbc,0xce,0x58,0x8a,0xa9,0xbf,0xcb,0xd8,0xe0,0xee,//三角波頻率調(diào)整中間值
0x98,0x60,0xa0,0x42,0x44,0xce,0x5a,0xb3,0xf5,0x3c};
/*************************************************************************************************/
uchar code triangle_tab[]={ //每隔數(shù)字8,采取一次
0x00,0x08,0x10,0x18,0x20,0x28,0x30,0x38,0x40,0x48,0x50,0x58,0x60,0x68,0x70,0x78,
0x80,0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0,0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8,0xff,
0xf8,0xf0,0xe8,0xe0,0xd8,0xd0,0xc8,0xc0,0xb8,0xb0,0xa8,0xa0,0x98,0x90,0x88,0x80,
0x78,0x70,0x68,0x60,0x58,0x50,0x48,0x40,0x38,0x30,0x28,0x20,0x18,0x10,0x08,0x00};
uchar code sine_tab[256]={
//輸出電壓從0到最大值(正弦波1/4部分)
0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,
0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,
0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
//輸出電壓從最大值到0(正弦波1/4部分)
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,
0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,
0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99 ,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,
//輸出電壓從0到最小值(正弦波1/4部分)
0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,
0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16 ,0x15,0x13,
0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
//輸出電壓從最小值到0(正弦波1/4部分)
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02 ,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,
0x11,0x13,0x15 ,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,
0x40,0x43,0x45,0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66 ,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80};
#endif
delay.h
#ifndef __DELAY_h__
#define __DELAY_h__
#define uchar unsigned char
#define uint unsigned int
void delay(uchar z)
{
uchar x,y;
for(x=z;x》0;x--)
for(y=110;y》0;y--);
}
void delay5us()
{ uchar i;
for(i=1;i》0;i--);
}
#endif
lcd1602.h
#define uchar unsigned char
#define uint unsigned int
void delay(uchar z)
{
uchar x,y;
for(x=z;x》0;x--)
for(y=110;y》0;y--);
}
void delay5us()
{ uchar i;
for(i=1;i》0;i--);
}
#endif
主程序
#include《reg52.h》
#include “l(fā)cd1602.h”
#include “delay.h”
#include “pltable.h”
#include “key.h”
#include “adc0832.h”
void timer0() interrupt 1
{
TH0=THtemp;
TL0=TLtemp;
if(waveform==0) sine_out();
else if(waveform==1) triangle_out();
else if(waveform==2) square_out();
}
void main()
{
DAdata=0;
DA_S1=1; //關(guān)閉8位輸入寄存器
init_lcd();
TMOD=0x01; //設(shè)置定時器0為16位工作方式
IT0=1; //設(shè)置外部中斷0為下降沿觸發(fā)
ET0=1; //開定時器中斷
EX0=1;
EA=1;
while(1) ;
}
小編推薦閱讀:
adc0832是什么_adc0832和adc0809區(qū)別
評論
查看更多