美國國家半導體公司生產的ADC0832是廣泛應用的8 位分辨率、雙通道A/D轉換芯片。ADC0832是雙通道輸入,并且可以軟件配置成單端或差分輸入,其串行輸出可以方便的和標準的移位寄存器及微處理器接口。 由于它體積小,兼容性,性價比高而深受單片機愛好者及企業歡迎,其目前已經有很高的普及率。
ADC0832的工作原理
正常情況下ADC0832 與單片機的接口應為4條數據線,分別是CS、CLK、DO、DI。但由于DO端與DI端在通信時并未同時使用并與單片機的接口是雙向的,所以在I/O口資源緊張時可以將DO和DI并聯在一根數據線上使用。當ADC0832未工作時其CS輸入端應為高電平,此時芯片禁用,CLK 和DO/DI 的電平可任意。當要進行A/D轉換時,須先將CS使能端置于低電平并且保持低電平直到轉換完全結束。此時芯片開始轉換工作,同時由處理器向芯片時鐘(CLK)輸入端輸入時鐘脈沖,DO/DI端則使用DI端輸入通道功能選擇的數據信號。在第一個時鐘脈沖的下沉之前DI端必須是高電平,表示啟始信號。在第二、三個脈沖下沉之前DI端應輸入兩位數據用于選擇通道功能。
表1:通道地址設置表
如表1所示,當此兩位數據為“1”、“0”時,只對CH0 進行單通道轉換。當2位數據為“1”、“1”時,只對CH1進行單通道轉換。當兩位數據為“0”、“0”時,將CH0作為正輸入端IN+,CH1作為負輸入端IN-進行輸入。當兩位數據為“0”、“1”時,將CH0作為負輸入端IN-,CH1 作為正輸入端IN+進行輸入。到第三個脈沖的下降之后DI端的輸入電平就失去輸入作用,此后DO/DI端則開始利用數據輸出DO進行轉換數據的讀取。從第4個脈沖下降沿開始由DO端輸出轉換數據最高位Data7,隨后每一個脈沖的下降沿DO端輸出下一位數據。直到第11個脈沖時發出最低位數據Data0,一個字節的數據輸出完成。也正是從此位開始輸出下一個相反字節的數據,即從第11個字節的下降沿輸出Data0。隨后輸出8位數據,到第19 個脈沖時數據輸出完成,也標志著一次A/D轉換的結束。最后將CS置高電平禁用芯片,直接將轉換后的數據進行處理就可以了。時序說明請參照圖1。
作為單通道模擬信號輸入時ADC0832的輸入電壓是0—5V且8位分辨率時的電壓精度為19.53mV,即(5/256)V。如果作為由IN+與IN-輸入的輸入時,可是將電壓值設定在某一個較大范圍之內,從而提高轉換的寬度。但值得注意的是,在進行IN+與IN-的輸入時,如果IN-的電壓大于IN+的電壓則轉換后的數據結果始終為00H。
圖1 ADC0832工作時序
ADC0832的引腳圖及功能
ADC0832的特點是
· 輸入輸出電平與TTL/CMOS相兼容;
· 工作頻率為250KHZ,轉換時間為32μS;
· 一般功耗僅為15mW;
· 8P、14P—DIP(雙列直插)、PICC 多種封裝;
· 商用級芯片溫寬為0°C to +70°C,工業級芯片溫寬為?40°C to +85°C;
芯片接口說明:
· CS_ 片選使能,低電平芯片使能。
· CH0 模擬輸入通道0,或作為IN+/-使用。
· CH1 模擬輸入通道1,或作為IN+/-使用。
· GND 芯片參考0 電位(地)。
· DI 數據信號輸入,選擇通道控制。
· DO 數據信號輸出,轉換 數據輸出。
· CLK 芯片時鐘輸入。
· Vcc/REF 電源輸入及參考電壓輸入(復用)。
圖3 ADC0832引腳圖
ADC0832 為8 位分辨率A/D轉換芯片,其最高分辨可達256級,可以適應一般的模擬量轉換要求。其內部電源輸入與參考電壓的復用,使得芯片的模擬電壓輸入在0~5V之間。芯片轉換時間僅為32μS,據有雙 數據輸出可作為數據校驗,以減少數據誤差,轉換速度快且穩定性能強。獨立的芯片使能輸入,使多器件掛接和處理器控制變的更加方便。通過DI 數據輸入端,可以輕易的實現通道功能的選擇。
adc0832內部結構及應用電路
adc0832內部結構圖
以下是基于stc89c51和ADC0832的函數信號發生器
仿真電路及調試圖
頭文件
adc0832.h
#ifndef __ADC0832_H__
#define __ADC0832_H__
#define DAdata P1//DA數據端口
uchar wavecount; //‘抽點’計數
uchar THtemp,TLtemp;//傳遞頻率的中間變量
uchar judge=1; //在方波輸出函數中用于簡單判別作用
uchar waveform; //當其為0、1、2時,分別代表三種波
uchar code freq_unit[3]={5,25,100}; //三種波的頻率單位
uchar idata wavefreq[3]={1,1,1}; //給每種波定義一個數組單元,用于存放單位頻率的個數
sbit DA_S1= P2^7; // 控制DAC0832的8位輸入寄存器,僅當都為0時,可以輸出數據(處于直通狀態),否則,輸出將被鎖存
void triangle_out()//三角波輸出
{
DAdata=triangle_tab[wavecount++];
if(wavecount》64) wavecount=0;
DA_S1=0; //打開8位輸入寄存器
DA_S1=1; //關閉8位輸入寄存器
}
void sine_out() //正弦波輸出
{
DAdata=sine_tab[wavecount++];
DA_S1=0; //打開8位輸入寄存器
DA_S1=1; //關閉8位輸入寄存器
}
void square_out() //方波輸出
{
judge=~judge;
if(judge==1) DAdata=0xff;
else DAdata=0x00;
DA_S1=0; //打開8位輸入寄存器
DA_S1=1; //關閉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; //關總中斷與定時器
delay(50); //延時夠嗎
if(key==0) //確實有按鍵按下而引發中斷
{delay(50);
if (key==0)
{
keytemp=P3&0xf8;
switch(keytemp)
{
case 0xf0://選擇波形
waveform++;
if(waveform》2) waveform=0;
break;
case 0xe8: //頻率按規定單位依次增加
wavefreq[waveform]++;
if(wavefreq[waveform]》10) wavefreq[waveform]=1;
break;
case 0xd8: //頻率按規定單位依次衰減
wavefreq[waveform]--;
if(wavefreq[waveform]《1) wavefreq[waveform]=10;
break;
}
}
THtemp=waveTH[waveform*10+(wavefreq[waveform]-1)]; //方括號中選取第幾個數后,并把該值賦給T_temp
TLtemp=waveTL[waveform*10+(wavefreq[waveform]-1)];
total_freq= wavefreq[waveform] * freq_unit[waveform]; //求輸出頻率(個數*單位)
lcd_hang2[5]=total_freq%10+0x30;lcd_hang3[5]=total_freq%10+0x30; //在液晶中顯示個位,(0x30 在液晶顯示中表示數字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; //‘抽點’計數清零
while(!key);
EA=1; TR0=1; //開啟總中斷與定時器
}
#endif
pltable.h
#ifndef __PLTABLE_h__
#define __PLTABLE_h__
/***********這兩組數組很重要,需要根據波形來調試,選擇合適的值,使輸出波形達到頻率要求************/
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, //正弦波頻率調整中間值
0xbc,0xce,0x58,0x8a,0xa9,0xbf,0xcb,0xd8,0xe0,0xee,//三角波頻率調整中間值
0x98,0x60,0xa0,0x42,0x44,0xce,0x5a,0xb3,0xf5,0x3c};
/*************************************************************************************************/
uchar code triangle_tab[]={ //每隔數字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 “lcd1602.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; //關閉8位輸入寄存器
init_lcd();
TMOD=0x01; //設置定時器0為16位工作方式
IT0=1; //設置外部中斷0為下降沿觸發
ET0=1; //開定時器中斷
EX0=1;
EA=1;
while(1) ;
}
小編推薦閱讀:
評論
查看更多