基于51单片机的电子琴完整版
#include #include #define uint unsigned int #define uchar unsigned char sbit feng = P0^7; // 蜂鸣器 uint FTemp; uint code tab[] = { //定时半周期的初始值 64021,64103,64260,64400, //低音3 4 5 6 64524,64580,64684,64777, //低音7,中音1 2 3 64820,64898,64968,65030, //中音4 5 6 7 65058,65110,65157,65178}; //高音1 2 3 4 //用扫描法读 P1 外接 4×4 键盘 uchar Keyscan(void) { uchar i, j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7}; for(j = 0; j < 4; j++) //循环四次,扫描四行 { P1 = Buffer[j]; //在低四位分别输出一个低电平 _nop_(); temp = 0x80; //计划先读出P1.7位 for(i = 0; i < 4; i++) //循环四次,检查四列 { if(!(P1& temp)) //从高四位,截取1位 { return (i + j * 4); //返回取得的按键值 } temp >>= 1; //换右边一位 } } return 16; //没有键按下就返回16 } void Main(void) { uchar Key_Value = 16, Key_Temp1, Key_Temp2;//读出的键值 TMOD = 0x01; //T0定时方式1 ET0 = 1; //允许T0中断 EX0 = 1; //允许INT0中断 EA = 1;//开总中断 while(1) { TR0 = 0; //T0工作停,暂不发音 Key_Temp1 = Keyscan(); //第一次读入按键 if(Key_Temp1 != 16) { //有键按下 Key_Temp2 = Keyscan(); //再读一次 if (Key_Temp1 == Key_Temp2) //两次相等 { Key_Value = Key_Temp1; //就确认下来 FTemp = tab[Key_Value]; //根据键值,取出定时半周期的初始值 TR0 = 1; //启动定时器T0,发音 while (Keyscan() < 16); //等待释放 feng = 1; //停止发音 } } } } //============================================================== void T0_INT(void) interrupt 1 { TL0 = FTemp; //载入定时半周期的初始值 TH0 = FTemp >> 8; feng = ~feng; //发音 因篇幅问题不能全部显示,请点此查看更多更全内容