程序大致可以实现定时刻PWM输出功能,但有一个缺点:输出的波形不稳定,在数码管上显示是不是出现跳码。跪求大神指点。
#include<reg51.h> #define uchar unsigned char #define uint unsigned int sbit PWM=P2^1; sbit alarm=P1^7; //高电平时闹钟响 sbit selecta=P2^4; sbit selectb=P2^5; sbit selectc=P2^6; sbit select=P2^7; //只需要第一段,第二段和第六段亮,即 uchar Keystate; uchar buffer[]={0,0,0,0,0}; uint a,b; uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴数码管代码 uchar Overflow=0;//定时溢出次数 uchar minute,second;//定义倒计时变量 //ms延时函数 void delayms(uint x) { uint i; while(x--) for(i=0;i<1000;i++); } void delay(uint x) { uchar j; while(x--)for(j=0;j<5;j++); } //数码管显示函数 void display() { uchar s,k; buffer[0]=minute/10; buffer[1]=minute%10; buffer[2]=second/10; buffer[3]=second%10; buffer[4]=b%10; for(k=0;k<5;k++) { s=k; switch(k) { case 0:selecta=0;selectb=1;selectc=0; break; case 1: selecta=1;selectb=1;selectc=0; break; case 2: selecta=0;selectb=0;selectc=1; break; case 3: selecta=1;selectb=0;selectc=1; break; case 4:selecta=1;selectb=1;selectc=1; break; } P0=table[buffer]; delay(3); } }//要实现动态显示 //本程序需要用到两个定时器,两个中断 void KeyScan(); void main() { P2=0x00; a=0; b=5; minute=30; second=0; RD=0; select=1; TMOD=0x11; TH0=(65536-10)/256; TL0=(65536-10)%256; EA=1; IT1=1; IT0=1; EX1=1; EX0=1; PX1=1; KeyScan(); TR1=1; ET1=1; while(1) { display(); delay(10); } } void X1_INT()interrupt 2 { if(b>0) b--; else b=9; } void X0_INT()interrupt 0 { b++; if(b>9) b=0; } void time1() interrupt 3 { TL1=(65536-10)%256; TH1=(65536-10)/256; a++; if(a==10) a=0; if(a<b) PWM=1; else PWM=0; } void timer0start()//定时器初始化函数 { TH0=(65536-50000)/256; //定时器定时为50ms,晶振的周期为12MHz TL0=(65536-50000)%256; ET0=1; //定时器1中断开 TR0=1; //定时器1开 } //闹铃函数 需要输出声音悦耳 void beef() { uchar x=100; while(x--) { alarm=!alarm; delayms(10); } alarm=0; } //定时器0中断函数程序 void time0()interrupt 1 { TH0=(65536-50000)/256; TL0=(65536-50000)%256; if(Overflow==20) { Overflow=0; if(second==0) { if(minute==0) { beef(); minute=0; second=0; while(1); } else minute--; second=59; } else second--; } else Overflow++; } //按键扫描函数 void KeyScan() { uint x=1000; while(x--) { P1=0xff; Keystate=P1&0x03; display(); delay(50); if(Keystate!=0x03) { delayms(2); //去抖 if(Keystate!=0x03)//去抖后再确认一下 { delayms(1); switch(Keystate) { case 0x01:minute++; if(minute==60)minute=0; break; case 0x02:minute--; if(minute==0)minute=59; break; default:break; } while(P1!=0xff)display(); //松手检测并保证可以从循环中出来 } } } timer0start(); }
|