找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机电子琴设计(可显示光敏、温度、日期)

[复制链接]
跳转到指定楼层
楼主
51单片机电子琴设计(可显示光敏、温度、日期)

作者:林宏伟   学校:shaoguandada   时间:2019/11/26

首先,看图:下面这张图是基于51单片机设计的基础要求,一共是10个小课题,难度的话,初步认为是半颗星,说难不算难,说简单确实很简单,这对于那些有基础的同学而言轻松,基本几个小时就搞定了。


编号
项目名称
要求
学号
1
基于DS1302的电子万年历设计
1、电子万年历功能;2、可设置三组以上的闹钟;3、温度检测功能;4、倒计时功能
学号尾数为1
2
简易数字电压表
1、可检测显示05V的直流电压;2、可检测环境光照功能,将系统工作环境的光线分为强、中、弱三个等级并在液晶上显示。
学号尾数为2
3
数控电压源设计
1、可输出05V的直流电压。直流电压的大小用键盘设置确定,精度为0.1V2、可输出正弦波、方波和三角波。波形的频率不限,但是幅度可在1~5V之间用键盘设置, 精度为0.1V
学号尾数为3
4
环境温度、光照检测报警系统设计
1、检测显示当前的环境温度和光线强度。2、键盘设置温度和光强的上限与下限值,如果温度与光强超出界限值,则蜂鸣器发出警报。同时液晶显示警报的类型。
学号尾数为4
5
多功能电子琴设计
1、高、中、低音调选择功能;2、手动演奏功能;3、至少能自动演奏一首歌曲;4、完美的中文操作界面。
学号尾数为5
6
多功能电子计算器设计
1、基本的加减乘除运算功能;2、乘方、开方运算;3、三角函数运算;4十进制、二进制、十六进制转换功能。
学号尾数为6
7
基于单片机的数字钟设计
file:///C:\Users\LITTLE~1\AppData\Local\Temp\ksohtml84440\wps1.jpg1、时分秒显示;2、时分秒可以现场键盘设置;3、断电后下一次通电时,时钟能在原来的基础上继续运行;4、温度检测显示;5、秒表功能
学号尾数为7
8
基于LCD图像显示的数字钟设计
1、 利用LCD图型模式,编程实现时钟功能。显示模式参考图如右图所示。
2、键盘实时调整时钟数据
学号尾数为8
9
英文记事本设计
1、开机密码设置功能。系统通电后,要输入6位的密码才能进入系统。3、进入系统后,可以输入英文文章。即系统按键具有数字、标点符号、大小写字母、空格,回车等字符输入功能。4、附加功能。进入系统后,密码可以用按键更改;输入的文章,液晶界面显示满之后,能够分页切换,并且具有保存、清楚功能。
学号尾数为9
0
PWM信号发生器设计
1、利用单片机控制DA转换器,变出控制输出两路相位相反的PWM信号;2PWM信号的幅度可在0.1V~5V之间用键盘按照0.1V的分辨率任意设定;3PWM的展空比,可在1%~99%之间,按照1%的精度,用键盘设定控制;4PWM的频率,可在10100Hz之间,按照1Hz的分辨率,任意设定。
学号尾数为0


1.首先,讲一下思路,这些基础要求其实用一块板就可以实现全部,因为是设计,设计要求电路板是自己焊接,不能买现成的,这对很多小可爱来说是一件十分痛苦的事情,下面是我自己的电路图,遵循简单化原则,尽量把电路精简


(1)原理图



(2)PCB图




(3)实物图

(1)LCD12864模块 :这个模块的通信方式有两种,一种是并行,一种是串行,并行虽然网上历程很多,但是焊接电路时候却很多线,于是我对这个模块的硬件图进行了修改,把并行改成串行,修改硬件图,这样就不用模块的引脚,下面是这个模块的部分说明:   我采用短接J2,这样PSB这个引脚就可以丢掉了,我再短接了背光电源和供电电源,这样就并行,总体这个模块就只需要用三条线,供电2条,数据线3条。无需多余的线路了,十分精简。

