找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 9965|回复: 4
打印 上一主题 下一主题
收起左侧

基于51单片机的简易电子琴源码

[复制链接]
跳转到指定楼层
楼主
用到了数码管显示,矩阵键盘,蜂鸣器,适合新接触51的朋友们,只是程序,一看就明白  c语言程序

单片机源程序如下:
  1. /*********************************************************************************************
  2. 程序名:    8键电子琴C程序
  3. 编写人:    杜洋 
  4. 编写时间:  2009年5月18日
  5. 硬件支持:  STC系列单片机 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;                //段选信号的锁存器控制
  18. sbit wela=P2^7;                //位选信号的锁存器控制
  19. sbit SPEAKER  = P2^3;
  20. bit flag; //标志音乐输出脚电平的高低
  21. uchar ptr = 0x00; //取音符
  22. uchar high; //计数器高位
  23. uchar low; //计数器低位

  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//结束
  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数码管
  90. void Init(void); //初始化函数
  91. void DelayMs(unsigned int time); //毫秒级延时函数
  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个音
  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个音
  180.                 else if(KeyValue==14)
  181.                                 {       
  182.                                 newmusic();
  183.                                 }//按键3播放音乐
  184.                 else{
  185.                                         SPEAKER = 1;        //按键4复位
  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. * 功能:设置计时器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]; //取设置频率数值的高8 位
  238.                         low = music2[ptr + 1]; //取设置频率数值的低8 位
  239.                         time = music2[ptr + 2]; //取发声时间
  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];           //选中第一个数码管
  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个数码管
  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 //结束符,停止2 秒后继续
  275.                 {
  276.                         TR0 = 0;
  277.                         SPEAKER = 1;
  278.                         DelayMs(1000);
  279.                         ptr = 0;
  280.                         lednum=0;
  281.                 }
  282.         }
  283. }
  284. /*******************************************

  285. ms延时*/
  286. void DelayMs(unsigned int time)
  287. {
  288.         unsigned int i;
  289.         unsigned int j;
  290.         for (j =0; j < time; j++) //每个循环 约 3ms
  291.         {
  292.                 for (i =0; i < 363; i++)
  293.                 {;}
  294.         }
  295. }
  296. /***************************************延时
  297. ***************************************/
  298. /*void Delay (unsigned int a){                                //需要输入变量值0~65535
  299.                 unsigned int i;
  300.                 while( --a != 0){                                        //i 从0加到600,CPU大概就耗时1毫秒
  301.                                 for(i = 0; i < 87; i++);        //空指令循环               
  302.                 }
  303. }*/
  304. /*******************************/
  305. void Init()
  306. {
  307.         TMOD = 0x01; //定时器0 处于计时方式,16 位
  308.         EA = 1;
  309.         ET0 = 1; //定时器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];           //选中第一个数码管
  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个数码管
  354.                         wela=1;
  355.                         wela=0;
  356.                         DelayMs(1);
  357.                         }
  358.                         P0=num[16];          //什么都不显示的代码
  359.                         dula=1;
  360.                         dula=0;
  361.                                
  362. }
复制代码

所有资料51hei提供下载:
8键电子琴.rar (23.08 KB, 下载次数: 48)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:628657 发表于 2019-10-23 09:28 | 只看该作者
好的,不错
回复

使用道具 举报

板凳
ID:628657 发表于 2019-10-23 10:20 | 只看该作者
能有proteus的图就好了
回复

使用道具 举报

地板
ID:646626 发表于 2019-11-21 16:55 | 只看该作者

你的可以用吗
回复

使用道具 举报

5#
ID:954889 发表于 2021-7-20 11:17 | 只看该作者
感谢楼主

(%JGI8TZOYTWB7%TQ)}9(HE.png (94.63 KB, 下载次数: 34)

没有数码管,但可以放音乐

没有数码管,但可以放音乐
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表