找回密码
 立即注册

QQ登录

只需一步,快速开始

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

帮我看看at89c51单片机电子琴,只能发出哆啦咪达四个音,剩下四个不发音

[复制链接]
跳转到指定楼层
楼主
ID:986113 发表于 2021-11-30 19:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include<AT89X52.h>
  2. #define SPK P0_0 //定义方波输出口
  3. #define LED P1_1
  4. #define shumaguan P0 //定义数码管段码输出
  5. unsigned int tone1,tone2;
  6. /*****标准音符表*****/
  7. //用于使定时器初值变化以产生相应频率的定时
  8. unsigned char code yinfu[]={
  9. 0xfb,0xe9, //Do
  10. 0xfc,0x5c, //Re
  11. 0xfc,0xc1, //Mi
  12. 0xfc,0xef, //Fa
  13. 0xfd,0x45, //So
  14. 0xfd,0x92, //La
  15. 0xfd,0xd0, //Si
  16. 0xfd,0xee, //Do#
  17. 0xfa,0x14, //So低
  18. 0xfa,0xb9, //La低
  19. 0xfb,0x4d, //Si低
  20. 0x00,0x00 //音符之间的间隔,只要间隔时间小于65ms时,
  21. //喇叭不会发出声音,用作拍子之间的短暂停顿
  22. };
  23. /*****军港之夜音调表*****/
  24. unsigned char code shengri_tone[]={9,3,3,1,2,3,2,3,3,10,9,1,2,1,3,5,5,3,6,5,3,
  25. 3,3,2,1,2,3,2,3,11,9,10,11,10,1,11,3,3,11,10,11,10,11,3,3,11,
  26. 11,10,11,10,2,10,1,11,10,9,10,9,3,5,5,3,6,5,6,5,3,5,3,1,3,3,3,5,
  27. 3,5,5,3,3,2,3,2,11,10,11,10,9,3,3,5,5,3,6,5,6,5,3,5,3,1,3,
  28. 3,5,3,5,5,3,3,3,2,3,2,11,10,11,10,9,1 //0代表不发声,即停顿;数字即为音调
  29. };
  30. /*****军港之夜节拍表*****/
  31. unsigned char code shengri_beat[]={24,24,24,24,12,12,48,24,48,24,24,12,12,86,24,24,24,24,24,48,24,
  32. 48,12,12,24,12,12,86,48,24,24,12,12,48,24,24,24,24,24,12,12,72,24,24,24,24,
  33. 24,12,12,48,24,12,12,24,24,12,12,86,24,24,24,24,24,12,12,48,12,24,12,24,12,12,12,48,
  34. 24,24,24,24,24,12,12,48,24,12,12,24,24,86,24,24,24,24,24,12,12,48,12,24,12,24,24,
  35. 24,72,24,24,24,12,12,24,12,12,48,24,12,12,24,24,86 //节拍,即tone表各音调的延时
  36. };
  37. /*****自动演示音调表*****/
  38. unsigned char code yanshi_tone[]={ 1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,
  39. 8,0,7,0,6,0,5,0,4,0,3,0,2,0,1,0
  40. };
  41. /*****自动演示节拍表*****/
  42. unsigned char code yanshi_beat[]={ 48,1,48,1,48,1,48,1,48,1,48,1,48,1,48,2,
  43. 48,1,48,1,48,1,48,1,48,1,48,1,48,1,48,2
  44. };
  45. /*****15ms延时子程序,用于节拍*****/
  46. void delay(void)
  47. {
  48. unsigned char n=50;
  49. while(n--)
  50. {
  51. unsigned char i;
  52. for(i=0;i<125;i++);
  53. }
  54. }
  55. /*****定时器0初始化*****/
  56. void initTimer(void)
  57. {
  58. TMOD=0x01; //定时器0,工作方式1;定时器1,工作方式1
  59. TH0=tone1;
  60. TL0=tone2;
  61. }
  62.           void timer0(void) interrupt 1
  63. {
  64. TH0=tone1;
  65. TL0=tone2;
  66. SPK=~SPK; //取反,以产生方波
  67. }
  68. /*****演奏子程序1*****/
  69. void play1(void)
  70. {
  71. unsigned char m=0;
  72. unsigned char s;
  73. unsigned char a=1;
  74. while(1)
  75. {
  76. EA=0;
  77. LED=0;
  78. a=shengri_tone[m]; //取音符
  79. s=shengri_beat[m]; //取节拍
  80. tone1=yinfu[2*a-2];
  81. tone2=yinfu[2*a-1];
  82. EA=1;
  83. while(s--)
  84. {
  85. delay();
  86. }
  87. LED=1;
  88. m++;
  89. if(m>=119) return; //数值是shengri相关表中的元素数量
  90. }
  91. }
  92. /*****演奏子程序2*****/
  93. void play2(void)
  94. {
  95. unsigned char m=0;
  96. unsigned char s;
  97. unsigned char a=1;
  98. while(1)
  99. {
  100. EA=0;
  101. LED=0;
  102. a=yanshi_tone[m];
  103. s=yanshi_beat[m];
  104. tone1=yinfu[2*a-2];
  105. tone2=yinfu[2*a-1];
  106. EA=1;
  107. while(s--)
  108. {
  109. delay();
  110. }
  111. LED=1;
  112. m++;
  113. if(m>=32) return;
  114. }
  115. }
  116. /*****按键检测*****/
  117. void check_key(void)
  118. {
  119. P2=0xff;
  120. P3=0xff; //设置为输入状态
  121. switch(P2) //检测按键,输出数码管、载入定时器初值、允许中断
  122. {
  123. case 0xfe:shumaguan=0xF9;tone1=0xfb;tone2=0x90;EA=1;break;
  124. case 0xfd:shumaguan=0xA4;tone1=0xfc;tone2=0xc;EA=1;break;
  125. case 0xfb:shumaguan=0xB0;tone1=0xfc;tone2=0x7b;EA=1;break;
  126. case 0xf7:shumaguan=0x99;tone1=0xfc;tone2=0xad;EA=1;break;
  127. case 0xef:shumaguan=0x92;tone1=0xfd;tone2=0xa;EA=1;break;
  128. case 0xdf:shumaguan=0x82;tone1=0xfd;tone2=0x5d;EA=1;break;
  129. case 0xbf:shumaguan=0xF8;tone1=0xfd;tone2=0xa7;EA=1;break;
  130. case 0x7f:play1();break;
  131. default: EA=0;SPK=0;shumaguan=0xff;//如果没有键按下则关闭中断和数码管
  132. }
  133. switch(P3)
  134. {
  135. case 0xfe:shumaguan=0x79;tone1=0xfd;tone2=0xc8;EA=1;break;
  136. case 0xfd:shumaguan=0x24;tone1=0xfe;tone2=0x6;EA=1;break;
  137. case 0xfb:shumaguan=0x30;tone1=0xfe;tone2=0x3e;EA=1;break;
  138. case 0xf7:shumaguan=0x19;tone1=0xfe;tone2=0x57;EA=1;break;
  139. case 0xef:shumaguan=0x12;tone1=0xfe;tone2=0x85;EA=1;break;
  140. case 0xdf:shumaguan=0x02;tone1=0xfe;tone2=0xaf;EA=1;break;
  141. case 0xbf:shumaguan=0x78;tone1=0xfe;tone2=0xd4;EA=1;break;
  142. case 0x7f:play2();break;
  143. default: EA=0;SPK=0;shumaguan=0xff;//如果没有键按下则关闭中断和数码管
  144. }
  145. }
  146. /*****主程序*****/
  147. void main(void)
  148. {
  149. initTimer();
  150. // shumaguan=0xff;
  151. TR0=1;
  152. ET0=1;
  153. SPK=0;
  154. while(1)
  155. {
  156. check_key();
  157. }
  158. }
复制代码


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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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