#include<REG52.H> sbit speaker=P3^1; //無源蜂鳴器 #define KeyPort P1 //按鍵 ////////////////////////////////////////////// unsigned char timer0h,timer0l,time; //timer0h,timer0l為定時器T1的高低位初值,time為對應的節拍時間 unsigned char key_num; signed int fre; //對應頻率數據表的地址 void delay(unsigned char t); //延時子函數,控制發音的時間長度 void delayms(unsigned int t); //普通延時子程序,可用于按鍵消抖 // 頻率-半周期數據表 高八位 共保存了四個八度的28個頻率數據 unsigned char code FREQH[]={ 0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低音1234567 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, //1,2,3,4,5,6,7,i 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, //高音 234567 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF}; //超高音 1234567 // 頻率-半周期數據表 低八位 unsigned char code FREQL[]={ 0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6, //低音1234567 0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i 0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D, //高音 234567 0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16}; //超高音 1234567 sbit smg=P3^0; unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//數碼管字符碼0-9 unsigned char High,Low; //定時器預裝值的高8位和低8位 void display(unsigned char n) //顯示函數 { smg=0; //選中1位 P2=table[n]; //P0口輸出數字碼,顯示十位數 delayms(5); //延時5ms } /* 按鍵處理 */ void KEY() { switch(KeyPort) //對按鍵進行處理 { case 0xfe:key_num= 1;display(1);break; //分別對應不用的音調 case 0xfd:key_num= 2;display(2);break; case 0xfb:key_num= 3;display(3);break; case 0xf7:key_num= 4;display(4);break; case 0xef:key_num= 5;display(5);break; case 0xdf:key_num= 6;display(6);break; case 0xbf:key_num= 7;display(7);break; case 0x7f:key_num= 8;display(8);break; default:key_num= 0;break; } if(key_num==0) { TR1=0; } else { TR1=1; High=FREQH[key_num+6]; //從數據表中讀出頻率數值,實際上是定時的時間長度 Low=FREQL[key_num+6]; } } /* 主函數 */ void main(void) { TMOD=0x11; //T0 T1 均在工作方式1 ET1=1; //T1開中斷 EA=1; //開總中斷 while(1) { KEY(); //按鍵處理函數 } } void delayms(unsigned int t) //MS延時子程序 { unsigned int i,j; for(i=0;i<t;i++) { for(j=0;j<123;j++) ; } } /* 定時器T1中斷子程序 */ void Timer1_isr(void) interrupt 3 { speaker=!speaker; //輸出方波, 發音 TH1=High; TL1=Low; } /* end */
|