仿真圖及報告.zip
(374.05 KB, 下載次數: 164)
2016-9-26 15:25 上傳
點擊文件名下載附件
一、設計題目:簡易頻率計 二、設計目的: 1、掌握89C52單片機產生脈沖及定時的簡單程序編寫。 2、理解頻率計的測量原理。 三、設計任務及主要技術指標 3.1. 課程設計的任務 設計并仿真測量頻率和相位差的數字頻率計。 四、方案設計及論證 4.1測量方案 測量頻率的方法有很多種,主要分為模擬法和數字法兩大類,因為本次設計的要求和環境,現在主要討論數字法中的電子計數式的幾種測頻方法。 電子計數式的測頻方法主要有以下幾種:脈沖數定時測頻法(M法),脈沖周期測頻法(T法),脈沖數倍頻測頻法(AM法),脈沖數分頻測頻法(AT法),脈沖平均周期測頻法(M/T法),多周期同步測頻法。下面是幾種方案的具體方法介紹。 脈沖數定時測頻法(M法):此法是記錄在確定時間Tc內待測信號的脈沖個數Mx,則待測頻率為: Fx=Mx/Tc (2-1) 脈沖周期測頻法(T法):此法是在待測信號的一個周期Tx內,記錄標準頻率信號變化次數Mo。這種方法測出的頻率是: Fx=Mo/Tx (2-2) 脈沖數倍頻測頻法(AM法):此法是為克服M法在低頻測量時精度不高的缺陷發展起來的。通過A倍頻,把待測信號頻率放大A倍,以提高測量精度。其待測頻率為: Fx=Mx/ATo (2-3) 脈沖數分頻測頻法(AT法):此法是為了提高T法高頻測量時的精度形成的。由于T法測量時要求待測信號的周期不能太短,所以可通過A分頻使待測信號的周期擴大A倍,所測頻率為: Fx=AMo/Tx (2-4) 脈沖平均周期測頻法(M/T法):此法是在閘門時間Tc內,同時用兩個計數器分別記錄待測信號的脈沖數Mx和標準信號的脈沖數Mo。若標準信號的頻率為Fo,則待測信號頻率為: Fx=FoMx/Mo (2-5) 4.2方案論證 多周期同步測頻法:是由閘門時間Tc與同步門控時間Td共同控制計數器計數的一種測量方法,待測信號頻率與M/T法相同。 以上幾種方法各有其優缺點: 脈沖數定時測頻法,時間Tc為準確值,測量的精度主要取決于計數Mx的誤差。其特點在于:測量方法簡單,測量精度與待測信號頻率和門控時間有關,當待測信號頻率較低時,誤差較大。 脈沖周期測頻法,此法的特點是低頻檢測時精度高,但當高頻檢測時誤差較大。 脈沖數倍頻測頻法,其特點是待測信號脈沖間隔減小,間隔誤差降低;精度比M法高A倍,但控制電路較復雜。 脈沖數分頻測頻法,其特點是高頻測量精度比T法高A倍,但控制電路也較復雜。 脈沖平均周期測頻法,此法在測高頻時精度較高,但在測低頻信號時精度較低。 多周期同步測頻法,此法的優點是,閘門時間與被測信號同步,消除了對被測信號計數產生的±1個字誤差,測量精度大大提高,且測量精度與待測信號的頻率無關,達到了在整個測量頻段等精度測量。 此次課程設計采用間接測量法來測量。此次設計涉及到相位差,即兩列波形異或得到的波形只需要測高電平,要用到GATE信號,GATE=1時,TR0=1,INTO=1才能啟動計數器,而計數器0是通過外部中斷INTO的下降沿開始觸發的,計時器從0開始計時,計數器只能測高電平,因此測得的時間為半個周期。當計數器0計時溢出,執行m加1的操作。則測量時間為:t1=TH0*256+TL0+m*65536 ,所求頻率F=1000000/(2*t1) 。 測量兩方波的相位差時,先將兩方波信號異或,得到的新波形輸入外部中斷1的入口,在信號的第n個下跳沿時,進入外部中斷的程序,開啟計數器1。第n+1個下跳沿到來時,則關閉計數器1,當GATE=1時,只有在INT1=1 時,TR1=1時,計數器T1才開始計數,當計數器0計時溢出,執行m加1的操作,所以讀的的時間只為高電平的持續時間,即為兩方波的相隔時間t2,相位差可計算如下:t2=TH1*256+TLI+N*65536 ;則相位差P=t2/(2*t1)*360
關鍵詞:單片機;低頻;絕對誤差 4.3系統設計框圖 經過方案論證和比較后,最終確定的系統框圖如圖1所示,主要由AT89C52單片機、異或器件、LCD1602、電源等組成。
圖1 系統設計框圖 五、設計基本原理 5.1測量頻率的原理 定時/計數器工作在方式1,每產生一次定時器0中斷,計數65536個脈沖,此時的脈沖來自振蕩器的12分頻后的脈沖,其周期為1uS。根據產生外部中斷0時,定時器0中斷的次數u,以及此時定時/計數器0計數寄存器的數值X,即可求得待測方波的周期為:T=(65536*u+X)us ,取其倒數即可求得待測方波的頻率,小數點后保留兩位,即可使得頻率精度為0.1HZ。 5.2相位差的測量原理 將兩路同頻不同相的方波信號進過鑒相器(即異或)后得到的脈沖寬度t與方波信號的周期T的比值(占空比),即對應為兩信號的相位差,此時相位差
。其中,脈沖寬度的測量方法與方波周期的測量方法相同。相位差測量的原理圖如下:
圖2 相位差測量原理圖 六、單元電路設計,元器件選擇,總體電路設計 6.1 單片機最小系統設計 單片機最小系統是能補足單片機工作的最簡單電路,它由單片機、電源、晶體振蕩器、復位電路等構成。它是本系統的處理單元也是控制單元,負責處理信號、外設的接口與控制,同時它也是所有軟件的載體。 本系統采用AT89C52是美國Atmel公司生產的低電壓、高性能CMOS 8位單片機,片內含8KB的可反復檫寫的程序存儲器和12B的隨機存取數據存儲器(RAM),器件采用Atmel公司的高密度、非易失性存儲技術生產,兼容標準MCS-51指令系統,片內配置通用8位中央處理器(CPU)和Flash存儲單元,功能強大的AT89C52單片機可靈活應用于各種控制領域。AT89C52單片機屬于AT89C51單片機的增強型,與Intel公司的80C52在引腳排列、硬件組成、工作特點和指令系統等方面兼容。 主要管腳有: XTAL1(19 腳)和XTAL2(18 腳)為振蕩器輸入輸出端口,外接12MHz 晶振。 RST/Vpd(9 腳)為復位輸入端口,外接電阻電容組成的復位電路。 VCC(40 腳)和VSS(20 腳)為供電端口,分別接+5V電源的正負端。 P0~P3 為可編程通用I/O 腳,其功能用途由軟件定義。 其管腳如下圖所示:
圖3 AT89C52單片機管腳圖 本設計中,P0 端口(32~39 腳)被定義為N1 功能控制端口,分別與N1的相應功能管腳相連接。單片機正常工作時,都需要有一個時鐘電路和一個復位電路。本設計 中選擇了內部時鐘方式和按鍵電平復位電路,來構成單片機的最小電路。如圖4所示。
圖4 單片機最小系統 6.2液晶LCD1602顯示電路 字符型液晶顯示模塊是一種專門用于顯示字母、數字、符號等點陣式LCD,目前常用16*1,16*2,20*2和40*2行等的模塊。LCD1602分為帶背光和不帶背光兩種,基控制器大部分為HD44780,帶背光的比不帶背光的厚,是否帶背光在應用中并無差別。LCD1602采用標準的14腳(無背光)或16腳(帶背光)接口,各引腳接口說明如下表1所示: 表 1 LCD1602引腳接口說明 1602液晶模塊的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。1602液晶模塊內部的控制器共有11條控制指令,如下表2所示,其中1為高電平、0為低電平。 表 2 LCD1602控制指令 指令1:清顯示,指令碼01H,光標復位到地址00H位置。 指令2:光標復位,光標返回到地址00H。 指令3:光標和顯示模式設置 I/D:光標移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。 指令4:顯示開關控制。 D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示 C:控制光標的開與關,高電平表示有光標,低電平表示無光標 B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。 指令5:光標或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標。 指令6:功能設置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。 指令7:字符發生器RAM地址設置。 指令8:DDRAM地址設置。 指令9:讀忙信號和光標地址 BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據,如果為低電平表示不忙。 指令10:寫數據。 與HD44780相兼容的芯片時序如下表3所示: 表 3 基本操作時序表 | | | | | | | RS=L,R/W=L, D0—D7=指令碼,E=高脈沖 | | | | | | | | | | RS=H,R/W=L, D0—D7=數據,E=高脈沖 | | |
其操作時序圖如下所示:
圖5 讀操作時序圖
圖6 寫操作時序圖 本設計中采用液晶LCD1602顯示輸入方波A和B的頻率和相位差,其D0~D7與單片機的P0端口連接,使能端E、RS、RW分別與單片機P2.4、P1.7、P1.6連接,此電路原理簡單,電路連接方便,如圖7所示。
圖7 液晶LCD1602顯示電路 6.3頻率、相位差測量電路 本設計中將方波A輸入,采用定時中斷測量其頻率,同時將方波A和方波B經過異或門74LS86異或后輸入即可測量出兩路方波的相位差。 異或門74LS86真值表如表4所示: 表4 74LS86真值表 綜上所述,頻率、相位表的總體電路圖如圖8所示:
圖8 頻率相位表的總體電路圖 6.4程序設計 6.4.1資源分配表 表5 資源分配表 七、軟件設計 7.1頻率、相位表的程序流程圖如圖所示:
圖9 程序流程圖 八、安裝(仿真)、調試 8.1仿真 仿真軟件PROTUES中按照電路圖連接好電路。輸入兩待測方波信號波形,當測試頻率時,先依次設置好方波A和B的頻率,進行仿真測得數據;當測試相位差,先將方波A和B頻率設置為500HZ,然后依次設置相位差,測試波形和結果如圖10所示:
圖10 仿真波形 表6 仿真頻率測試結果 表7 仿真相位差測試結果 8.2性能分析 根據表6測試所得結果可以看出:當輸入頻率0-550HZ時,頻率誤差大約為0.05HZ,小于0.1HZ;當輸入頻率大于600HZ時,頻率誤差大于0.1HZ,并且隨著輸入頻率增大,頻率誤差均大于0.1HZ,故輸入頻率為0-550HZ時滿足要求。根據表7測試所得結果可以看出:當輸入的兩路方波的相位差0-180度時,測試相位差大約為0度,小于0.1度,測試所得相位差性能比較好。由此可得如下結論:本次所設計的頻率/相位差表適合測試低頻信號,最佳頻率范圍為0-550HZ,輸入方波相位差任意均可。 九、心得與體會 本次課程設計有較強的綜合性,不僅要求設計者能靈活使用單片機,熟練使用單片計計數器和定時器,熟練編寫順序結構程序,循環結構程序以及分支結構程序,還要求對單片機的電路連接結構,對數碼管芯片有明確清晰的了解與認識,否則在設計的第一步就會遇到障礙。鞏固和應用了C語言的程序編寫,對于仿真,基于以往對PROTUTES和KEIL的使用,此次仿真更是得心應手,基本上沒遇到大問題,不過這次設計學會了虛擬示波器的使用。 看著自己親自通過自己的知識和努力設計的頻率計,心里是很欣慰的,還學到了很多,例如面對問題要保持冷靜,特別是在程序的編寫這一塊,通過大量查閱資料和思考,還有組員的討論與鼓勵,最終解決了問題,使我深刻感知要找出程序的錯誤一定要保持一個冷靜的頭腦,否則很難發現錯誤甚至是越改越錯。另外我還認識到與他人合作的重要性,虛心向別人學習,能力和意志力都有所提高。 最后,感謝在這次課程設計中汪斌老師、袁菊明老師及謝東福老師提供的指導和幫助! 十、參考文獻 李朝青,劉艷玲.單片機原理及接口技術[M].4版.北京:北京航空航天大學出版社,2013. 附錄一: 源程序 - #include
- #include
- #define uint unsigned int
- #define uchar unsigned char
- uchar m=0,n=0;
- uchar u,v;
- uint i,j;
- uint x,y;
- uint c,d; //相位數據結果保存
- float t0,t1,f,p;
- uint a[]={70,61,48,48,48,48,48,46,48,48,72,90}; //頻率數據結果保存
- //F,=,0,0,0,0,0,.,0,0,H,Z
- uint b[]={80,61,48,48,48,46,48,48,34}; //相位數據結果保存
- //P,=,0,0,0,.,0,0," //相位數據結果保存
- sbit lcdrw=P1^6;
- sbit lcdrs=P1^7;
- sbit lcden=P2^4;
- /////////////////LCD1602的設置//////////////////////////////////
- void delay(uint s)//延時1MS
- {
- uint r,g;
- for(r=s;r>0;r--)
- for(g=110;g>0;g--);
- }
- void write_com(uchar com) // 寫指令
- {
- lcdrs=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_data(uchar date) // 寫數據
- {
- lcdrs=1;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void initlcd()//初始化
- {
- lcdrw=0;
- lcden=0;
- //write_com(0x01);//顯示清屏
- write_com(0x38);//顯示模式設置
- write_com(0x0c); //顯示開,開游標,不閃爍
- write_com(0x06); // 字符時整體不移動
- }
- ////////////LCD1602設置///////////////
- ///////////定時器的設置//////////////
- void CT_init() //定時計數器初始化
- { TMOD=0x99; //GATE=1,T1、T0工作在方式1,定時方式
- TH0=0; //定時計數器初值清零
- TL0=0;
- TH1=0;
- TL1=0;
- TR0=1; //TR0,TR1置位,此時定時計數器的啟動有INT0,INT1引腳電平決定
- TR1=1;
- ET0=1; //開中斷
- ET1=1;
- }
- void ITC0() interrupt 0 //外部中斷0服務程序
- {
- u=m; //讀定時計數器0溢出次數
- m=0; //溢出次數清零
- x=TH0*256+TL0; //讀定時計數器0當前值
- TH0=0; //定時計數器0清零
- TL0=0;
- }
- void TIME0() interrupt 1 //定時計數器0溢出中斷
- {
- m++; //溢出次數加1
- }
- void ITC1() interrupt 2 //外部中斷1服務程序
- {
- v=n; //讀定時計數器1溢出次數
- n=0; //溢出次數清零
- y=TH1*256+TL1; //讀定時計數器1當前值
- TH1=0; //定時計數器1清零
- TL1=0;
- }
- void TIME1() interrupt 3 //定時計數器1溢出中斷
- {
- n++; //溢出次數加1
- }
- ////////////定時器的設置//////////////
- void main()
- {
- initlcd(); //液晶顯示初始化
- CT_init(); //定時計數器初始化
- EA=1; //開總中斷
- EX0=1; //允許外部中斷
- EX1=1;
- IT0=1; //設置外部中斷方式為下降沿觸發
- IT1=1;
- P3=0xff;
- while(1)
- {
- t0=u*65536+x; //計算脈沖時間寬度
- f=1000000/(2*t0); //計算頻率
- c=f*100; //計算結果逐位保存
- a[9]=c%10+48;
- a[8]=(c/10)%10+48;
- c=f;
- a[6]=c%10+48;
- a[5]=(c/10)%10+48;
- a[4]=(c/100)%10+48;
- a[3]=(c/1000)%10+48;
- a[2]=(c/10000)%10+48;
- write_com(0x80);
- for(i=0;i<=11;i++)
- {
- write_data(a[i]);
- delay(10);
- }
- t1=v*65536+y; //計算脈沖寬度
- p=(t1/(2*t0))*360; //計算相位差
- d=p*100; //將計算結果逐位保存
- b[7]=d%10+48;
- b[6]=(d/10)%10+48;
- d=p;
- b[4]=d%10+48;
- b[3]=(d/10)%10+48;
- b[2]=(d/100)%10+48;
- write_com(0x80+0X40);
- for(j=0;j<=8;j++)
- {
- write_data(b[j]);
- delay(10);
- }
- }
- }
復制代碼
|