簡易數(shù)字直流電壓表電路及程序 2022-06-20
簡易數(shù)字直流電壓表電路及程序
??? 設計一個簡易數(shù)字直流電壓表。(量程0V-2V、測量速度為大于等于2次/秒、測量誤差在±0.05V以內(nèi),有超限報警、數(shù)碼管顯示。)3.5.1模塊1:系統(tǒng)設計(1)分析任務要求,寫出系統(tǒng)整體設計思路從試題的要求分析,主要包括的內(nèi)容為ADC轉換電路的控制、采用定時器定時讀取ADC轉換器的數(shù)據(jù)、將ADC轉換器的數(shù)據(jù)計算為對應的電壓值,最后在數(shù)碼管上顯示出來。(2)選擇單片機型號和所需外圍器件型號,設計單片機硬件電路原理圖?采用MCS51系列單片機At89S51作為主控制器,外圍電路器件包括數(shù)碼管驅動、AD轉換器TLC549、基準電壓TL431等。數(shù)碼管驅動采用2個四聯(lián)共陰極數(shù)碼管顯示,由于單片機驅動能力有限,采用74HC244作為數(shù)碼管的驅動。在74HC244的7段碼輸出線上串聯(lián)100歐姆電阻起限流作用。AD轉換器的參考電壓由精密基準電源TL431提供,標準參考電壓Vref+為2.5伏, Vref-為0伏。由于0V-2V內(nèi)的測量誤差控制在±0.05V內(nèi),因此8 位A/D轉換器即可滿足要求。AD轉換器TLC549是以8位開關電容逐次逼近A/D轉換器為基礎而構造的CMOS A/D轉換器。 它們設計成能通過3態(tài)數(shù)據(jù)輸出和模擬輸入與微處理器或外圍設備串行接口。TLC549僅用輸入/輸出時鐘(I/O CLOCK)和芯片選擇 (CS)輸入作數(shù)據(jù)控制。TLC549的IO CLOCK輸入頻率最高可達1.1MHz。TLC549提供了片內(nèi)系統(tǒng)時鐘,它通常工作在4MHz且不需要外部元件。片內(nèi)系統(tǒng)時鐘使內(nèi)部器件的操作獨立于串行輸入/輸出的時序并允許TLC548和TLC549象許多軟件和硬件所要求的????? I/O CLOCK和內(nèi)部系統(tǒng)時鐘一起可以實現(xiàn)高速數(shù)據(jù)傳送以及對于TLC549為每秒40,000次轉換的轉換速度。TLC549 的引腳排列分別如圖3-17下。
如圖3-17 TLC549 的引腳排列??? TLC549 的工作時序如圖3-18所示。
圖3-18? TLC549 的工作時序轉換周期需要36個系統(tǒng)時鐘周期(最大為 17μs),它開始于CS變?yōu)榈碗娖街驣/O CLOCK的第8個下降沿,這適用于該時刻其地址存在于存儲器中的通道。在CS變?yōu)榈碗娖胶?,最高有效?(A7)自動被放置在DATA OUT總線上。其余的7 位(A6-A0)在前7個I/O CLOCK下降沿由時鐘同步輸出。TLC549的工作原理TLC549是在單個芯片內(nèi)的完善的數(shù)據(jù)采集系統(tǒng)。每一個器件包含內(nèi)部系統(tǒng)時鐘,采樣和保持,8位A/D轉換器,數(shù)據(jù)寄存器以及控制邏輯電路。為了提高靈活性和訪問速度,器件有兩個控制輸入:I/OCLOCK和芯片選擇(CS)。這些控制輸入和與TTL兼容的3態(tài)輸出易于與微處理器或小型計算機的串行通信。器件可在17μs或更短時間內(nèi)完成轉換。TLC549每25μs重復一次完整的輸入-轉換-輸出(input-conversion-output)周期。內(nèi)部系統(tǒng)時鐘和I/OCLOCK獨立使用且不需要任何特定的速度或二者之間的相位關系。這種獨立性簡化了器件的硬件和軟件控制任務。由于這種獨立性和系統(tǒng)時鐘的內(nèi)部產(chǎn)生,控制硬件和軟件只需關心利用I/O時鐘讀出先前轉換結果和啟動轉換。內(nèi)部系統(tǒng)時鐘以這種方式驅動轉換電路以便控制硬件和軟件不需要涉及此項任務。當CS為高電平時,DATAOUT處于高阻狀態(tài)且I/OCLOCK(I/O時鐘)被禁止。正常控制時序為:1.CS被拉至低電平。當CS變?yōu)榈碗娖綍r,前次轉換結果的最高有效位(MSB)開始出現(xiàn)在DATAOUT端。2.前4個I/OCLOCK周期的下降沿輸出前次轉換結果的第2、第3、第4和第5個最高有效位。在I/OCLOCK第4個高電平至低電平的跳變之后,片內(nèi)采樣和保持電路開始對模擬輸入采樣。采樣操作主要包括內(nèi)部電容器充電到模擬輸入電壓的電平。3.其后再把三個I/OCLOCK周期加至I/OCLOCK端,在這些時鐘周期的下降沿,第6、第7和第8個轉換位被移出。4.最后(第8個)時鐘周期被加至I/OCLOCK。此時鐘周期高電平至低電平的跳變使片內(nèi)采樣和保持電路開始保持功能。保持功能在接著四個內(nèi)部系統(tǒng)時鐘周期內(nèi)繼續(xù)進行,在此之后保持功能結束且在下面32個系統(tǒng)時鐘周期內(nèi)完成轉換,總共為36個周期。在第8個I/OCLOCK周期之后,CS必須變?yōu)楦唠娖剑駝tI/OCLOCK必須保持低電平達至少36個系統(tǒng)時鐘周期以供保持和轉換功能的完成。在多個轉換周期內(nèi)CS可保持低電平。在多個轉換周期內(nèi)使CS保持低電平時必須特別注意防止I/OCLOCK線上的噪聲閃變。如果在I/OCLOCK上發(fā)生閃變,那么在微處理器/控制器和器件之間的I/O時序將失去同步。此外,如果CS變?yōu)楦唠娖?,那么它必須保持高電平直至轉換結束為止。否則,CS的有效高電平至低電平跳變將引起復位,它使正在進行的轉換失敗。在36個系統(tǒng)時鐘周期發(fā)生之前,通過完成步驟1至4可以啟動新的轉換,同時正在進行的轉換中止。此操作產(chǎn)生先前的轉換結果而不是正在進行的轉換結果。(3)分析軟件任務要求,寫出程序設計思路,分配單片機內(nèi)部資源,畫出程序流程圖??? 軟件的任務包括定時器的定時功能、AD轉換器TLC549的控制與數(shù)據(jù)的讀取,數(shù)碼管的動態(tài)掃描。程序設計思路,采用查詢定時器中斷標志的方式來啟動AD轉換器TLC549的工作,在讀取AD轉換器的數(shù)據(jù)之后,再對數(shù)據(jù)進行計算換算為對應的電壓值。??? 需要分配的單片機存儲資源包括AD轉換器數(shù)據(jù)的暫存變量(re_data)、定時器溢出次數(shù)的計數(shù)變量(T_cnt)、數(shù)據(jù)換算的系數(shù)(xishu)以及電壓值(volt)等。??? 主程序的流程圖如圖3-19所示。由于采用查詢中斷標志的方式來響應的中斷,所以主程序要循環(huán)完成如下任務:中斷標志的查詢、AD轉換器數(shù)據(jù)的讀取、電壓值的換算以及數(shù)碼管的動態(tài)掃描顯示。
圖3-19數(shù)字電壓表的主程序流程圖
(4)設計系統(tǒng)軟件調(diào)試方案、硬件調(diào)試方案及軟硬件聯(lián)合調(diào)試方案軟件調(diào)試方案:偉福軟件中,在“文件\新建文件”中,新建C語言源程序文件,編寫相應的程序。在“文件\新建項目”的菜單中,新建項目并將C語言源程序文件包括在項目文件中。?在 “項目\編譯”菜單中將C源文件編譯,檢查語法錯誤及邏輯錯誤。在編譯成功后,產(chǎn)生以 “*.hex”和“*.bin” 后綴的目標文件。硬件調(diào)試方案:在設計平臺中,將單片機的P1.0接TLC549的CLK管腳,P1.1接TLC549的DOUT管腳,P1.2接TLC549的CS管腳。在偉福中將程序文件編譯成目標文件后,將下載線安裝在實驗平臺上,運行“MCU下載程序”,選擇相應的flash 數(shù)據(jù)文件,點擊“編程”按鈕,將程序文件下載到單片機的Flash中。然后,上電重新啟動單片機,檢查所編寫的程序是否達到題目的要求,是否全面完整地完成試題的內(nèi)容。
3.6.2 模塊2 程序設計//晶振:11.0592MHz,定時器T0每50ms中斷一次,每隔0.1秒讀ADC一次/* AD轉換器使用 TLC549?? p1.0-Clock?? p1.1-Data out?? p1.2-CS?? */#include "reg51.h"#include "intrins.h"#include "math.h"sbit ad_clk=P1^0;sbit ad_dout=P1^1;sbit ad_cs=P1^2;unsigned char data re_data;unsigned int? data T_cnt;double volt,xishu;char code led_seg_code[10]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//led_seg_code[0-9]代表0-9的7段碼 //---------------void delay(unsigned int i)//延時{??? while(--i); }//---------------void led_show(double f){ unsigned char i,s;? unsigned int k,*j;? if (f<2)? {?? k=f;//取整數(shù) 部分????? i=k;????? P0=led_seg_code[i] | 0x80;????? P2=0xfb;????? delay(50);????? i=f*10;????? i=i%10;????? P0=led_seg_code[i];????? P2=0xfd;????? delay(50);????? i=f*100;? //取小數(shù)后1位????? i=i%10;????? P0=led_seg_code[i];????? P2=0xfe;????? delay(50);?? else //超限報警,顯示“---”?? {? P0=0x40;????? P2=0xfb;????? delay(50);?? ????? //---------????? P2=0xfd;????? delay(50);????? //-----------????? P2=0xfe;????? delay(50);?? }}//----讀取ADC轉換器TLC549的數(shù)據(jù)----unsigned char receive_data(){unsigned char i,d;?d=0;?ad_cs=1;??? // /CS置高,片選無效?ad_clk=0;?ad_cs=0;?_nop_();?for(i<0;i<8;i++)?{ ad_clk=1;?? d=d<<1;?? if (ad_dout)?? { d++;}?? ad_clk=0;?}?ad_cs=1;?for(i=0;i<10;i++) // 適當延時超過17us? _nop_();?return d;}//-------------main(){T_cnt=0;TMOD=0x01; //定時器設置T0TH0=0x4c;?? //50000us=(65536-0x4c00)*12/11.0592TL0=00;EA=0;TR0=1;re_data=0x00;volt=0;xishu=2.5/255.0;//-----------------------------while(1){? if(TF0==1)?? {? TF0=0;????? TH0=0x4c;?? //50000us=(65536-0x4c00)*12/11.0592????? TL0=0x0;????? if (T_cnt<2) //T0為50毫秒溢出一次,每100ms讀取一次AD轉換器數(shù)據(jù)????? {T_cnt++;}????? else????? {? T_cnt=0;//計時到100ms了???????? re_data=receive_data();???????? //轉換為電壓值???????? volt=re_data;???????? volt=volt*xishu;?????? }?? }?? led_show(volt);}}
|