显示函数和按键检测放在主循环里,因为中断随时在发生,按键检测和显示就经常被打断,按键有经常检测不到,显示有更新的话,变换很慢。而放在中断里的话,按键检测倒是没有问题,显示更新也快了,但是由于显示需要计算耗费不少时间,导致中断不准,输出波形也就变了。。。
单片机源程序如下:
- #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;
- }
-
- }
复制代码
|