找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3240|回复: 3
收起左侧

基于51单片机的电子琴设计(按键加预存歌曲)附PCB源程序

[复制链接]
ID:444375 发表于 2020-11-5 15:50 | 显示全部楼层 |阅读模式
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.png

Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
51hei.png 51hei.png

单片机源程序如下:
  1. #include <reg51.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. #define HALFF 460800      //11.9652MHZ晶振的半频率
  5. #define MAX 65536   //16位计数器最大计数次数
  6. #define LED P3              //小灯 P0
  7. #define input P1        //键盘  P1

  8. #define soo 784//中音'5'
  9. #define dao 523        //宏定义高音‘1’频率为1047Hz
  10. #define re 587
  11. #define mi 659
  12. #define fa 698
  13. #define so 784
  14. #define la 880
  15. #define xi 988

  16. sbit SPEAK = P2^3;          //蜂鸣器声音不怎么样,我们使用扬声器,接P2.3口
  17. sbit S1 = P3^3;
  18. uint C;              //定时器初始值定义
  19. bit flag=0;          //功能切换标志位
  20. uchar STH0;
  21. uchar STL0;
  22. uchar code lab[] = {dao,re,mi,fa,so,la,xi,soo,0XFF};
  23. void delay()
  24. {
  25.     uint i,j;
  26.     for(i=0; i<1000; i++)
  27.         for(j=0; j<120; j++);        //1ms
  28. }
  29. void DelayMs(uint n)   //误差 0us ,延时n毫秒
  30. {
  31.     uint a,b,c;
  32.     for(c=n; c>0; c--)
  33.         for(b=199; b>0; b--)
  34.             for(a=1; a>0; a--);
  35. }

  36. /******************************频率发生函数 定时器T0*******************/
  37. void t0() interrupt 1 using 1
  38. {
  39.     TH0 =STH0;
  40.     TL0 =STL0;
  41.     SPEAK = ~SPEAK;
  42. }
  43. void INT0_init(void) //定时器0初始化
  44. {
  45.     TMOD = 0x01;        //定时器T0用工作方式1(16位计数器)
  46.     EA = 1;         //开总中断
  47.     ET0 = 1;        //开定时器T0中断
  48.     TR0 = 0;    //T0停止运行状态
  49. }

  50. void play_song()  //《两只老虎》编曲
  51. {
  52.     uchar i,j;
  53.     uint code song[] = {dao,re,mi,dao,
  54.                         dao,re,mi,dao,
  55.                         mi,fa,so,
  56.                         mi,fa,so,
  57.                         so,la,so,fa,mi,dao,
  58.                         so,la,so,fa,mi,dao,
  59.                         re,soo,dao,
  60.                         re,soo,dao,
  61.                         0xff};        //以0xff为音符结束标志
  62.     //以下为每个音符节拍,4个延时单位为1拍
  63.     //'4'对应4个延时单位,'2'对应2个延时单位,'1'对应1个
  64.     uchar code JP[] = {4,4,4,4,
  65.                        4,4,4,4,
  66.                        4,4,8,
  67.                        4,4,8,
  68.                        3,1,3,1,4,4,
  69.                        3,1,3,1,4,4,
  70.                        4,4,8,
  71.                        4,4,8
  72.                       };
  73.     EA = 1;         //开总中断
  74.     ET0 = 1;        //开定时器T0中断
  75.     TMOD = 0x01;        //定时器T0用工作方式1(16位计数器)
  76.     while(!flag)
  77.     {
  78.         i = 0;
  79.         while(song[i] != 0xff)
  80.         {
  81.             C = HALFF/song[i];
  82.             STH0 = (MAX - C) / 256; // 高8位
  83.             STL0 = (MAX - C) % 256; // 低8位
  84.             TR0 = 1;                           //启动定时器

  85.             for(j=0; j<JP[i]; j++) //控制节拍
  86.                 delay();                   //延时1个延时单位
  87.             TR0 = 0;                           //关闭定时器
  88.             i++;                                   //播放下一个音符
  89.         }
  90.     }
  91. }

  92. void key_play()
  93. {
  94.     uchar temp;
  95.     uchar num;
  96.     input = 0xff;
  97.     if(input!=0xff)               //按键输入P1口
  98.     {
  99.         DelayMs(5);
  100.         if(input!=0xff)
  101.         {
  102.             temp = input;
  103.         }
  104.     }
  105.     switch(temp)
  106.     {
  107.     case 0xfe:
  108.         num=0;
  109.         break;
  110.     case 0xfd:
  111.         num=1;
  112.         break;
  113.     case 0xfb:
  114.         num=2;
  115.         break;
  116.     case 0xf7:
  117.         num=3;
  118.         break;
  119.     case 0xef:
  120.         num=4;
  121.         break;
  122.     case 0xdf:
  123.         num=5;
  124.         break;
  125.     case 0xbf:
  126.         num=6;
  127.         break;
  128.     case 0x7f:
  129.         num=7;
  130.         break;
  131.     default:
  132.         num=8;
  133.         break;
  134.     }
  135.     C = lab[num];   //定时器0的初值
  136.     if( C == 0XFF )
  137.     {
  138.         STH0 = (MAX - C) / 256; // 高8位
  139.         STL0 = (MAX - C) % 256; // 低8位
  140.         TR0 = 1;
  141. ……………………

  142. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
设计一 电子琴.rar (1014.66 KB, 下载次数: 56)

评分

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

查看全部评分

回复

使用道具 举报

ID:316613 发表于 2020-11-5 17:34 | 显示全部楼层
实测好像不大行,波形和频率显示都正常 但是蜂鸣器没有声音
51hei.png
回复

使用道具 举报

ID:583559 发表于 2020-11-22 12:14 | 显示全部楼层
用不了!
回复

使用道具 举报

ID:444375 发表于 2021-3-22 12:10 | 显示全部楼层
QEQWE123 发表于 2020-11-5 17:34
实测好像不大行,波形和频率显示都正常 但是蜂鸣器没有声音

看看电脑的仿真配置,有可能是电脑声音没开。我遇到过这个问题
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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