![]() |
發布時間: 2018-9-26 20:34
正文摘要:請問,我用以下的仿真圖連接實物,為什么采不出真實的電壓值?仿真圖,可以采到差不多的電壓值。我的實物圖是沒有還提供采集通道的電壓呢,怎么就有電壓3.710出來了?有做個類似的么?是不是仿真圖不能用實物連接的 ... |
仿真不準正常 |
xuanshao 發表于 2018-11-7 22:12 建議還是用帶ADC的單片機采集AD吧 |
不要在AD0808之類的過時芯片上浪費時間了,0808占用IO口超多,還需提供時鐘,并且只有8位.現在的單片機基本都集成了ADC功能,分辨率也完爆0808,要求不高的話,模擬電壓量直接接到IO剩下的工作就是敲鍵盤而已.寄存器設置參考手冊上的例程即可,非常簡單.可以說0808已經沒有任何使用價值,這完全是教材跟不上時代的原因.(沒記錯的話0808的價錢還比片上集成12位ADC的51價格還貴)個人覺得學51最好的教材就是參考手冊 |
樓主,我的也遇到相同問題能加下你,問下么 |
cjm82 發表于 2018-9-28 09:56 我今天用12系列的做出來了,也采到了電壓。謝謝你們了。 |
FJ2018 發表于 2018-9-27 16:54 一般應用直接接帶有ADC功能的IO口,設置相關寄存器就行,怎么設置手冊里有詳細的介紹,12系列ADC是10位的,最新的8系列IO口是12位的.QFP64封裝的有單獨的ADC電源和參考電壓引腳,適合接基準源精度較高的場合.相關電路手冊里也有,下圖是從手冊里截的,最常用的接法 |
QQ圖片20180928094823.png (42.8 KB, 下載次數: 60)
有時候不要光想著軟件問題,有可能是硬件問題呢?之前我弄了一個搞了半天,結果是硬件的問題,你查一下基準電壓,還有電阻的阻值啊!這些有偏差也會導致電壓不準的! |
cjm82 發表于 2018-9-27 11:01 我想請問下,用STC12系列的單片機是不是采集電壓直接連IO口就可以了,不用其他外圍電路了吧。你有類似的電路么 |
看來,直接用89C52直接產生不了AD芯片需要的時鐘信號(500-640KHZ),實物上沒有產生clk這個時鐘信號。 |
yk910127 發表于 2018-9-27 10:19 好的,我試試,謝謝了 |
8位重載模式,定時計數器高8位和低8位應該值相等才對. 并且不需要在中斷函數里面對TH0 TL0進行設置. void Init_T0() //12M晶振12分頻 { TMOD |=0x02; TH0 = 0x9c; TL0 = 0x9c; ET0 = 1; TR0 = 1; EA = 1; } 中斷服務函數 void Timer0_ISR () interrupt 1 { CLK = ~CLK; } 如果沒有示波器,你可以接個LED到CLK口,然后用中斷寫個1秒閃一次的程序看看LED會不會閃就知道了,如果閃,把頻率改高就行. 用AD直接用12系列以上的51現在新出的芯片片上都集成了12位的ADC,只需要1個IO口作為模擬輸入口就行,ADC0809這種過時的芯片,除了在過時的書上面,實際運用中根本不會用到. |
看下ADC0809這個芯片手冊提供的時序,然后看看你程序是不是一致,如果大致沒問題,可以嘗試微調下延時的時間,如有需求可以加Q:1327360970 |
有沒人給我看看,是不是AD芯片時鐘信號給的不對?下面是程序 #include <reg52.h> //52系列單片機頭文件 #include <intrins.h> #include "math.h" #define uchar unsigned char #define uint unsigned int sbit st=P2^2; //定義AD的WR端口 sbit oe=P2^3; //定義AD的RD端口 sbit eoc=P2^0; sbit ale=P2^1; sbit lcden=P2^6; //液晶使能端 sbit lcdrs=P2^4; //液晶數據命令選擇端 sbit ADDA=P2^5; //定義A、B、C三條地址線 sbit ADDB=P3^6; sbit ADDC=P3^7; sbit CLK=P2^7; //定義時鐘端口 uint a,num; float OPA,OPB,AD; uchar code table41[]="WELCOME!"; /********* 延遲函數 **********/ void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } /************ 2002寫命令 **************/ void write_com(uchar com) { lcdrs=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } /************ 2002寫數據 *************/ void write_data(uchar date) { lcdrs=1; P0=date; delay(5); lcden=1; delay(5); lcden=0; } /**************** 液晶初始化 *********************/ void init() { lcden=0; write_com(0x38);//設置2002顯示,5X7點陣,8位數據接口 write_com(0x0c);//設置開顯示,不顯示光標 write_com(0x06);//寫一個字符后地址指針加1 write_com(0x01);//顯示清零,數據指針清零 } /******************** 顯示程序 ****************************/ void display(uint x,uint qian,uint bai,uint shi,uint ge) { write_com(0x80+x); write_data(0x30+qian); write_data('.'); write_data(0x30+bai); write_data(0x30+shi); write_data(0x30+ge); } /******************** 定時中斷初始化,為了產生AD芯片需要的時鐘信號 *********************/ void init_time0() { TMOD = 0x02; TH0=(65536-100)/256; TL0=(65536-100)%256; IE = 0x82; TR0 = 1; } /******************** A通道OPA光電壓采集 ***********************/ void OPA_1() { ADDA=1; //選擇通道1 ADDB=0; ADDC=0; oe=0; //關閉輸出允許位 st=0; st=1; st=0; //以上三句,開ADC0809 delay(1); //延遲1ms while(!eoc);//等待轉化結束 P1=0xff; oe=1; //開啟輸出允許位 a=P1; //將轉化出的數字存放至a a=a*19.53125; // a=a*5/256*1000 OPA=a*0.001; } /******************** 主函數: *******************/ void main() { uint a1,a2,a3,a4; init_time0(); init(); write_com(0x80+0x07); for(num=0;num<8;num++) { write_data(table41[num]); delay(150); } delay(1000); while(1) { OPA_1();//A路光電壓采集 a1=a/1000; a2=a/100%10; a3=a/10%10; a4=a%10; display(0x48,a1,a2,a3,a4); } } void Timer0_INT() interrupt 1 //用定時中斷產生ADC芯片時鐘信號 { TH0=(65536-100)/256; TL0=(65536-100)%256; CLK = ~CLK; } |
小貓貓愛吃魚 發表于 2018-9-26 21:21 我用是0.2ms中斷一次產生時鐘的,給你看看程序對不對 #include <reg52.h> //52系列單片機頭文件 #include <intrins.h> #include "math.h" #define uchar unsigned char #define uint unsigned int sbit st=P2^2; //定義AD的WR端口 sbit oe=P2^3; //定義AD的RD端口 sbit eoc=P2^0; sbit ale=P2^1; sbit lcden=P2^6; //液晶使能端 sbit lcdrs=P2^4; //液晶數據命令選擇端 sbit ADDA=P2^5; //定義A、B、C三條地址線 sbit ADDB=P3^6; sbit ADDC=P3^7; sbit CLK=P2^7; //定義時鐘端口 uint a,num; float OPA,OPB,AD; uchar code table41[]="WELCOME!"; /********* 延遲函數 **********/ void delay(uint z) { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } /************ 2002寫命令 **************/ void write_com(uchar com) { lcdrs=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } /************ 2002寫數據 *************/ void write_data(uchar date) { lcdrs=1; P0=date; delay(5); lcden=1; delay(5); lcden=0; } /**************** 液晶初始化 *********************/ void init() { lcden=0; write_com(0x38);//設置2002顯示,5X7點陣,8位數據接口 write_com(0x0c);//設置開顯示,不顯示光標 write_com(0x06);//寫一個字符后地址指針加1 write_com(0x01);//顯示清零,數據指針清零 } /******************** 顯示程序 ****************************/ void display(uint x,uint qian,uint bai,uint shi,uint ge) { write_com(0x80+x); write_data(0x30+qian); write_data('.'); write_data(0x30+bai); write_data(0x30+shi); write_data(0x30+ge); } /******************** 定時中斷初始化,為了產生AD芯片需要的時鐘信號 *********************/ void init_time0() { TMOD = 0x02; TH0=(65536-200)/256; TL0=(65536-200)%256; IE = 0x82; TR0 = 1; } /******************** A通道OPA光電壓采集 ***********************/ void OPA_1() { ADDA=1; //選擇通道1 ADDB=0; ADDC=0; oe=0; //關閉輸出允許位 st=0; st=1; st=0; //以上三句,開ADC0809 delay(1); //延遲1ms while(!eoc);//等待轉化結束 P1=0xff; oe=1; //開啟輸出允許位 a=P1; //將轉化出的數字存放至a a=a*19.53125; // a=a*5/256*1000 OPA=a*0.001; } /******************** 主函數: *******************/ void main() { uint a1,a2,a3,a4; init_time0(); init(); write_com(0x80+0x07); for(num=0;num<8;num++) { write_data(table41[num]); delay(150); } delay(1000); while(1) { OPA_1();//A路光電壓采集 a1=a/1000; a2=a/100%10; a3=a/10%10; a4=a%10; display(0x48,a1,a2,a3,a4); } } void Timer0_INT() interrupt 1 //用定時中斷產生ADC芯片時鐘信號 { TH0=(65536-200)/256; TL0=(65536-200)%256; CLK = !CLK; } |