51单片机电子琴设计(可显示光敏、温度、日期)
作者:林宏伟 学校:shaoguandada 时间:2019/11/26
首先,看图:下面这张图是基于51单片机设计的基础要求,一共是10个小课题,难度的话,初步认为是半颗星,说难不算难,说简单确实很简单,这对于那些有基础的同学而言轻松,基本几个小时就搞定了。
编号 | | | | | | 1、电子万年历功能;2、可设置三组以上的闹钟;3、温度检测功能;4、倒计时功能 | | | | 1、可检测显示0~5V的直流电压;2、可检测环境光照功能,将系统工作环境的光线分为强、中、弱三个等级并在液晶上显示。 | | | | 1、可输出0~5V的直流电压。直流电压的大小用键盘设置确定,精度为0.1V;2、可输出正弦波、方波和三角波。波形的频率不限,但是幅度可在1~5V之间用键盘设置, 精度为0.1V。 | | | | 1、检测显示当前的环境温度和光线强度。2、键盘设置温度和光强的上限与下限值,如果温度与光强超出界限值,则蜂鸣器发出警报。同时液晶显示警报的类型。 | | | | 1、高、中、低音调选择功能;2、手动演奏功能;3、至少能自动演奏一首歌曲;4、完美的中文操作界面。 | | | | 1、基本的加减乘除运算功能;2、乘方、开方运算;3、三角函数运算;4十进制、二进制、十六进制转换功能。 | | | | file:///C:\Users\LITTLE~1\AppData\Local\Temp\ksohtml84440\wps1.jpg1、时分秒显示;2、时分秒可以现场键盘设置;3、断电后下一次通电时,时钟能在原来的基础上继续运行;4、温度检测显示;5、秒表功能 | | | | 1、 利用LCD图型模式,编程实现时钟功能。显示模式参考图如右图所示。 2、键盘实时调整时钟数据 | | | | 1、开机密码设置功能。系统通电后,要输入6位的密码才能进入系统。3、进入系统后,可以输入英文文章。即系统按键具有数字、标点符号、大小写字母、空格,回车等字符输入功能。4、附加功能。进入系统后,密码可以用按键更改;输入的文章,液晶界面显示满之后,能够分页切换,并且具有保存、清楚功能。 | | | | 1、利用单片机控制DA转换器,变出控制输出两路相位相反的PWM信号;2、PWM信号的幅度可在0.1V~5V之间用键盘按照0.1V的分辨率任意设定;3、PWM的展空比,可在1%~99%之间,按照1%的精度,用键盘设定控制;4、PWM的频率,可在10~100Hz之间,按照1Hz的分辨率,任意设定。 | |
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)矩阵按键驱动程序:这个采用最最基础的扫描程序,还有状态机、翻转两种,比较高阶,如果是新手就建议不要采用(怕看不懂)
- #include "DS1302.h"
- /*----------------------DS1302相关声明-------------------------*/
- char TAB_1302[]={ 0x00,0x29,0x02, //秒:分:时.
- 0x18,0x06,0x06,0x08}; //日:月:星期:年.
- uchar code TAB_XQ[]={"一二三四五六日"};//把DS1302数字日期转换为中文字符.
- /*----------------以下为DS1302相关函数-------------------------*/
- /**************************************************************
- 函数名称:void w_1302byte(uchar date)
- 函数功能:写一个字节(上升沿)
- ***************************************************************/
- void w_1302byte(uchar date)
- {
- uchar i;
- datbyte=date;
- for(i=0;i<8;i++)
- {
- T_IO=datbyte0; //写最低位
- T_CLK=0;
- T_CLK=1;
- datbyte>>=1;
- }
- }
- /**************************************************************
- 函数名称:uchar r_1302byte(void)
- 函数功能:读一个字节(下降沿)
- ***************************************************************/
- uchar r_1302byte(void)
- {
- uchar i;
- datbyte=0;
- for(i=0;i<8;i++)
- {
- datbyte7=T_IO; //读最低位
- T_CLK=1;
- T_CLK=0;
- datbyte>>=1;
- }
- return(datbyte);
- }
- /***************************************************************
- 函数名称:void write_1302(uchar addr,uchar date)
- 函数功能: 指定位置写数据
- ****************************************************************/
- void write_1302(uchar addr,uchar date)
- {
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- w_1302byte(addr);
- w_1302byte(date);
- T_CLK=0;
- T_RST=0;
- }
- /**************************************************************
- 函数名称:uchar read_1302(uchar addr)
- 函数功能: 指定位置读数据
- ****************************************************************/
- uchar read_1302(uchar addr)
- {
- uchar dat1,dat2,temp;
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- w_1302byte(addr);
- temp=r_1302byte();
- T_RST=0;
- T_CLK=0;
- dat1=temp/16;
- dat2=temp%16;
- temp=dat1*10+dat2;
- return(temp);
- }
- /***************************************************************
- 函数名称:void init_1302(void)
- 函数功能: 初始化
- *****************************************************************/
- void init_1302(void)
- {
- uchar i;
- uchar addr=0x80;
- write_1302(0x8e,0x00);
- for(i=0;i<7;i++)
- {
- write_1302(addr,TAB_1302[i]);
- addr+=2;
- }
- write_1302(0x8e,0x80);
- }
- /****************************************************************
- 函数名称:void get_1302(void)
- 功能说明:读取DS1302时钟信息.
- *****************************************************************/
- void get_1302(void)
- {
- uchar i,addr=0x81;
- for(i=0;i<7;i++)
- {
- TAB_1302[i]=read_1302(addr);
- addr+=2;
- }
- }
复制代码 (4)其他驱动程序在附件下载
也就是说,上面驱动搞定,基本是完成50%的要求,是不是很简单,剩下的就是自己的控制程序了,这个设计其实难点在驱动程序,只要搞定驱动程序,剩下的就是所谓的if啥的,好,下面看看我设计的电子琴,是在这个基础上扩展的,没加什么,就是加了一些蜂鸣器的控制程序
3 电子琴的设计
其实,对于基于51单片机的电子琴在网上已经是烂透的那种了,本人也参考了网上大神的程序,然后修改了一下下,实现了蓝牙控制电子琴,电脑实现远程控制电子琴演奏。
(5)电子琴设计实物图
蓝牙控制和PC远程控制:选用的是HC05,通过修改串口的收发程序,实现了接收串口数据后进行演奏,其实原理很简单,下面是控制程序。利用两个按键扫描程序,实现多功能的控制,多次收发的控制。基本功能就是按键选择高低音,按键演奏,扩展功能就是蓝牙控制,电脑演奏
- KeyScan1(); //电子琴功能按键
- Keyscan(); //行列式扫描比较慢,耐心长按
- switch(key)
- {
- case 0: time = 1;break;
- case 1: time = 2;break;
- case 2: time = 3;break;
- case 3: time = 4;break;
- case 4: time = 5;break;
- case 5: time = 6;break;
- case 6: time = 7;break;
- case 7: time = 8;break;
- case 8: time = 9;break;
- case 9: time = 10;break;
- case 10: time = 11;break;
- case 11: time = 12;break;
- case 12: time = 13;break;
- case 13: time = 14;break;
- case 14: time = 15;break;
- default: time = 0; break;//无按键按下
-
- }
- if(time==0) TR0=0,Beep=1;
- else high=freq[7*Music_Freq+time-1][1],low= freq[7*Music_Freq+time-1][0],TR0=1;
- Q(Music_Freq,time);//显示
复制代码 4 其他选题的实现
如果对其他选题不懂,或者不会修改的可以看看网上的相关控制历程,结合这里的驱动程序应该是很简单就可以完成的。
|