初學單片機,.附件是對程序的分析和proteus仿真,適合初學搭建電路,按鍵1,2程序功能有問題,不知道那步的邏輯出現了問題,沒有實現頻率微調的功能.
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
Proteus仿真中ANOLOGUE示波器使用簡述: 第一次運行示波器會自動打開,在關閉示波器也就是叉了之后,再次運行不會自動打開,需右擊示波器選擇最下面英文選項. 連接四個掃描口中的一個,對應有四個channal,旋鈕調節掃描電壓值以改變格子代表單位,,指向為一格所代表的電壓值,例如指向2mv,則上下一格代表2mv.滾輪移動上下坐標,可調節使其對其某根線便于測量. Horizontal旋鈕橫向掃描周期調節,可用于調節周期波形寬度,橫向滾輪調節水平坐標.小旋扭都為微調. 
Proteus仿真 原件:res電阻 89c51 DAC0832 LM358N BUTTON GENELECT10U16V
主函數: void main() { m=65536-(150000/pinlv); // a=m/256; b=m%256; initclock(); while(1) { if(h==0) { keyscan(); }
switch(boxing) { case 0 : P1=sin; break; case 1 : P1=juxing; break; case 2 : P1=sanjiao; break; case 3 : P1=juchi; break; } } }
主函數: 首先給m,a,b賦初值,調用initclock(),initclock void initclock() { TMOD=0x01; TH0=a ; TL0=b ; EA=1; ET0=1; TR0=1; }
定時器方式寄存器TMOD: TMOD用于寫入方式控制字,,以選擇定時/計數器的工作狀態及控制方式;共八位,高四位與低四位相同,分別是GATE C/T M1 M0,高四位控制T1,低四位控制T0. M1M0用于指定工作方式,通過00 01 10 11的組合,可使定時/計數器分別對應工作在0 1 2 3方式 C/T:選擇定時/計數.C,T分別表示計數器和定時器.當C/T=1時,選擇計數狀態,當C/T=0時選擇定時狀態 TH0= TL0= 計數器0的高八位和第八位,組合以放更大的數字,加一計數直至計數器滿溢出,這時打開EA(EA=1)開啟中斷總開關,打開ET0開啟計數器一中斷開關,TR0=1,開啟定時器0開關
實參賦給Initclock()TH0,TL0,a=m/256;b=m%256;賦初值的意義是使計數器提前溢出從而啟動中斷 void T0_time()interrupt 1 { TH0= a ; TL0= b ; u++; if(u>=64) u=0; } 之后執行循環 while(1) { keyscan();
switch(boxing) { case 0 : P1=sin; break; case 1 : P1=juxing; break; case 2 : P1=sanjiao; break; case 3 : P1=juchi; break; } } } 循環體首先調用函數按鍵檢測函數keyscan() void keyscan() { if(s1==0) { EA=0; delay(2); if(s1==0) { while(!s1); pinlv+=bujin; if(pinlv>1000) { pinlv=100; } m=65536-(150000 / pinlv); a=m / 256; b=m % 256; EA=1; } } if(s2==0) { delay(5); if(s2==0) { EA=0; while(!s2); pinlv-=bujin; if(pinlv<100) { pinlv=1000; } m=65536-(150000/pinlv); a=m/256; b=m%256; EA=1; } } if(s3==0) { delay(5); if(s3==0) { EA=0; while(!s3); boxing++; if(boxing>=4) { boxing=0; }
EA=1; } } } S3是波形變換按鍵,首先關閉總中斷執行下方語句,按鈕按下判斷,當 S3=0即按鈕按下,while(!s3); 語句代表按鍵按下時,進行死循環不執行下方語句,松開按鍵后boxing++是波形變換關鍵,通過變boxing的值,賦給switch()語句選擇波形 switch(boxing) { case 0 : P1=sin; break; case 1 : P1=juxing; break; case 2 : P1=sanjiao; break; case 3 : P1=juchi; break; } Sin[] juxing[] sanjiao[] juchi[] 為四個數組,通過賦值給P1并行IO口,傳給DAC0832以VREF輸出模擬信號,通過中斷中的u++實現數組取數組元素的移動,實現信號的變換,在波形顯示器上顯示波形,然后打開中斷執行變換后波形, 按鍵s1,s2執行波形頻率的加減.同樣關閉中斷,pinglv+=bujin改變值,然后打開中斷.
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit s1=P3^5;
- sbit s2=P3^6;
- sbit s3=P3^7;
- sbit s4=P3^4;
- int pinlv=100,bujin=1;
- unsigned int m;
- char boxing,u;
- int a,b;
- uchar code sin[64]={
- 135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
- 146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128
- }; //正弦波取碼
- uchar code juxing[64]={
- 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
- 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
- }; //矩形波取碼
- uchar code sanjiao[64]={
- 0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
- 248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
- }; //三角波取碼
- uchar code juchi[64]={
- 0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,
- 146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255
- }; //鋸齒波取碼
- void initclock()
- {
- TMOD=0x01;
- TH0=a ;
- TL0=b ;
- EA=1;
- ET0=1;
- TR0=1;
- }
-
- void delay(uint xms)
- {
- int c,d;
- for (c=xms;c>0;c--)
- for(d=110;d>0;d--);
- }
- void keyscan()
- {
- if(s1==0)
- {
- EA=0;
- delay(2);
- if(s1==0)
- {
- while(!s1);
- pinlv+=bujin;
- if(pinlv>1000)
- {
- pinlv=100;
- }
- m=65536-(150000 / pinlv);
- a=m / 256;
- b=m % 256;
- EA=1;
- }
- }
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- EA=0;
- while(!s2);
- pinlv-=bujin;
- if(pinlv<100)
- {
- pinlv=1000;
- }
- m=65536-(150000/pinlv);
- a=m/256;
- b=m%256;
- EA=1;
- }
- }
- if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- EA=0;
- while(!s3);
- boxing++;
- if(boxing>=4)
- {
- boxing=0;
- }
-
- EA=1;
- }
- }
- }
-
- void main()
- {
- m=65536-(150000/pinlv);
- a=m/256;
- b=m%256;
- initclock();
- while(1)
- {
- keyscan();
-
- switch(boxing)
- {
- case 0 : P1=sin[u]; break;
- case 1 : P1=juxing[u]; break;
- case 2 : P1=sanjiao[u]; break;
- case 3 : P1=juchi[u]; break;
- }
- }
- }
-
- void T0_time()interrupt 1
- {
- TH0= a ;
- TL0= b ;
- u++;
- if(u>=64)
- u=0;
- }
復制代碼
所有資料51hei提供下載:
波形發生器.rar
(334.09 KB, 下載次數: 144)
2018-8-5 11:11 上傳
點擊文件名下載附件
|