特色:(1)模组背部自带 10K 3*3 硬封可调电位器,可以调到
理想对比度
(2)LED 背光极性可调,JP4 为液晶背光正负反接处,此模组
背光为 4 颗 LED 灯,非普通背光
(3)模组自带原装三星正品防静电电容,抗干扰性更强 C6 C7
C8
(4)串并口可通过两种方式调节 1 PSB 脚控制 2 JP2 短路到+
为并口 短路到-为串口
(5)自改 3.3V 可通过 JP3 调节,默认接+级为 5V,接-为 3.3V,
C4 C5 加极性电容即可 型号
为 106A 14FH4,背光电阻 33 欧改成 3.3 欧


(4)LCD12864硬件修改和电路板布局

(2)DS18B20模块,这个模块是温度传感器,这个不需要修改什么,直接使用就行了

(3)DS1302模块    同上,注意副电源是否需要

(4)其他模块,不多解释了,模块只需要看网上使用手册就行了

2.如何实现上面的功能?

这块板可以实现的功能有:显示温度、光敏值、时间、独立按键可用、矩阵按键可用。

(1)矩阵按键驱动程序:这个采用最最基础的扫描程序,还有状态机、翻转两种,比较高阶,如果是新手就建议不要采用(怕看不懂)

  1. void Keyscan(void)
  2. {
  3.         unsigned char temp;
  4.         P2=0xfe;                                        //第一行置低
  5.         temp=P2;                                           //将P2口的值赋给temp
  6.         temp=temp&0xf0;                                //将temp跟1111 0000 按位与
  7.         if(temp!=0xf0)
  8.         {
  9.                 delay1ms(10);
  10.                 temp=P2;
  11.                 temp=temp&0xf0;
  12.                 if(temp!=0xf0)
  13.                 {
  14.                         temp=P2;
  15.                         switch(temp)
  16.                         {
  17.                                 case 0xee:
  18.                                 key=0;
  19.                                 break;

  20.                                 case 0xde:
  21.                                 key=1;
  22.                                 break;

  23.                                 case 0xbe:
  24.                                 key=2;
  25.                                 break;

  26.                                 case 0x7e:
  27.                                 key=3;
  28.                                 break;
  29.                         }
  30.                         while(temp!=0xf0)
  31.                         {
  32.                                 temp=P2;
  33.                                 temp=temp&0xf0;
  34.                         }
  35.                 }
  36.         }

  37.         P2=0xfd;                                        //第二行置低
  38.         temp=P2;                                           //将P2口的值赋给temp
  39.         temp=temp&0xf0;                                //将temp跟1111 0000 按位与
  40.         if(temp!=0xf0)
  41.         {
  42.                 delay1ms(10);
  43.                 temp=P2;
  44.                 temp=temp&0xf0;
  45.                 if(temp!=0xf0)
  46.                 {
  47.                         temp=P2;
  48.                         switch(temp)
  49.                         {
  50.                                 case 0xed:
  51.                                 key=4;
  52.                                 break;

  53.                                 case 0xdd:
  54.                                 key=5;
  55.                                 break;

  56.                                 case 0xbd:
  57.                                 key=6;
  58.                                 break;

  59.                                 case 0x7d:
  60.                                 key=7;
  61.                                 break;
  62.                         }
  63.                         while(temp!=0xf0)
  64.                         {
  65.                                 temp=P2;
  66.                                 temp=temp&0xf0;
  67.                         }
  68.                 }
  69.         }

  70.         P2=0xfb;                                        //第二行置低
  71.         temp=P2;                                           //将P2口的值赋给temp
  72.         temp=temp&0xf0;                                //将temp跟1111 0000 按位与
  73.         if(temp!=0xf0)
  74.         {
  75.                 delay1ms(10);
  76.                 temp=P2;
  77.                 temp=temp&0xf0;
  78.                 if(temp!=0xf0)
  79.                 {
  80.                         temp=P2;
  81.                         switch(temp)
  82.                         {
  83.                                 case 0xeb:
  84.                                 key=8;
  85.                                 break;

  86.                                 case 0xdb:
  87.                                 key=9;
  88.                                 break;

  89.                                 case 0xbb:
  90.                                 key=10;
  91.                                 break;

  92.                                 case 0x7b:
  93.                                 key=11;
  94.                                 break;
  95.                         }
  96.                         while(temp!=0xf0)
  97.                         {
  98.                                 temp=P2;
  99.                                 temp=temp&0xf0;
  100.                         }
  101.                 }
  102.         }

  103.         P2=0xf7;                                        //第二行置低
  104.         temp=P2;                                           //将P2口的值赋给temp
  105.         temp=temp&0xf0;                                //将temp跟1111 0000 按位与
  106.         if(temp!=0xf0)
  107.         {
  108.                 delay1ms(10);
  109.                 temp=P2;
  110.                 temp=temp&0xf0;
  111.                 if(temp!=0xf0)
  112.                 {
  113.                         temp=P2;
  114.                         switch(temp)
  115.                         {
  116.                                 case 0xe7:
  117.                                 key=12;
  118.                                 break;

  119.                                 case 0xd7:
  120.                                 key=13;
  121.                                 break;

  122.                                 case 0xb7:
  123.                                 key=14;
  124.                                 break;

  125.                                 case 0x77:
  126.                                 key=15;
  127.                                 break;
  128.                         }
  129.                         while(temp!=0xf0)
  130.                         {
  131.                                 temp=P2;
  132.                                 temp=temp&0xf0;
  133.                         }
  134.                 }
  135.         }
  136. }
