基于51单片机的16键电子琴音乐盒仿真原理图方案设计

链接:https://pan.baidu.com/s/1ljQM_fOYl4r_0dfMIosDAQ
提取码:zsq4

系统硬件电路设计

原理图:
在这里插入图片描述
仿真图
在这里插入图片描述
主控模块
主控模块模块在整个系统中起着统筹的作用,需要检测键盘,温度传感器等各种参数,同时驱动液晶显示相关参数,在这里我们选用了51系列单片机中的STC89C52单片机作为系统的主控芯片。
51系列单片机最初是由Intel 公司开发设计的,但后来Intel 公司把51 核的设计方案卖给了几家大的电子设计生产商,譬如 SST、Philip、Atmel 等大公司。因此市面上出现了各式各样的均以51 为内核的单片机。这些各大电子生产商推出的单片机都兼容51 指令、并在51 的基础上扩展一些功能而内部结构是与51一致的。
STC89C52有40个引脚,4个8位并行I/O口,1个全双工异步串行口,同时内含5个中断源,2个优先级,2个16位定时/计数器。STC89C52的存储器系统由4K的程序存储器(掩膜ROM),和128B的数据存储器(RAM)组成。

矩阵键盘模块设计
在这里插入图片描述
硬件电路设计图如上图所示。把单片机的P3.0-P3.7端口通过8联拨动拨码开关连接到“44行列式键盘”,其中P3.0-P3.3作为列线,P3.4-P3.7作为行线,系统首先通过CPU对全部键盘进行扫描,即把第一根行线置为“0”状态,其余行线置于“1”状态,读入输入缓冲器的状态,若其状态全为“1”表明该行无键按下,再将第二根行线置为“0”状态,同样读入输入缓冲器的状态,如其状态也全为“1”,则置第一根行线置为“0”状态,以此类推。如读入输入缓冲器的状态不全为“1”,确定哪一根列线为“0”状态,当某个键的行线和列线都为“0”状态时,表明该键按下。
矩阵式键盘模式以N个端口连接控制N
N个按键,实时在LED数码管上显示按键信息。显示按键信息,省下了很多的I/O端口为他用,相反,独立式按键虽编程简单,但占用I/O口资源较多,不适合在按键较多的场合应用。并且在实际应用中经常要用到输入数字、字母、符号等操作功能,如电子密码锁、电话机键盘、计算器按键等,至少都需要12到16个按键。矩阵式键盘简介:矩阵式键盘又称行列键盘,它是用N条I/O线作为行线,N条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上设置一个按键。这样键盘上按键的个数就为N*N个。这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。
最常见的键盘布局如图3-7所示。一般由16个按键组成,在单片机中正好可以用一个P口实现16个按键功能,这也是在单片机系统中最常用的形式,本设计就采用这个键盘模式。
在这里插入图片描述

图3-7 键盘布局
矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。

功率放大模块设计
功率放大模块我们选用了LM386作为功率放大模块的主要芯片,LM386是美国国家半导体公司生产的音频功率放大器,主要应用于低电压消费类产品。为使外围元件最少,电压增益内置为20。但在1脚和8脚之间增加一只外接电阻和电容,便可将电压增益调为任意值,直至 200。输入端以地位参考,同时输出端被自动偏置到电源电压的一半,在6V电源电压下,它的静态功耗仅为24mW,使得LM386特别适用于电池供电的场合。

LM386使用注意事项
尽管LM386的应用非常简单,但稍不注意,特别是器件上电、断电瞬间,甚至工作稳定后,一些操作(如插拔音频插头、旋音量调节钮)都会带来的瞬态冲击,在输出喇叭上会产生非常讨厌的噪声。
(1)通过接在1脚、8脚间的电容(1脚接电容+极)来改变增益,断开时增益为20。因此用不到大的增益,电容就不要接了,不光省了成本,还会带来好处–噪音减少,何乐而不为?
(2)PCB设计时,所有外围元件尽可能靠近LM386;地线尽可能粗一些;输入音频信号通路尽可能平行走线,输出亦如此。这是死理,不用多说了吧。
(3)好调节音量的电位器。质量太差的不要,否则受害的是耳朵;阻值不要太大,10K最合适,太大也会影响音质,转那么多圈圈,不烦那!
(4)可能采用双音频输入/输出。好处是:“+”、“-”输出端可以很好地抵消共模信号,故能有效抑制共模噪声。
(5)7脚(BYPASS)的旁路电容不可少!实际应用时,BYPASS端必须外接一个电解电容到地,起滤除噪声的作用。工作稳定后,该管脚电压值约等于电源电压的一半。增大这个电容的容值,减缓直流基准电压的上升、下降速度,有效抑制噪声。在器件上电、掉电时的噪声就是由该偏置电压的瞬间跳变所致,这个电容可千万别省啊!
(6)少输出耦合电容。此电容的作用有二:隔直+耦合。隔断直流电压,直流电压过大有可能会损坏喇叭线圈;耦合音频的交流信号。它与扬声器负载构成了一阶高通滤波器。减小该电容值,可使噪声能量冲击的幅度变小、宽度变窄;太低还会使截止频率(fc=1/(2πRLCout))提高。分别测试,发现10uF/4.7uF最为合适,这是我的经验值。
(7)源的处理,也很关键。如果系统中有多组电源,太好了!由于电压不同、负载不同以及并联的去耦电容不同,每组电源的上升、下降时间必有差异。非常可行的方法:将上电、掉电时间短的电源放到+12V处,选择上升相对较慢的电源作为LM386的Vs,但不要低于4V,效果确实非常不错!

