用到了數碼管顯示,矩陣鍵盤,蜂鳴器,適合新接觸51的朋友們,只是程序,一看就明白 c語言程序
單片機源程序如下:
- /*********************************************************************************************
- 程序名: 8鍵電子琴C程序
- 編寫人: 杜洋
- 編寫時間: 2009年5月18日
- 硬件支持: STC系列單片機 12MHz
- 接口說明:
- 修改日志:
- NO.1-
- /*********************************************************************************************
- 說明:
- /*********************************************************************************************/
- #include <at89x52.h>
- #define uchar unsigned char
-
- #define KEY P3
- #define LED P1
- sbit dula=P2^6; //段選信號的鎖存器控制
- sbit wela=P2^7; //位選信號的鎖存器控制
- sbit SPEAKER = P2^3;
- bit flag; //標志音樂輸出腳電平的高低
- uchar ptr = 0x00; //取音符
- uchar high; //計數器高位
- uchar low; //計數器低位
- unsigned char KeyValue;
- unsigned char KeyValue2;
- unsigned char STH0;
- unsigned char STL0;
- unsigned char i;
- unsigned char lednum=0;
- /*unsigned int code tab[]={
- 64021,64103,64260,64400,//低音3開始
- 64524,64580,64684,64777,
- 64820,64898,64968,65030,
- 65058,65110,65157,65178
- }; */
- unsigned int code tab[]={
- /*10000,64103,64260,64400,//低音3開始 */
- 64580,64633,64684,64732,
- 64777,64820,64860,64898,
- 64934,64968,64994,65030
- };
- unsigned int code music[] ={
- 4 ,6 ,8, 9 ,11,13,15
- };
- unsigned char code music2[] = {
- // 1 _ 1_ 1 .5
- 0xFC,0x44,0x7F, 0xFC,0x44,0x7F, 0xFC,0x44,0xFF, 0xFA,0x68,0xFF,
- // 3 _ 3_ 3 1
- 0xFD,0x23,0x7F, 0xFD,0x23,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
- // 1_ 3_ 5 5
- 0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFD,0x82,0xFF, 0xFD,0x82,0xFF,
- // 4_ 3_ 2 -
- 0xFD,0x23,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFF,0xFF,0xFF,
- // 2_ 3_ 4 4
- 0xFC,0xAC,0x7F, 0xFD,0x23,0x7F, 0xFD,0x34,0xFF, 0xFD,0x34,0xFF,
- // 3_ 2_ 3 1
- 0xFD,0x23,0x7F, 0xFC,0xAC,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
- // 1_ 3_ 2 .5
- 0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFA,0x68,0xFF,
- // .7_ 2_ 1 -
- 0xFC,0x0C,0x7F, 0xFC,0xAC,0x7F, 0xFC,0x44,0xFF, 0xFF,0xFF,0xFF,
- 0x00//結束
- };
- unsigned char code music_num[] ={
- 1,20,1,20,1,1,5,5,
- 3,20,3,20,3,3,1,1,
- 1,20,3,20,5,5,5,5,
- 4,20,3,20,2,19,2,19,
- 2,20,3,20,4,4,4,4,
- 3,20,2,20,3,3,1,1,
- 1,20,3,20,2,2,5,5,
- 7,20,2,20,1,19,1,19} ;
- unsigned int code key_num[] ={1,1,2,2,3,4,4,5,5,6,6,7
- } ;
- unsigned int code key2_num[] ={0,16,1,16,2,3,16,4,16,5,16,6
- } ;
- /*unsigned int code twotiger[] ={
- 1,2,3,1,1,2,3,1,3,4,5,5,3,4,5,5,5,6,5,4,3,3,1,1,5,6,
- 5,4,3,3,1,1,2,2,5,5,1,1,0,0,2,2,5,5,1,1,0,0 };
- unsigned int code twotiger2[] = {
- 1,1,5,5,6,6,5,5,4,4,3,3,2,2,1,1 ,5 ,5,4,4,3,3,2,2,5
- ,5,4,4,3,3,2,2,1,1,5,5,6,6,5,5,4,4,3,3,2,2,1,1
- }; */
- unsigned char code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
- 0x00,0x76,0x40,0x40,0x08};
- //0-F,,,19,,20的碼表
- unsigned char code numb[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
- unsigned char i3; //0-7數碼管
- void Init(void); //初始化函數
- void DelayMs(unsigned int time); //毫秒級延時函數
- /*void Delay (unsigned int a);*/
- void newmusic(void);
- void keyy(void);
- void led8(void);
- void main(void){
-
- TMOD=0x01;
- ET0=1;
- EA=1;
- KEY = 0xf0;
- LED=0xff;
- while(1){
- KeyValue=15;
-
- if(KEY != 0xf0){
- DelayMs(10);//?óê±10ms??DD????
- if(KEY!=0xf0)//?ù′??ì2a?ü?ìê?·?°′??
- {
- KEY=0X0F;
- switch(KEY)
- {
- case(0X0e): KeyValue=0;LED=0xfe;break;
- case(0X0d): KeyValue=1;LED=0xfd;break;
- case(0X0b): KeyValue=2;LED=0xfb;break;
- case(0X07): KeyValue=3;LED=0xf7;break;
- }
- //2aê?DD
- KEY=0XF0;
- switch(KEY)
- {
- case(0Xe0): KeyValue=KeyValue;break;
- case(0Xd0): KeyValue=KeyValue+4;break;
- case(0Xb0): KeyValue=KeyValue+8;break;
- case(0X70): KeyValue=KeyValue+12;break;
- }
- } }
-
- if( KeyValue<12){
-
-
-
- high=tab[KeyValue]/256;
- low=tab[KeyValue]%256;
- TR0=1;
- led8();
-
- }
- else if(KeyValue==12)
- {KeyValue=0;
- while(KeyValue!=12){
- keyy();
- if (KeyValue2==15){KeyValue=0;break;}
- else if (KeyValue2==0){break;}
-
- high=tab[KeyValue]/256;
- low=tab[KeyValue]%256;
- TR0=1;
- DelayMs(160);
-
- led8();
- SPEAKER = 1;
- TR0=0;
- DelayMs(600);
- KeyValue++;
-
- }} //按鍵1遍歷12個音
-
-
-
- else if(KeyValue==13)
- {i=0 ;
- while(i!=7){
-
- keyy();
- if (KeyValue2==15){i=0;break;}
- else if (KeyValue2==0){break;}
- KeyValue=music[i]-4 ;
-
- high=tab[KeyValue]/256;
- low=tab[KeyValue]%256;
- TR0=1;
- DelayMs(160);
- led8();
- SPEAKER = 1;
- TR0=0;
- DelayMs(600);
- i++;
- }}//按鍵0遍歷7個音
- else if(KeyValue==14)
- {
- newmusic();
- }//按鍵3播放音樂
- else{
- SPEAKER = 1; //按鍵4復位
- TR0=0;}
-
-
-
- }
- }
- /*void t0(void) interrupt 1 using 0{
- TH0=STH0;
- TL0=STL0;
- SPEAKER=~SPEAKER;
- } */
- /*********************************************************************************
- * 名稱:Count1(void) interrupt 1
- * 功能:設置計時器0 溢出中斷,每中斷一次改變P2_3 引腳電平
- *********************************************************************************/
- void Count1(void) interrupt 1
- {
- TH0 = high;
- TL0 = low;
- if (flag == 0) //改變P2_3 引腳電平
- {
- SPEAKER = 0;
- flag = 1;
- }
- else
- {
- SPEAKER = 1;
- flag = 0;
- }
- }
- /*************************************************************
- * 杜洋工作室 DoYoung Studio
- * 與電子愛好者同行 www.DoYoung.net
- 音樂播放
- /*************************************************************/
- void newmusic()
- {
- uchar time;
- Init();
- TH0 = high;
- TL0 = low;
- while (1)
- {
- if (music2[ptr] != 0xFF && music2[ptr] != 0x00)//判斷是否是正常音符
- { keyy();
- if (KeyValue2==15){ptr=0;break;}
- else if (KeyValue2==0){break;}
- TR0 = 0;
- SPEAKER = 1;
- DelayMs(10); //間歇
- TR0 = 1;
- high = music2[ptr]; //取設置頻率數值的高8 位
- low = music2[ptr + 1]; //取設置頻率數值的低8 位
- time = music2[ptr + 2]; //取發聲時間
-
- for(i3=0;i3<40;i3++){
- P0=num[music_num[lednum]];
- dula=1;
- dula=0;
-
- P0=numb[0]; //選中第一個數碼管
- wela=1;
- wela=0;
- DelayMs(1);
-
- P0=num[music_num[lednum+1]];
- dula=1;
- dula=0;
- P0=numb[1]; //選中第2個數碼管
- wela=1;
- wela=0;
- DelayMs(1);
- }
- P0=num[16]; //什么都不顯示的代碼
- dula=1;
- dula=0;
-
- DelayMs(time);
- ptr += 3;
- lednum+=2;
- }
- else if (music2[ptr] == 0xFF) //判斷是否是休止符
- {
- time = music2[ptr + 2];
- DelayMs(time);
- ptr += 3;
- lednum+=2;
- }
- else //結束符,停止2 秒后繼續
- {
- TR0 = 0;
- SPEAKER = 1;
- DelayMs(1000);
- ptr = 0;
- lednum=0;
- }
- }
- }
- /*******************************************
- ms延時*/
- void DelayMs(unsigned int time)
- {
- unsigned int i;
- unsigned int j;
- for (j =0; j < time; j++) //每個循環 約 3ms
- {
- for (i =0; i < 363; i++)
- {;}
- }
- }
- /***************************************延時
- ***************************************/
- /*void Delay (unsigned int a){ //需要輸入變量值0~65535
- unsigned int i;
- while( --a != 0){ //i 從0加到600,CPU大概就耗時1毫秒
- for(i = 0; i < 87; i++); //空指令循環
- }
- }*/
- /*******************************/
- void Init()
- {
- TMOD = 0x01; //定時器0 處于計時方式,16 位
- EA = 1;
- ET0 = 1; //定時器0 溢出中斷
- }
- /*******************************/
- void keyy()
- {
- KEY = 0xf0;
- if(KEY != 0xf0){
- DelayMs(10);//?óê±10ms??DD????
- if(KEY!=0xf0)//?ù′??ì2a?ü?ìê?·?°′??
- { KEY=0X0F;
- switch(KEY)
- {
- case(0X0e): KeyValue2=0;break;
- case(0X0d): KeyValue2=1;break;
- case(0X0b): KeyValue2=2;break;
- case(0X07): KeyValue2=3;break;
- }
- //2aê?DD
- KEY=0XF0;
- switch(KEY)
- {
- case(0Xe0): KeyValue2=KeyValue2;break;
- case(0Xd0): KeyValue2=KeyValue2+4;break;
- case(0Xb0): KeyValue2=KeyValue2+8;break;
- case(0X70): KeyValue2=KeyValue2+12;break;
- }
-
-
- } }
- }
- /*******************************************************/
- void led8() { for(i3=0;i3<50;i3++){
- P0=num[key_num[KeyValue]];
- dula=1;
- dula=0;
-
- P0=numb[0]; //選中第一個數碼管
- wela=1;
- wela=0;
- DelayMs(1);
-
- P0=num[key2_num[KeyValue]+1];
- dula=1;
- dula=0;
- P0=numb[1]; //選中第2個數碼管
- wela=1;
- wela=0;
- DelayMs(1);
- }
- P0=num[16]; //什么都不顯示的代碼
- dula=1;
- dula=0;
-
- }
復制代碼
所有資料51hei提供下載:
8鍵電子琴.rar
(23.08 KB, 下載次數: 48)
2018-12-7 21:34 上傳
點擊文件名下載附件
應該是16鍵 下載積分: 黑幣 -5
|