找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7087|回复: 5
收起左侧

单片机八音盒程序和与仿真原理图

[复制链接]
ID:393359 发表于 2018-11-29 00:48 | 显示全部楼层 |阅读模式
八音盒程序和与原理图见附件
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png

单片机源程序如下:
  1. #include <reg52.h>
  2. #include<intrins.h>
  3. #define uhar unsigned char
  4. #define uint  unsigned int
  5. sbit key1=P3^2;//定义按key1可切换花样                                                                  
  6. sbit key2=P3^3;//定义按key2可切换歌曲
  7. sbit fm=P3^5;//蜂鸣器连续的IO口,接蜂鸣器的管脚
  8. sbit rs=P2^0;
  9. sbit rw=P2^1;
  10. sbit ep=P2^2;
  11. uchar i;
  12. uchar Tong_index=0;//音乐片段索引音符索引
  13. uchar song_index=0;
  14. uchar *discode;//暂存LCD需要显示的歌名
  15. uchar *song_Tone,*song_Time;
  16. uchar code dis1[]={"song1"};//第一首歌名,dis1~dis4位LCD第一行要显示的歌名;
  17. uchar code dis2[]={"song2"};
  18. uchar code dis3[]={"song3"};
  19. uchar code dis4[]={"song4"};
  20. uchar code dis[]={"K1:Down K2:Up"};        //第二行显示的内容
  21. uint code Tong_tab[]={62018,62401,62491,62895,63184,63441,63506,63773,
  22. 63965,64137,64215,64360,64488,64603,64654,64751,64836,64876,64948,65012,65067,65535};                                                                 
  23. //---------------------------简谱---------------------------------------
  24. //编程规则:字节高位是简谱,低位是持续时间,代表多少个十六分音符。
  25. //1-7代表中央C调,8-E代表高八度,0代表停顿
  26. //最后的0是结束标志
  27. //uchar code song1_Tone[]={         //        歌曲1的演奏音符
  28. //11,9,11,14,12,14,12,11,11,7,8,9,8,7,8,
  29. //11,9,11,14,13,12,14,11,11,7,8,9,6,7,
  30. //12,14,14,13,12,13,14,12,13,14,12,12,11,10,7,8,
  31. //11,9,11,14,13,12,14,11,11,8,9,10,6,7,0xff};//结束标志
  32. //uchar code song1_Time[]={ // 歌曲1的节拍频率
  33. //4,2,2,8,4,2,2,8,4,2,2,4,2,2,12,
  34. //4,2,2,4,2,4,4,8,4,2,2,4,2,12,
  35. //4,4,8,4,2,2,8,2,2,2,2,2,2,2,2,16,
  36. //4,2,2,4,2,4,4,8,4,2,2,4,2,12,0xff};
  37. //uchar code song2_Tone[]={         //        歌曲2的演奏音符
  38. //7,8,9,7,7,8,9,7,9,10,11,9,10,11,
  39. //11,12,11,10,9,7,11,12,11,10,9,7,7,4,7,7,4,7,0xff};//结束标志
  40. //uchar code song2_Time[]={ // 歌曲2的节拍频率
  41. //4,4,4,4,4,4,4,4,4,4,8,4,4,8,
  42. //2,2,2,2,4,4,2,2,2,2,4,4,4,4,8,4,4,8,0xff};       
  43. //uchar code song3_Tone[]={         //        歌曲3的演奏音符
  44. //7,7,7,8,9,9,9,9,10,11,12,12,11,10,9,11,11,8,9,7,
  45. //7,7,7,8,11,9,9,9,10,11,12,12,11,10,9,11,11,8,9,7,0xff};//结束标志
  46. //uchar code song3_Time[]={ // 歌曲3的节拍频率
  47. //2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,
  48. //2,2,2,2,4,2,2,2,2,4,2,2,2,2,4,2,2,2,2,5,0xff};
  49. //uchar code song4_Tone[]={         //        歌曲4的演奏音符
  50. //5,9,9,9,9,8,7,8,7,6,5,12,12,12,12,12,11,
  51. //2,11,11,10,9,9,12,12,11,9,8,7,8,7,6,5,9,
  52. //2,7,7,6,5,9,8,7,6,4,12,0xff};//结束标志
  53. //uchar code song4_Time[]={ // 歌曲4的节拍频率
  54. //2,2,2,2,2,2,2,2,2,2,8,2,2,2,2,4,2,
  55. //2,2,2,2,8,2,2,2,2,4,2,2,2,2,2,4,2,
  56. //2,2,2,2,4,2,2,2,2,2,8,0xff};

  57. void delayms(uint ms)
  58. {
  59.          uchar a;
  60.          while(ms--)
  61.                  {
  62.                  for(a=230;a>0;a--);
  63.                  }

  64. }
  65. uchar Busy_Check(void)//测试LED忙碌状态
  66. {
  67.         uchar LCD_Status;
  68.         rs=0;
  69.         rw=1;
  70.         ep=1
  71.         _nop_();
  72.          _nop_();
  73.          _nop_();
  74.          _nop_();
  75.          LCD_Status=P0&0x80;
  76.          ep=0;
  77.          return LCD_Status;
  78. }
  79. void led_wemd(uchar cmd)//写入指令数据到LCD
  80. {
  81.         while(Busy_Check());
  82.                 rs=0;
  83.                 rw=0;
  84.                 ep=0;
  85.                 _nop_()
  86.                 _nop_()
  87.                 P0=cmd;
  88.                 _nop_()
  89.                 _nop_()
  90.                 _nop_()
  91.                 _nop_()
  92.                 ep=1;
  93.                 _nop_()
  94.                 _nop_()
  95.                 _nop_()
  96.                 _nop_()
  97.                 ep=0;
  98. }
  99. void lcd_pos(uchar pos)
  100. {
  101.         lcd_wcmd(pos|0x80);
  102. }
  103. void lcd_wdat(uchar dat)
  104.   {
  105.         while(Busy_Check());
  106.                 rs=0;
  107.                 rw=0;
  108.                 ep=0;
  109.                 _nop_()
  110.                 _nop_()
  111.                 P0=cmd;
  112.                 _nop_()
  113.                 _nop_()
  114.                 _nop_()
  115.                 _nop_()
  116.                 ep=1;
  117.                 _nop_()
  118.                 _nop_()
  119.                 _nop_()
  120.                 _nop_()
  121.                 ep=0;
  122. }
  123. void lcd_init(void) //lcd初始化设定
  124. {
  125. lcd_wcmd(0x38); //设置显示格式为16*2行显示,5*8点阵,8位

  126. delay(1);
  127. lcd_wcmd(0x0C);        //0x0c-显示开关设置
  128. delay(1);
  129. lcd_wcmd(0x06);        //0x06读写后指针+1
  130. delay(1);
  131. lcd_wcmd(0x01);//清除lcd显示内容
  132. }
  133. //----------------------------简谱音调对应的定时器初值---------------------------
  134. //适合11.0592M的晶振,对定时器置入的初值
  135. uchar code cuzhi[]={
  136.          0xff,0xff,//占位用的,没有实际的意义
  137.          0xFC,0x8E,//中央C调1-7
  138.          0xFC,0xED,       
  139.          0xFD,0x43,       
  140.          0xFD,0x6A,       
  141.          0xFD,0xB3,       
  142.          0xFD,0xF3,       
  143.          0xFE,0x2D,
  144.          0xFE,0x47,        //高八度1-7          
  145.          0xFE,0x76,
  146.          0xFE,0xA1,
  147.          0xFE,0xC7,       
  148.          0xFE,0xD9,
  149.          0xFE,0xF9,
  150.          0xFF,0x16
  151.          };
  152. uchar yinyue[]={0xff,0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x0,0x0};
  153. //将音调转化为对应的LED样式
  154. void delay1(uint z);        //延时1MS
  155. void delay(uint z);        //延时165MS,即十六分音符
  156. void song();
  157. void beep();//蜂鸣器叫一声

  158. void int0() interrupt 0
  159. {
  160. delayms(100);
  161. if(INT0==0)
  162.         {
  163.                 TR0=0;
  164.                 if(song_index>5)
  165.                 {
  166.                 song_index=5;
  167.                 }
  168.                  else{song_index++;}
  169.                  if(song_index==1)
  170.                  {temp=songl[i];discode=dis2;}
  171.                  if(song_index==2)
  172.                  {temp=song2[i];discode=dis3;}
  173.                  if(song_index==3)
  174.                  {temp=song3[i];discode=dis4;}
  175.                  if(song_index==4)
  176.                  {temp=song4[i];discode=dis1;song_index=0;}
  177.                  TR0=1;
  178.                  i=0;
  179.         }
  180. }
  181. void int1() interrupt 2  //外部中断1
  182. {
  183.   delayms(100);
  184. if(INT1==0)
  185.         {
  186.                 TR1=0;
  187.                 if(song_index<1)
  188.                 {
  189.                 song_index=0;
  190.                 }
  191.                  else{song_index--;}
  192.                  if(song_index==1)
  193.                  {temp=song[i];discode=dis2;}
  194.                  if(song_index==2)
  195.                  {temp=song2[i];discode=dis3;}
  196.                  if(song_index==3)
  197.                  {temp=song3[i];discode=dis4;}
  198.                  if(song_index==4)
  199.                  {temp=song4[i];discode=dis1;song_index=0;}
  200.                  TR0=1;
  201.                  i=0;
  202.         }
  203. }

  204. //---------------.按照51单片机的中断向量顺序编的号,也是缺省状态下的优先级------------
  205. //外部中断0 interrupt 0
  206. //定时器0     interrupt 1
  207. //外部中断1 interrupt 2
  208. //定时器1     interrupt 3
  209. //串口中断   interrupt 4
  210. //定时器2     interrupt 5
  211. void timer0() interrupt 1         //用于产生各种音调 定时器0
  212. {
  213.         TH0=Tone_tab[Tone_index]/256;//重置T0定时初值
  214.         TL0=Tone_tab[Tone_index]%256;
  215.         fm=~fm;
  216. }
  217. void LCD_disp(void)
  218. {
  219.         uchar i;
  220.         lcd_pos(0);
  221.         i=0;
  222.         while(discode!='\0')
  223.         {
  224.                 lcd_wdat(discode[i]);
  225.                 i++;
  226.         }
  227.         lcd_pos(0x40);
  228.         i=0;
  229.         while(dis[i]!='\0')
  230.         {
  231.         lcd_wdat(dis[i]);
  232.         i++;
  233.         }
  234. }
  235. void int_init(void)
  236. {
  237. TMOD=0x01;
  238. ET0=1;//允许Timer0中断
  239. EX0=1;//允许INT0中断
  240. IT0=1; //INT0为边沿触发
  241. EX1=1;
  242. IT1=1;
  243. EA=1;
  244. TR0=0; //Timer0停止
  245. }
  246. void main(void)
  247. {
  248. int_init();
  249. song_Tone=song1_Tone;
  250. song_Time=song1_Time;
  251. discode=dis1;
  252. lcd_init();
  253.         while(1)
  254.         {
  255.                 LCD_disp();
  256.                 Tone_index=song_Tone[i];
  257.                 if(Tone_index==0xFF)
  258.                 {
  259.                         i=0;
  260.                         TR0=0;
  261.                 }
  262.                 TR0=1;
  263.                 delayms(song_Time[Tone_index]*60);
  264.                 TR0=0
  265.                 i++
  266.         }                                
  267. }
复制代码

所有资料51hei提供下载:
《流水灯音乐盒》.rar (806.82 KB, 下载次数: 84)
回复

使用道具 举报

ID:433094 发表于 2018-11-29 20:04 | 显示全部楼层
感谢分享
回复

使用道具 举报

ID:861347 发表于 2020-12-16 14:53 | 显示全部楼层
这个程序有错误呀
回复

使用道具 举报

ID:865583 发表于 2020-12-22 16:35 | 显示全部楼层
故意改错。。。
回复

使用道具 举报

ID:864339 发表于 2020-12-23 18:03 | 显示全部楼层
这个是电子琴吗
回复

使用道具 举报

ID:907317 发表于 2021-7-3 15:16 | 显示全部楼层
程序全是错误  改完都够我再编两个的了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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