复制代码
(2)DS18B20驱动程序

  1. #include "DS18B20.h"

  2.         
  3. uchar dis1[16];



  4. /*---------------以下为18B20相关函数-----------------------------*/
  5. /******************************************************************
  6. 函数名称:void delay (uint x)
  7. 功能说明:若机器周期为1us,则本延时程序为延时 4*x(us)
  8. ******************************************************************/
  9. void delay (uint x) //本板延时8us
  10. {
  11.      while (--x);
  12. }

  13. /*****************************************************************
  14. 函数名称:uchar bus_rest(void)
  15. 功能说明:产生单总线系统信号的总线复位信号,并返回
  16. 总线上是否存在单总线器件信息
  17. ******************************************************************/
  18. uchar bus_rest(void)
  19. {
  20.      uchar presence;
  21.      DQ=0; //将DQ信号线拉低
  22.      delay(29); //持续48US
  23.      DQ=1; //释放总线
  24.      delay(3); //等待从设备将总线拉低
  25.      presence=DQ; //保存当前总线状态
  26.      delay(25); //等待总线初始化过程结束
  27.      return presence;//返回是否有从设备将总线拉低

  28. }

  29. /****************************************************************
  30. 函数名称:uchar r_1820BYTE(void)
  31. 功能说明:向单总线读取一个数据字节
  32. *****************************************************************/
  33. uchar r_1820BYTE(void)
  34. {
  35.       uchar i=0;
  36.       uchar date = 0;
  37.       for (i=8;i>0;i--)
  38.       {
  39.           DQ = 0; // 将DQ信号线拉低启动读时隙
  40.           DQ=1;// 释放总线,等待从机动车辆返回数据位
  41.           delay(1); //越接近15us越好; 准备采样总线上的信号
  42.           date>>=1 ;
  43.           if (DQ)
  44.                date=date|0x80;
  45.           delay(6);
  46.        }
  47.        return(date);
  48. }

  49. /*****************************************************************
  50. 函数名称:void w_1280Byte(uchar bytevalue)
  51. 功能说明:向单总线写一个数据字节
  52. ******************************************************************/
  53. void w_1280Byte(uchar bytevalue)
  54. {
  55.      uchar i;
  56.      for(i=0;i<8;i++)
  57.      {
  58.          DQ=0; // 将DQ信号线拉低启动读时隙
  59.          DQ=bytevalue&0x01; //
  60.          delay(5);//等待写时隙结束
  61.          DQ=1; //释放
  62.          bytevalue>>=1;
  63.      }
  64.      delay(5); ////等待写时隙结束
  65. }
  66. /*****************************************************************
  67. 函数名称:uint read_T(void)
  68. 功能说明:读取1820温度
  69. *******************************************************************/
  70. uint read_T(void)
  71. {
  72.      uchar a=0;
  73.      uchar b=0;
  74.      uint t=0;
  75.      bus_rest();
  76.      w_1280Byte(0xCC); // 跳过读序号列号的操作 ;
  77.      w_1280Byte(0x44); // 启动温度转换,模数转化;
  78.      bus_rest();
  79.      w_1280Byte(0xCC); //跳过读序号列号的操作 ;
  80.      w_1280Byte(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 ;
  81.      a=r_1820BYTE();// 低8位
  82.      b=r_1820BYTE();// 高8位
  83.      t=(b*256)+a;
  84.      return(t);
  85. }
  86. /**************************************************************
  87. 函数名称:void show_T(uint temp)
  88. 函数功能:显示温度
  89. **************************************************************/
  90. void show_T(uint temp)
  91. {
  92.      int i;
  93.      float ftemp;
  94.      ftemp = temp* 0.0625;
  95.      sprintf(dis1,"%f",ftemp);//把温度值写入数组内存
  96.      w_12864(com,0x98+3);
  97.      for(i=0;i<5;i++)
  98.      w_12864(dat,dis1[i]); //写入温度
  99. }



复制代码
(3)DS1302驱动程序:

  1. #include "DS1302.h"


  2. /*----------------------DS1302相关声明-------------------------*/
  3. char TAB_1302[]={ 0x00,0x29,0x02, //秒:分:时.
  4.                   0x18,0x06,0x06,0x08}; //日:月:星期:年.
  5. uchar code TAB_XQ[]={"一二三四五六日"};//把DS1302数字日期转换为中文字符.
  6. /*----------------以下为DS1302相关函数-------------------------*/
  7. /**************************************************************
  8. 函数名称:void w_1302byte(uchar date)
  9. 函数功能:写一个字节(上升沿)
  10. ***************************************************************/
  11. void w_1302byte(uchar date)
  12. {
  13.      uchar i;
  14.      datbyte=date;
  15.      for(i=0;i<8;i++)
  16.      {
  17.          T_IO=datbyte0; //写最低位
  18.          T_CLK=0;
  19.          T_CLK=1;
  20.          datbyte>>=1;
  21.      }
  22. }
  23. /**************************************************************
  24. 函数名称:uchar r_1302byte(void)
  25. 函数功能:读一个字节(下降沿)
  26. ***************************************************************/
  27. uchar r_1302byte(void)
  28. {
  29.      uchar i;
  30.      datbyte=0;
  31.      for(i=0;i<8;i++)
  32.      {
  33.          datbyte7=T_IO; //读最低位
  34.          T_CLK=1;
  35.          T_CLK=0;
  36.          datbyte>>=1;
  37.      }
  38.      return(datbyte);
  39. }
  40. /***************************************************************
  41. 函数名称:void write_1302(uchar addr,uchar date)
  42. 函数功能: 指定位置写数据
  43. ****************************************************************/
  44. void write_1302(uchar addr,uchar date)
  45. {
  46.      T_RST=0;
  47.      T_CLK=0;
  48.      T_RST=1;
  49.      w_1302byte(addr);
  50.      w_1302byte(date);
  51.      T_CLK=0;
  52.      T_RST=0;
  53. }
  54. /**************************************************************
  55. 函数名称:uchar read_1302(uchar addr)
  56. 函数功能: 指定位置读数据
  57. ****************************************************************/
  58. uchar read_1302(uchar addr)
  59. {
  60.       uchar dat1,dat2,temp;
  61.       T_RST=0;
  62.       T_CLK=0;
  63.       T_RST=1;
  64.       w_1302byte(addr);
  65.       temp=r_1302byte();
  66.       T_RST=0;
  67.       T_CLK=0;
  68.       dat1=temp/16;
  69.       dat2=temp%16;
  70.       temp=dat1*10+dat2;
  71.       return(temp);
  72. }
  73. /***************************************************************
  74. 函数名称:void init_1302(void)
  75. 函数功能: 初始化
  76. *****************************************************************/
  77. void init_1302(void)
  78. {
  79.      uchar i;
  80.      uchar addr=0x80;
  81.      write_1302(0x8e,0x00);
  82.      for(i=0;i<7;i++)
  83.      {
  84.          write_1302(addr,TAB_1302[i]);
  85.          addr+=2;
  86.      }
  87.      write_1302(0x8e,0x80);
  88. }
  89. /****************************************************************
  90. 函数名称:void get_1302(void)
  91. 功能说明:读取DS1302时钟信息.
  92. *****************************************************************/
  93. void get_1302(void)
  94. {
  95.      uchar i,addr=0x81;
  96.      for(i=0;i<7;i++)
  97.      {
  98.           TAB_1302[i]=read_1302(addr);
  99.           addr+=2;
  100.      }
  101. }
复制代码
(4)其他驱动程序在附件下载



也就是说,上面驱动搞定,基本是完成50%的要求,是不是很简单,剩下的就是自己的控制程序了,这个设计其实难点在驱动程序,只要搞定驱动程序,剩下的就是所谓的if啥的,好,下面看看我设计的电子琴,是在这个基础上扩展的,没加什么,就是加了一些蜂鸣器的控制程序

3 电子琴的设计

其实,对于基于51单片机的电子琴在网上已经是烂透的那种了,本人也参考了网上大神的程序,然后修改了一下下,实现了蓝牙控制电子琴,电脑实现远程控制电子琴演奏。



(5)电子琴设计实物图

蓝牙控制和PC远程控制:选用的是HC05,通过修改串口的收发程序,实现了接收串口数据后进行演奏,其实原理很简单,下面是控制程序。利用两个按键扫描程序,实现多功能的控制,多次收发的控制。基本功能就是按键选择高低音,按键演奏,扩展功能就是蓝牙控制,电脑演奏

  1.         KeyScan1();                                                                        //电子琴功能按键
  2.                 Keyscan();                                                                         //行列式扫描比较慢,耐心长按
  3.                 switch(key)
  4.                 {
  5.                         case 0:  time = 1;break;
  6.                         case 1:  time = 2;break;
  7.                         case 2:  time = 3;break;
  8.                         case 3:  time = 4;break;
  9.                         case 4:  time = 5;break;
  10.                         case 5:  time = 6;break;
  11.                         case 6:  time = 7;break;
  12.                         case 7:  time = 8;break;        
  13.                         case 8:  time = 9;break;
  14.                         case 9:         time = 10;break;
  15.                         case 10: time = 11;break;
  16.                         case 11: time = 12;break;
  17.                         case 12: time = 13;break;        
  18.                         case 13: time = 14;break;        
  19.                         case 14: time = 15;break;                                       
  20.                         default: time = 0;                                         break;//无按键按下
  21.                         
  22.                 }
  23.                 if(time==0)                                                TR0=0,Beep=1;
  24.                 else                                                                        high=freq[7*Music_Freq+time-1][1],low= freq[7*Music_Freq+time-1][0],TR0=1;
  25.                 Q(Music_Freq,time);//显示
复制代码
4 其他选题的实现

如果对其他选题不懂,或者不会修改的可以看看网上的相关控制历程,结合这里的驱动程序应该是很简单就可以完成的。

51hei图片_20191126205342.jpg (241.32 KB, 下载次数: 27)

51hei图片_20191126205342.jpg

51单片机课程设计-电子琴(林宏伟).rar

103.8 KB, 下载次数: 32, 下载积分: 黑币 -5

林宏伟单片机原理图.pdf

462.23 KB, 下载次数: 13, 下载积分: 黑币 -5

评分

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

查看全部评分

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

使用道具 举报

沙发
ID:284488 发表于 2019-11-27 09:02 | 只看该作者
赞!感谢楼主的分享
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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