找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 10506|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

基于51單片機(jī)的簡(jiǎn)易電子琴源碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
用到了數(shù)碼管顯示,矩陣鍵盤,蜂鳴器,適合新接觸51的朋友們,只是程序,一看就明白  c語言程序

單片機(jī)源程序如下:
  1. /*********************************************************************************************
  2. 程序名:    8鍵電子琴C程序
  3. 編寫人:    杜洋 
  4. 編寫時(shí)間:  2009年5月18日
  5. 硬件支持:  STC系列單片機(jī) 12MHz
  6. 接口說明:    
  7. 修改日志:  
  8.   NO.1-                                                               
  9. /*********************************************************************************************
  10. 說明:

  11. /*********************************************************************************************/

  12. #include <at89x52.h>
  13. #define uchar unsigned char
  14.        
  15. #define KEY  P3
  16. #define LED  P1
  17. sbit dula=P2^6;                //段選信號(hào)的鎖存器控制
  18. sbit wela=P2^7;                //位選信號(hào)的鎖存器控制
  19. sbit SPEAKER  = P2^3;
  20. bit flag; //標(biāo)志音樂輸出腳電平的高低
  21. uchar ptr = 0x00; //取音符
  22. uchar high; //計(jì)數(shù)器高位
  23. uchar low; //計(jì)數(shù)器低位

  24. unsigned char KeyValue;
  25. unsigned char KeyValue2;
  26. unsigned char STH0;
  27. unsigned char STL0;
  28. unsigned char i;
  29. unsigned char lednum=0;
  30. /*unsigned int code tab[]={
  31. 64021,64103,64260,64400,//低音3開始
  32. 64524,64580,64684,64777,
  33. 64820,64898,64968,65030,
  34. 65058,65110,65157,65178
  35. }; */
  36. unsigned int code tab[]={
  37. /*10000,64103,64260,64400,//低音3開始          */
  38. 64580,64633,64684,64732,
  39. 64777,64820,64860,64898,
  40. 64934,64968,64994,65030
  41. };
  42. unsigned int code music[] ={
  43. 4 ,6 ,8, 9 ,11,13,15
  44. };
  45. unsigned char code music2[] = {
  46. // 1 _ 1_ 1 .5
  47. 0xFC,0x44,0x7F, 0xFC,0x44,0x7F, 0xFC,0x44,0xFF, 0xFA,0x68,0xFF,
  48. // 3 _ 3_ 3 1
  49. 0xFD,0x23,0x7F, 0xFD,0x23,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
  50. // 1_ 3_ 5 5
  51. 0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFD,0x82,0xFF, 0xFD,0x82,0xFF,
  52. // 4_ 3_ 2 -
  53. 0xFD,0x23,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFF,0xFF,0xFF,
  54. // 2_ 3_ 4 4
  55. 0xFC,0xAC,0x7F, 0xFD,0x23,0x7F, 0xFD,0x34,0xFF, 0xFD,0x34,0xFF,
  56. // 3_ 2_ 3 1
  57. 0xFD,0x23,0x7F, 0xFC,0xAC,0x7F, 0xFD,0x23,0xFF, 0xFC,0x44,0xFF,
  58. // 1_ 3_ 2 .5
  59. 0xFC,0x44,0x7F, 0xFD,0x23,0x7F, 0xFC,0xAC,0xFF, 0xFA,0x68,0xFF,
  60. // .7_ 2_ 1 -
  61. 0xFC,0x0C,0x7F, 0xFC,0xAC,0x7F, 0xFC,0x44,0xFF, 0xFF,0xFF,0xFF,
  62. 0x00//結(jié)束
  63. };
  64. unsigned char code music_num[] ={
  65. 1,20,1,20,1,1,5,5,
  66. 3,20,3,20,3,3,1,1,
  67. 1,20,3,20,5,5,5,5,
  68. 4,20,3,20,2,19,2,19,
  69. 2,20,3,20,4,4,4,4,
  70. 3,20,2,20,3,3,1,1,
  71. 1,20,3,20,2,2,5,5,
  72. 7,20,2,20,1,19,1,19}  ;
  73. unsigned int code key_num[] ={1,1,2,2,3,4,4,5,5,6,6,7
  74. } ;
  75. unsigned int code key2_num[] ={0,16,1,16,2,3,16,4,16,5,16,6
  76. } ;
  77. /*unsigned int code twotiger[] ={
  78. 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,
  79. 5,4,3,3,1,1,2,2,5,5,1,1,0,0,2,2,5,5,1,1,0,0 };
  80. unsigned int code twotiger2[] =        {
  81. 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
  82. ,5,4,4,3,3,2,2,1,1,5,5,6,6,5,5,4,4,3,3,2,2,1,1
  83. };        */
  84. unsigned char code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
  85.                         0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,
  86.                                                 0x00,0x76,0x40,0x40,0x08};
  87.                                                 //0-F,,,19,,20的碼表

  88. unsigned char code numb[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
  89. unsigned char i3;                                                //0-7數(shù)碼管
  90. void Init(void); //初始化函數(shù)
  91. void DelayMs(unsigned int time); //毫秒級(jí)延時(shí)函數(shù)
  92. /*void Delay (unsigned int a);*/
  93. void newmusic(void);
  94. void keyy(void);
  95. void led8(void);
  96. void main(void){
  97.        
  98.         TMOD=0x01;
  99.         ET0=1;
  100.         EA=1;
  101.         KEY = 0xf0;
  102.         LED=0xff;
  103.         while(1){
  104.         KeyValue=15;       
  105.                
  106.         if(KEY != 0xf0){
  107.         DelayMs(10);//?óê±10ms??DD????
  108.         if(KEY!=0xf0)//?ù′??ì2a?ü?ìê?·?°′??
  109.                 {
  110.                 KEY=0X0F;
  111.                 switch(KEY)
  112.                         {
  113.                                 case(0X0e):        KeyValue=0;LED=0xfe;break;
  114.                                 case(0X0d):        KeyValue=1;LED=0xfd;break;
  115.                                 case(0X0b): KeyValue=2;LED=0xfb;break;
  116.                                 case(0X07):        KeyValue=3;LED=0xf7;break;
  117.                         }
  118.                         //2aê?DD
  119.                         KEY=0XF0;
  120.                         switch(KEY)
  121.                         {
  122.                                 case(0Xe0):        KeyValue=KeyValue;break;
  123.                                 case(0Xd0):        KeyValue=KeyValue+4;break;
  124.                                 case(0Xb0): KeyValue=KeyValue+8;break;
  125.                                 case(0X70):        KeyValue=KeyValue+12;break;
  126.                                 }
  127.                                  }         }
  128.                
  129.                 if( KeyValue<12){
  130.                        
  131.                        
  132.                    
  133.                         high=tab[KeyValue]/256;
  134.                     low=tab[KeyValue]%256;
  135.                     TR0=1;
  136.                         led8();
  137.                        
  138.                          }

  139.                 else if(KeyValue==12)  
  140.                                  {KeyValue=0;
  141.                                   while(KeyValue!=12){


  142.                                   keyy();
  143.                                  if (KeyValue2==15){KeyValue=0;break;}
  144.                                  else if (KeyValue2==0){break;}
  145.                                   
  146.                                          high=tab[KeyValue]/256;
  147.                                     low=tab[KeyValue]%256;
  148.                                     TR0=1;
  149.                                         DelayMs(160);

  150.                                        
  151.                                 led8();

  152.                                         SPEAKER = 1;
  153.                                         TR0=0;
  154.                                         DelayMs(600);
  155.                                         KeyValue++;
  156.                                                  
  157.                                                 }} //按鍵1遍歷12個(gè)音
  158.                
  159.                
  160.        
  161.                 else if(KeyValue==13)
  162.                 {i=0 ;
  163.                 while(i!=7){
  164.        
  165.                 keyy();
  166.                                  if (KeyValue2==15){i=0;break;}
  167.                                  else if (KeyValue2==0){break;}
  168.                 KeyValue=music[i]-4 ;

  169.                

  170.                 high=tab[KeyValue]/256;
  171.             low=tab[KeyValue]%256;
  172.             TR0=1;
  173.                 DelayMs(160);
  174.                 led8();
  175.                 SPEAKER = 1;
  176.                 TR0=0;
  177.                 DelayMs(600);
  178.                 i++;

  179.                 }}//按鍵0遍歷7個(gè)音
  180.                 else if(KeyValue==14)
  181.                                 {       
  182.                                 newmusic();
  183.                                 }//按鍵3播放音樂
  184.                 else{
  185.                                         SPEAKER = 1;        //按鍵4復(fù)位
  186.                                         TR0=0;}
  187.                                
  188.            
  189.                
  190.    }
  191. }
  192. /*void t0(void) interrupt 1 using 0{
  193.   TH0=STH0;
  194.   TL0=STL0;
  195.   SPEAKER=~SPEAKER;
  196. } */
  197. /*********************************************************************************
  198. * 名稱:Count1(void) interrupt 1
  199. * 功能:設(shè)置計(jì)時(shí)器0 溢出中斷,每中斷一次改變P2_3 引腳電平
  200. *********************************************************************************/
  201. void Count1(void) interrupt 1
  202. {
  203.         TH0 = high;
  204.         TL0 = low;
  205.         if (flag == 0) //改變P2_3 引腳電平
  206.         {
  207.                 SPEAKER = 0;
  208.                 flag = 1;
  209.         }
  210.         else
  211.         {
  212.                 SPEAKER = 1;
  213.                 flag = 0;
  214.         }
  215. }
  216. /*************************************************************
  217. * 杜洋工作室 DoYoung Studio
  218. * 與電子愛好者同行 www.DoYoung.net
  219. 音樂播放
  220. /*************************************************************/
  221. void newmusic()
  222. {
  223.         uchar time;
  224.         Init();
  225.         TH0 = high;
  226.         TL0 = low;
  227.         while (1)
  228.         {
  229.                 if (music2[ptr] != 0xFF && music2[ptr] != 0x00)//判斷是否是正常音符
  230.                 {                 keyy();
  231.                                  if (KeyValue2==15){ptr=0;break;}
  232.                                  else if (KeyValue2==0){break;}          
  233.                         TR0 = 0;
  234.                         SPEAKER = 1;
  235.                         DelayMs(10); //間歇
  236.                         TR0 = 1;
  237.                         high = music2[ptr]; //取設(shè)置頻率數(shù)值的高8 位
  238.                         low = music2[ptr + 1]; //取設(shè)置頻率數(shù)值的低8 位
  239.                         time = music2[ptr + 2]; //取發(fā)聲時(shí)間
  240.                        
  241.                                  for(i3=0;i3<40;i3++){
  242.                         P0=num[music_num[lednum]];          
  243.                         dula=1;
  244.                         dula=0;
  245.                        
  246.                         P0=numb[0];           //選中第一個(gè)數(shù)碼管
  247.                         wela=1;
  248.                         wela=0;
  249.                         DelayMs(1);
  250.                                
  251.                         P0=num[music_num[lednum+1]];          
  252.                         dula=1;
  253.                         dula=0;
  254.                         P0=numb[1];           //選中第2個(gè)數(shù)碼管
  255.                         wela=1;
  256.                         wela=0;
  257.                         DelayMs(1);
  258.                         }
  259.                         P0=num[16];          //什么都不顯示的代碼
  260.                         dula=1;
  261.                         dula=0;

  262.                        
  263.                         DelayMs(time);
  264.                         ptr += 3;
  265.                         lednum+=2;
  266.                 }
  267.                 else if (music2[ptr] == 0xFF) //判斷是否是休止符
  268.                 {
  269.                         time = music2[ptr + 2];
  270.                         DelayMs(time);
  271.                         ptr += 3;
  272.                         lednum+=2;
  273.                 }

  274.                 else //結(jié)束符,停止2 秒后繼續(xù)
  275.                 {
  276.                         TR0 = 0;
  277.                         SPEAKER = 1;
  278.                         DelayMs(1000);
  279.                         ptr = 0;
  280.                         lednum=0;
  281.                 }
  282.         }
  283. }
  284. /*******************************************

  285. ms延時(shí)*/
  286. void DelayMs(unsigned int time)
  287. {
  288.         unsigned int i;
  289.         unsigned int j;
  290.         for (j =0; j < time; j++) //每個(gè)循環(huán) 約 3ms
  291.         {
  292.                 for (i =0; i < 363; i++)
  293.                 {;}
  294.         }
  295. }
  296. /***************************************延時(shí)
  297. ***************************************/
  298. /*void Delay (unsigned int a){                                //需要輸入變量值0~65535
  299.                 unsigned int i;
  300.                 while( --a != 0){                                        //i 從0加到600,CPU大概就耗時(shí)1毫秒
  301.                                 for(i = 0; i < 87; i++);        //空指令循環(huán)               
  302.                 }
  303. }*/
  304. /*******************************/
  305. void Init()
  306. {
  307.         TMOD = 0x01; //定時(shí)器0 處于計(jì)時(shí)方式,16 位
  308.         EA = 1;
  309.         ET0 = 1; //定時(shí)器0 溢出中斷
  310. }

  311. /*******************************/
  312. void keyy()
  313. {
  314.         KEY = 0xf0;
  315.         if(KEY != 0xf0){
  316.                         DelayMs(10);//?óê±10ms??DD????
  317.                         if(KEY!=0xf0)//?ù′??ì2a?ü?ìê?·?°′??
  318.                 {         KEY=0X0F;
  319.                 switch(KEY)
  320.                         {
  321.                                 case(0X0e):        KeyValue2=0;break;
  322.                                 case(0X0d):        KeyValue2=1;break;
  323.                                 case(0X0b): KeyValue2=2;break;
  324.                                 case(0X07):        KeyValue2=3;break;
  325.                         }
  326.                         //2aê?DD
  327.                         KEY=0XF0;
  328.                         switch(KEY)
  329.                         {
  330.                                 case(0Xe0):        KeyValue2=KeyValue2;break;
  331.                                 case(0Xd0):        KeyValue2=KeyValue2+4;break;
  332.                                 case(0Xb0): KeyValue2=KeyValue2+8;break;
  333.                                 case(0X70):        KeyValue2=KeyValue2+12;break;
  334.                                 }
  335.                                
  336.                
  337.                                  }         }
  338. }
  339. /*******************************************************/
  340. void led8()           {           for(i3=0;i3<50;i3++){
  341.                         P0=num[key_num[KeyValue]];          
  342.                         dula=1;
  343.                         dula=0;
  344.                        
  345.                         P0=numb[0];           //選中第一個(gè)數(shù)碼管
  346.                         wela=1;
  347.                         wela=0;
  348.                         DelayMs(1);
  349.                                
  350.                         P0=num[key2_num[KeyValue]+1];          
  351.                         dula=1;
  352.                         dula=0;
  353.                         P0=numb[1];           //選中第2個(gè)數(shù)碼管
  354.                         wela=1;
  355.                         wela=0;
  356.                         DelayMs(1);
  357.                         }
  358.                         P0=num[16];          //什么都不顯示的代碼
  359.                         dula=1;
  360.                         dula=0;
  361.                                
  362. }
復(fù)制代碼

所有資料51hei提供下載:
8鍵電子琴.rar (23.08 KB, 下載次數(shù): 48)


評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:628657 發(fā)表于 2019-10-23 09:28 | 只看該作者
好的,不錯(cuò)
回復(fù)

使用道具 舉報(bào)

板凳
ID:628657 發(fā)表于 2019-10-23 10:20 | 只看該作者
能有proteus的圖就好了
回復(fù)

使用道具 舉報(bào)

地板
ID:646626 發(fā)表于 2019-11-21 16:55 | 只看該作者

你的可以用嗎
回復(fù)

使用道具 舉報(bào)

5#
ID:954889 發(fā)表于 2021-7-20 11:17 | 只看該作者
感謝樓主

(%JGI8TZOYTWB7%TQ)}9(HE.png (94.63 KB, 下載次數(shù): 35)

沒有數(shù)碼管,但可以放音樂

沒有數(shù)碼管,但可以放音樂
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表