顯示函數和按鍵檢測放在主循環里,因為中斷隨時在發生,按鍵檢測和顯示就經常被打斷,按鍵有經常檢測不到,顯示有更新的話,變換很慢。而放在中斷里的話,按鍵檢測倒是沒有問題,顯示更新也快了,但是由于顯示需要計算耗費不少時間,導致中斷不準,輸出波形也就變了。。。
單片機源程序如下:
- #include <reg52.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar code Sin[]={"Sine "};
- uchar code Squ[]={"Square "} ;
- uchar code Tri[]={"Triangle "};
- uchar code No[]={"No Signal out "};
- uchar code Wave[]={"Wave: "};
- uchar code Fre[]={"f="};
- uchar code vpp1[]={"V="};
- uint vpp;
- uint freq;
- uchar i;
- sbit RS = P1^0; //數據/命令選擇端(H/L)
- sbit RW = P1^1; //數/寫選擇端(H/L)
- sbit EN = P1^2; //使能信號
- float k=0.4;
- uint peri=500;
- uchar key_wave=1;//鍵值
- unsigned long c;
- sbit key1=P2^0;//波形切換按鈕
- sbit key2=P2^1;//頻率加
- sbit key3=P2^2;//頻率減
- sbit key4=P2^3;//幅值加
- sbit key5=P2^4;//幅值減
- /**************定義數組產生正弦波 64個點******************/
- uchar code sine1[]=
- {
- 0x80,0x8d,0x99,0xa5,0xb1,0xbc,0xc7,0xd1,
- 0xda,0xe3,0xea,0xf1,0xf6,0xfa,0xfd,0xff,
- 0xff,0xff,0xfd,0xf9,0xf5,0xef,0xe9,0xe1,
- 0xd8,0xcf,0xc5,0xba,0xae,0xa2,0x96,0x89,
- 0x80,0x72,0x66,0x5a,0x4e,0x43,0x38,0x2e,
- 0x25,0x1c,0x15,0x0e,0x09,0x05,0x02,0x00,
- 0x00,0x00,0x02,0x06,0x0a,0x10,0x16,0x1e,
- 0x27,0x30,0x3a,0x45,0x51,0x5d,0x69,0x76
- };
- /**************定義數組產生方波 64個點******************/
- uchar code Square1[]=
- {
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- /**************定義數組產生三角波 64個點******************/
- uchar code Triangle1[]=
- {
- 0xff,0xf7,0xef,0xeb,0xde,0xd6,0xce,0xc5,
- 0xbd,0xb5,0xad,0xa4,0x9c,0x94,0x8c,0x84,
- 0x76,0x73,0x6b,0x63,0x5a,0x52,0x4a,0x42,
- 0x39,0x31,0x29,0x21,0x19,0x10,0x08,0x00,
- 0x00,0x08,0x10,0x19,0x21,0x29,0x31,0x39,
- 0x42,0x4a,0x52,0x5a,0x63,0x6b,0x73,0x76,
- 0x84,0x8c,0x94,0x9c,0xa4,0xad,0xb5,0xbd,
- 0xc5,0xce,0xd6,0xde,0xeb,0xef,0xf7,0xff
- };
- void Delayms(unsigned int n)
- {
- unsigned int i,j;
- for(j=n;j>0;j--)
- for(i=112;i>0;i--);
- }
- //………………………………定時器初始化…………………………………//
- void init_Timer0()
- {
- TMOD=0x22;
- TH0 = (unsigned int)(65536-peri)/256;
- TL0 = (unsigned int)(65536-peri)%256; //確定頻率
- TR0=1;
- ET0=1;
- EA=1;//開中斷
- }
- /***************************
- 測忙函數
- *************************/
- uchar Busy_Check()
- {
- uchar LCD_Status;
- RS=0; // 寄存器選擇
- RW=1; //讀狀態寄存器
- EN=1; // 開始讀
-
- Delayms(1);
- LCD_Status=P3;//P3作為輸出口
- EN=0;
- return LCD_Status;
- }
- /***************************
- 寫入字符
- *************************/
- void Write_LCD_Command(uchar cmd)
- {
- while((Busy_Check()&0x80)==0x80); //忙等待
- RS=0; //選擇命令寄存器
- RW=0; //寫
- EN=0;
- P3=cmd;
- EN=1;
- Delayms(1);
- EN=0;
- }
- /***************************
- 寫入數據
- *************************/
- void Write_LCD_Data(uchar dat)
- {
- while((Busy_Check()&0x80)==0x80); //忙等待
- RS=1;
- RW=0;
- EN=0;
- P3=dat;
- EN=1;
- Delayms(1);
- EN=0;
- }
- /***************************
- 初始化函數
- *************************/
- void Init_LCD()
- {
- Write_LCD_Command(0x38);
- Delayms(1);
- Write_LCD_Command(0x01); //清屏
- Delayms(1);
- Write_LCD_Command(0x06); //字符進入模式:屏幕不動,字符后移
- Delayms(1);
- Write_LCD_Command(0x0C); //顯示開、關光標
- Delayms(1);
- for (i=0;i<sizeof(Wave);i++)//----顯示WAVE:
- {
- Write_LCD_Data(Wave[i]);
- Delayms(1);
- }
- Write_LCD_Command(0x80+0x40);//----顯示freq:
- Delayms(1);
- for (i=0;i<sizeof(Fre);i++)
- {
- Write_LCD_Data(Fre[i]);
- Delayms(1);
- }
- Write_LCD_Command(0xc0+8);//----顯示vpp:
- Delayms(1);
- for (i=0;i<sizeof(vpp1);i++)
- Write_LCD_Data(vpp1[i]);
- Delayms(1);
-
-
-
- }
- /***************************
- 寫入頻率 成功
- *************************/
- void Write_freq(uint k)
- {
- uchar bai,shi,ge;
- bai=k/100%10;
- shi=k/10%10;
- ge=k%10;
- Write_LCD_Command(0xc0+2);
- Write_LCD_Data(0x30+bai);
- Write_LCD_Data(0x30+shi);
- Write_LCD_Data(0x30+ge);
- Write_LCD_Data(0x48);//代表H
- Write_LCD_Data(0x5a);//代表Z
- }
- /***************************
- 寫入幅值 成功
- *************************/
- void Write_vpp(uint u)
- {
- uchar Va,Vb,Vc,Vd;
- Va=1000*u/1000%10;
- Vb=1000*u/100%10;
- Vc=1000*u/10%10;
- Vd=1000*u%10;
- Write_LCD_Command(0xc0+10);//位置
- Write_LCD_Data(0x30+Va);
- Write_LCD_Data(0x30+Vb);
- Write_LCD_Data(0x30+Vc);
- Write_LCD_Data(0x30+Vd);
- Write_LCD_Data(0x6d);///顯示m
- Write_LCD_Data(0x56);///顯示V
- }
- /***************************
- lcd1602 頻率計算 成功
- *************************/
- void Xianshi()
- {
- freq=1/(64*peri*0.000001);
- Write_freq(freq);
- vpp=5*k;
- Write_vpp(vpp);
- }
- /***************************
- lcd1602 幅值計算幅值
- amplitude 成功
- *************************/
- void Write_wave(uchar t )
- {
- switch(t)
- {
- case 0:
- Write_LCD_Command(0x86);//定位
- for (i=0;i<sizeof(No);i++)
- {
- Write_LCD_Data(No[i]);//
- Delayms(1);
- }
- break;
- case 1:
- Write_LCD_Command(0x86);//定位
- Delayms(1);
- for (i=0;i<sizeof(Sin)-1;i++)
- {
- Write_LCD_Data(Sin[i]);
- Delayms(1);
- }
- break;
- case 2:
- Write_LCD_Command(0x86);//定位
- Delayms(1);
- for (i=0;i<sizeof(Squ)-1;i++)
- {
- Write_LCD_Data(Squ[i]);
- Delayms(1);
- }
-
- break;
- case 3:
- Write_LCD_Command(0x86);//定位
- Delayms(1);
- for (i=0;i<sizeof(Tri)-1;i++)
- {
- Write_LCD_Data(Tri[i]);
- Delayms(1);
- }
- break;
- }
- }
- void key()
- {
- if(key1==0)
- {
- Delayms(10);//延時消抖
- if(key1==0)
- {
- key_wave+=1;
- if(key_wave>3)
- {
- key_wave=1;
- }
- }
- while(!key1);
- }
- if(key2==0)
- {
- Delayms(10);//延時消抖
- if(key2==0)
- {
- peri+=50;
- if(peri>=781)
- {
- peri=781;
- }
- }
- while(!key2);
- }
- if(key3==0)
- {
- Delayms(10);//延時消抖
- if(key3==0)
- {
- peri-=50;
- if(peri<=31)
- {
- peri=31;
- }
- }
- while(!key3);
- }
- if(key4==0)
- {
- Delayms(10);//延時消抖
- if(key4==0)
- {
- k+=0.1;
- if(k>=1)
- {
- k=1;
- }
- }
- while(!key4);
- }
- if(key5==0)
- {
- Delayms(10);//延時消抖
- if(key5==0)
- {
- k-=0.1;
- if(k<=0)
- {
- k=0;
- }
- }
- while(!key5);
- }
- }
- void main()
- {
- Init_LCD(); //LCD初始化
- init_Timer0();//定時器初始化
-
- while(1)
- {
- key();
-
- Write_wave(key_wave);//顯示波形名字
- Xianshi();//顯示波形大小
-
- }
- }
- void Time0_isr(void) interrupt 1 //定時中斷
- {
- TH0 = (unsigned int)(65536-peri)/256;
- TL0 = (unsigned int)(65536-peri)%256; //確定頻率
- // key();
- c++;
- if(c>=64)
- c=0;
- switch(key_wave)
- //根據輸出哪種波形,從P0口向DAC0832送數字量
-
- {
-
- //無輸出
- case 0:
- P0=0x00;
- break;
- //正弦波
- case 1:
- P0=k*sine1[c];
- break;
- //方波
- case 2:
- P0=k*Square1[c];
- break;
- //三角波
- case 3:
- P0=k*Triangle1[c];
- break;
- }
-
- }
復制代碼
|