系统软件总体设计

在这里插入图片描述

#include <reg52.h>	         //调用单片机头文件
#define uchar unsigned char  //无符号字符型 宏定义	变量范围0~255
#define uint  unsigned int	 //无符号整型 宏定义	变量范围0~65535

sbit beep  = P3^2;	   //蜂鸣器定义

sbit K1=P2^7;//音乐播放按键
uchar flag_en = 0;	   //开始放歌
uchar flag_i = 0;

uchar num=0;//初始化num,用于控制数1码管显示的字符

//数码管段选定义       0    1    2    3   4	   5	6	 7	  8	   9	
uchar code smg_du[]={0x28,0xee,0x34,0xa4,0xe2,0xa1,0x21,0xec,0x20,0xa0,
//					   A	B	 C	  D	   E   F	不显示
					   0x60,0x23,0x39,0x26,0x31,0x71,0xbf};	 //断码	
					 

uchar m,n; 
uchar code T[49][2]={{0,0},
{0xF8,0x8B},{0xF8,0xF2},{0xF9,0x5B},{0xF9,0xB7},{0xFA,0x14},{0xFA,0x66},{0xFA,0xB9},{0xFB,0x03},
{0xFB,0x4A},{0xFB,0x8F},{0xFB,0xCF},{0xFC,0x0B},{0xFC,0x43},{0xFC,0x78},{0xFC,0xAB},{0xFC,0xDB},
{0xFD,0x08},{0xFD,0x33},{0xFD,0x5B},{0xFD,0x81},{0xFD,0xA5},{0xFD,0xC7},{0xFD,0xE7},{0xFE,0x05},
{0xFE,0x21},{0xFE,0x3C},{0xFE,0x55},{0xFE,0x6D},{0xFE,0x84},{0xFE,0x99},{0xFE,0xAD},{0xFE,0xC0},
{0xFE,0x02},{0xFE,0xE3},{0xFE,0xF3},{0xFF,0x02},{0xFF,0x10},{0xFF,0x1D},{0xFF,0x2A},{0xFF,0x36},
{0xFF,0x42},{0xFF,0x4C},{0xFF,0x56},{0xFF,0x60},{0xFF,0x69},{0xFF,0x71},{0xFF,0x79},{0xFF,0x81}
};
uchar code music1[][2]={{0,4},	   //两只蝴蝶 
{23,4},{21,4},{23,16},{23,4},{21,4},{23,4},{21,4},{19,16},{16,4},{19,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{19,4},{14,24},
{23,4},{21,4},{23,16},{23,4},{21,4},{23,4},{21,4},{19,24},{16,4},{19,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{19,4},{21,24},

{23,4},{21,4},{23,16},{23,4},{21,4},{23,4},{21,4},{19,16},{16,4},{19,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{19,4},{14,24},
{23,4},{26,4},{26,16},{26,4},{28,4},{26,4},{23,24},{21,4},{23,4},{21,8},{21,4},{23,4},{21,4},{19,4},{16,4},{16,2},{19,2},{19,24},{0,20},
{26,4},{26,4},{28,4},{31,4},{30,4},{30,4},{28,4},{23,4},{21,4},{21,4},{23,16},{0,4},{23,4},{23,4},{26,4},{28,8},{28,12},{16,4},{23,4},{21,4},
{21,24},{23,4},{26,4},{26,4},{23,4},{26,8},{0,4},{31,8},{30,4},{28,4},{30,4},{23,8},{0,4},{28,4},{28,4},{30,4},{28,4},{26,4},{23,4},{21,8},{23,4},{21,4},{23,4},{26,16},
{0xFF,0xFF}};


uchar code music2[][2]={{0,4},	  //生日快乐
{17,6},{17,2},{19,8},{17,8},{22,8},{21,16},
{17,6},{17,2},{19,8},{17,8},{24,8},{22,16},{17,6},{17,2},{29,8},{26,8},{22,8},{21,8},{19,8},{27,6},{27,2},{26,8},{22,8},{24,8},{22,16},
{0xFF,0xFF}};

uchar code music3[][2]={{0,4},	 //爱情买卖
{22,4},{22,4},{17,4},{15,4},{15,4},{17,12},
{15,4},{15,2},{17,2},{15,4},{13,4},{13,4},{15,12},{0,4},
{20,4},{20,4},{20,4},{17,4},{20,4},{20,4},{20,4},{17,4},
{22,4},{17,4},{17,4},{15,4},{15,4},{17,12},
{22,4},{22,4},{17,4},{15,4},{15,4},{17,12},
{15,4},{15,2},{17,2},{15,4},{13,4},{13,4},{15,12},
{20,4},{20,4},{20,2},{17,2},{17,4},{20,4},{20,4},{20,2},{17,2},{17,2},{17,2},
{24,4},{20,4},{20,2},{17,2},{17,4},{20,4},{22,12},
{17,4},{22,4},{25,4},{25,4},{17,4},{22,4},{25,8},
{24,4},{22,2},{24,2},{22,4},{20,4},{15,4},{17,12},
{15,4},{15,4},{15,4},{10,4},{15,4},{17,4},{20,8},
{17,4},{24,4},{24,4},{20,4},{15,4},{17,12},
{17,4},{22,4},{25,4},{25,4},{17,4},{22,4},{25,8},
{29,4},{27,2},{29,2},{27,4},{25,4},{25,4},{27,12},
{29,4},{29,2},{27,4},{25,4},{27,6},{27,2},{25,4},{24,4},
{20,4},{20,2},{17,2},{20,4},{20,2},{22,2},{22,16},
{0xFF,0xFF}};
void delay(uchar p)
{
    uchar i,j; 
    for(;p>0;p--)
    for(i=181;i>0;i--)
    for(j=181;j>0;j--);
}

void pause()
{
    uchar i,j;
    for(i=150;i>0;i--)
    for(j=150;j>0;j--);
}


/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
	uint i,j;
	for(i=0;i<q;i++)
		for(j=0;j<120;j++);
}

/******************按键程序*************************/
uchar key_can;	 //按键值
	
void key()	 //独立按键程序
{
	static uchar key_new = 0, key_l;
	key_can = 20;                   //按键值还原
	P2 = 0x0f;
	if((P2 & 0x0f) != 0x0f)		//按键按下
	{
		delay_1ms(1);	     	//按键消抖动
		if(((P2 & 0x0f) != 0x0f) && (key_new == 1))
		{						//确认是按键按下
			key_new = 0;
			key_l = (P2 | 0xf0);   //矩阵键盘扫描
			P2 = key_l;
			switch(P2)
			{						
				case 0xee:  key_can = 0; m = 8;	TR0 = 1; break;  //得到按键值  //打开定时器 
				case 0xde:  key_can = 1; m = 9;	TR0 = 1;   break;   //得到按键值 
				case 0xbe:  key_can = 2; m = 10;	TR0 = 1;   break;   //得到按键值 
				case 0x7e:  key_can = 3; m = 11;	TR0 = 1;   break;   //得到按键值 
	
				case 0xed:  key_can = 4; m = 12;	TR0 = 1;   break;  //得到按键值 
				case 0xdd:  key_can = 5; m = 13;	TR0 = 1;   break;   //得到按键值 
				case 0xbd:  key_can = 6; m = 14;	TR0 = 1;  break;   //得到按键值 
				case 0x7d:  key_can = 7; m = 15;	TR0 = 1;   break;   //得到按键值 
	
				case 0xeb:  key_can = 8; m = 16;	TR0 = 1;   break;  //得到按键值 
				case 0xdb:  key_can = 9; m = 17;	TR0 = 1;   break;   //得到按键值 
				case 0xbb:  key_can = 10; m = 18;	TR0 = 1;   break;   //得到按键值 
				case 0x7b:  key_can = 11; m = 19;	TR0 = 1;   break;   //得到按键值 
	
				case 0xe7:  key_can = 12; m = 20;	TR0 = 1;   break;  //得到按键值 
				case 0xd7:  key_can = 13; m = 21;	TR0 = 1;   break;  //得到按键值 
				case 0xb7:  key_can = 14; m = 22;	TR0 = 1;   break;   //得到按键值 
				case 0x77:  key_can = 15; m = 23;	TR0 = 1;   break;  //得到按键值 	
			}	
			P1 = smg_du[key_can];	  //显示
			while(P2 != 0x0f)
		   		P2 = 0x0f;
			TR0 = 0;  	    //关闭定时器
		}			
	}
	else 		  //按键松开
	{
		P1 = 0xdf;	  //显示小数点
		key_new = 1;	
	}

.

  • 24
    点赞
  • 218
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值