程序大致可以實現定時刻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(); }

|