仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
#include <reg51.h>
#define uchar unsigned char //宏的定义变量类型 uchar 代替 unsigned char
#define uint unsigned int //宏的定义变量类型 uint 代替 unsigned int
uchar dis_buf; //显示缓存
uchar temp;
uchar key,a,b,c,d,e,f,g,h,k,m,n,p,q,r,s,t,bb,cc; //键顺序码
void delay(uchar x); //x*0.14MS
#define LCDLCDDisp_Off 0x3e
#define LCDLCDDisp_On 0x3f
#define Page_Add 0xb8//页地址
#define LCDCol_Add 0x40//列地址
#define Start_Line 0xC0//行地址
/*****液晶显示器的端口定义*****/
#define data_ora P0 /*液晶数据总线*/
sbit LCDMcs=P2^1 ; /*片选1*/
sbit LCDScs=P2^2 ; /*片选2*/
sbit RESET=P2^3 ; /*复位信号*/
sbit LCDDi=P2^4 ; /*数据/指令 选择*/
sbit LCDRW=P2^5 ; /*读/写 选择*/
sbit LCDEnable=P2^6 ; /*读/写 使能*/
sbit key1=P1^0;
sbit key2=P1^1;
sbit key3=P1^2;
sbit key4=P1^3;
sbit LED_R=P1^6;
sbit LED_G=P1^7;
sbit SPK = P3^7;
uchar tone_h; //高音
uchar tone_l; //低音
uint note = 1; //音符
uchar beat; //节拍
uchar a=0;
unsigned int Num0=0,Num1=0,Num2=0,Num3=0,Num4=0,Num5=0,Num6=0;
bit flag0,flag_up,flag_dn,flag_door,flag_keyoff,flag_bb,flag_cc,flag1,flag2,flag3,flag4,flag5,flag6,flag7,flag8,flag9;
bit flag_1_up, flag_2_up,flag_2_dn, flag_3_up,flag_3_dn,flag_4_dn;
unsigned char code Bmp0[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板! /已选楼层
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xC0,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xC0,0x30,0x1E,0x10,0x10,0x10,0xFF,0x10,0x10,0x10,0x10,0x18,0x10,0x00,0x00,
0x00,0x00,0x00,0xFE,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xFF,0x02,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x04,0x0C,0x18,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x41,0x40,0x42,0x42,0x42,0x42,0x42,0x7F,0x42,0x42,0x42,0x43,0x42,0x60,0x40,0x00,
0x00,0x00,0x00,0x7F,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7F,0x00,0x00,0x00,0x00
};
unsigned char code Bmp1[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/当前楼层
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x0C,0x08,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x10,0x10,0x10,0xFF,0x90,0x50,0xFE,0x42,0x42,0xC2,0x42,0x42,0xFF,0x02,0x00,0x00,
0x10,0x21,0x62,0x06,0x80,0xFE,0x22,0xE2,0x22,0x22,0x22,0x22,0xBF,0x02,0x00,0x00,
0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,0x10,0x00,
0x00,0x00,0x04,0x0C,0x18,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x02,0x42,0x81,0x7F,0x40,0x20,0x1E,0x10,0x20,0x7F,0x44,0x44,0x46,0x64,0x20,0x00,
0x04,0x04,0x7E,0x81,0x60,0x1F,0x00,0x3F,0x48,0x44,0x42,0x41,0x41,0x40,0x70,0x00
};
unsigned char code Bmp2[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/升降状态
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x00,0x04,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xC4,0x86,0x04,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x02,0xF2,0x12,0x12,0x12,0xFE,0x12,0x12,0x12,0xFE,0x12,0x12,0x12,0xFB,0x12,0x00,
0x00,0x00,0x00,0xFC,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0xFE,0x04,0x00,0x00,0x00,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x00,
0x00,0x00,0x04,0x0C,0x18,0x38,0x38,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xFF,0x10,0x08,0x04,0x03,0x14,0x08,0x04,0x03,0x04,0x48,0x98,0x7F,0x00,0x00,
0x00,0x80,0x40,0x23,0x11,0x19,0x01,0x01,0x01,0x09,0x11,0x23,0x60,0xC0,0x00,0x00
};
unsigned char code Bmp3[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/开门状态
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code Bmp4[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/ 上升
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x80,0x70,0x00,0xFF,0x10,0x20,0x10,0x10,0xFF,0x10,0x10,0x10,0xF8,0x10,0x00,0x00,
0x00,0x80,0xC0,0xBC,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0xC0,0x80,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFF,0x82,0x42,0x22,0x1A,0x07,0x0A,0x12,0x22,0x43,0xC2,0x42,0x00,
0x00,0x40,0x20,0x10,0x0C,0x40,0x80,0x7F,0x00,0x00,0x04,0x08,0x30,0x60,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code Bmp5[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/ 下降
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x10,0xE8,0x27,0xF4,0x2C,0xE0,0x24,0xA4,0xFC,0x22,0x22,0x40,0xFF,0x40,0x30,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0xCF,0x49,0x2F,0x29,0x2F,0x04,0x03,0xFF,0x81,0x42,0x30,0x0F,0x30,0x40,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code Bmp6[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/ 打开
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x40,0x40,0x48,0x48,0x48,0x48,0x7F,0xC8,0x4C,0x68,0x50,0x48,0x4C,0x60,0x40,0x00,
0x00,0x00,0xF8,0x48,0x48,0x48,0xF8,0x4F,0x4A,0x2A,0x2B,0x0A,0xA8,0x18,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0x20,0x10,0x08,0x04,0x7E,0x91,0x90,0x88,0x88,0x84,0x86,0x80,0xE0,0x00,0x00,
0x80,0x40,0x3F,0x80,0x40,0x3C,0x04,0x05,0x05,0x7F,0x85,0x81,0x81,0xE0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char code Bmp7[]=
{
/*------------------------------------------------------------------------------
源文件 / 文字 : 来自剪贴板!/ 关闭
宽×高(像素): 64×16
字模格式/大小 : 单色点阵液晶字模,纵向取模,字节倒序/256字节
数据转换日期 : 2018-6-22
------------------------------------------------------------------------------*/
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
uchar code chuzhi[3][16]={ //音调对应的计数初值
0xff,0xff,//占0位
0xf8,0x8c,//低1
0xf9,0x5b,// 2
0xfa,0x15,// 3
0xfa,0x67,// 4
0xfb,0x04,// 5
0xfb,0x90,// 6
0xfc,0x0c,//低7
0xff,0xff,//占0位
0xfc,0x44,//中1
0xfc,0xac,// 2
0xfd,0x09,// 3
0xfd,0x34,// 4
0xfd,0x82,// 5
0xfd,0xc8,// 6
0xfe,0x06,//中7
0xff,0xff,//占0位
0xfe,0x22,//高1
0xfe,0x56,// 2
0xfe,0x85,// 3
0xfe,0x9a,// 4
0xfe,0xc1,// 5
0xfe,0xe4,// 6
0xff,0x03 //高7
};
//****** 测试曲谱 ****** 个位:音调 ,十位:低中高音 对应 0 1 2,千百位:节拍 1~16
uint code test2[] = { 120, //曲速 暂时未用到
401,402,403,404,405,406,407,
611,612,613,614,615,616,617,
821,822,823,824,825,826,827,
0xffff //0xffff表示结尾
};
//****** 生日快乐 ******
uint code test[] = { 120,
205,205,406,405,411,807,
205,205,406,405,412,811,
205,205,415,413,411,407,406,
314,114,413,411,413,812,
305,105,406,405,411,807,
305,105,406,405,412,811,
305,105,415,413,411,
407,406,314,114,413,411,412,811,410,
0xffff
};
void delayms(uint ms) /*ms 等于1时,延时1ms 等于2时,延时2ms,以此类推*/
{
uchar a,b,c; //+3
while(ms--)
{
for(c=1;c>0;c--) // 1+2 = 3
for(b=142;b>0;b--) // 1*( 1+142*2)) = 285
for(a=2;a>0;a--); // 142*(1+2*2) = 710
}
}
void delay125ms(uint pai) //延时 ?*125ms 即?个节拍
{
uchar a,b,c;
while(pai--)
{
for(c=239;c>0;c--)
for(b=104;b>0;b--)
for(a=1;a>0;a--);
}
}
void system_Ini()
{
EA = 1;
ET0 = 1;
PT0 = 1;
TMOD = 0x11;
TH0 = 255;
TL0 = 255;
}
void delay(uchar x)
{ uchar j;
while((x--)!=0) //CPU执行x*12次
{ for(j=0;j<125;j++)
{;}
}
}
/****************************************************************************
函数功能:LCD延时程序
入口参数:t
出口参数:
****************************************************************************/
void LCDdelay(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++);
for(j=0;j<10;j++);
}
/****************************************************************************
状态检查,LCD是否忙
*****************************************************************************/
void CheckState()
{
unsigned char dat,DATA;//状态信息(判断是否忙)
LCDDi=0; // 数据\指令选择,D/I(RS)="L" ,表示 DB7∽DB0 为显示指令数据
LCDRW=1; //R/W="H" ,E="H"数据被读到DB7∽DB0
do
{
DATA=0x00;
LCDEnable=1; //EN下降源
LCDdelay(2);//延时
dat=DATA;
LCDEnable=0;
dat=0x80 & dat; //仅当第7位为0时才可操作(判别busy信号)
}
while(!(dat==0x00));
}
/*****************************************************************************
函数功能:写命令到LCD程序,RS(DI)=L,RW=L,EN=H,即来一个脉冲写一次
入口参数:cmdcode
出口参数:
*****************************************************************************/
void write_com(unsigned char cmdcode)
{
CheckState();//检测LCD是否忙
LCDDi=0;
LCDRW=0;
P0=cmdcode;
LCDdelay(2);
LCDEnable=1;
LCDdelay(2);
LCDEnable=0;
}
/*****************************************************************************
函数功能:LCD初始化程序
入口参数:
出口参数:
*****************************************************************************/
void init_lcd()
{
system_Ini();
LCDdelay(100);
LCDMcs=1;//刚开始关闭两屏
LCDScs=1;
LCDdelay(100);
write_com(LCDLCDDisp_Off); //写初始化命令
write_com(Page_Add+0);
write_com(Start_Line+0);
write_com(LCDCol_Add+0);
write_com(LCDLCDDisp_On);
}
/*****************************************************************************
函数功能:写数据到LCD程序,RS(DI)=H,RW=L,EN=H,即来一个脉冲写一次
入口参数:LCDDispdata
出口参数:
*****************************************************************************/
void write_data(unsigned char LCDDispdata)
{
CheckState();//检测LCD是否忙
LCDDi=1;
LCDRW=0;
P0=LCDDispdata;
LCDdelay(2);
LCDEnable=1;
LCDdelay(2);
LCDEnable=0;
}
/*****************************************************************************
函数功能:清除LCD内存程序
入口参数:pag,col,hzk
出口参数:
*****************************************************************************/
void Clr_Scr()
{
unsigned char j,k;
LCDMcs=0; //左、右屏均开显示
LCDScs=0;
write_com(Page_Add+0);
write_com(LCDCol_Add+0);
for(k=0;k<8;k++)//控制页数0-7,共8页
{
write_com(Page_Add+k); //每页每页进行写
for(j=0;j<64;j++) //每页最多可写32个中文文字或64个ASCII字符
{
write_com(LCDCol_Add+j);
write_data(0x00);//控制列数0-63,共64列,写点内容,列地址自动加1
}
}
}
/*****************************************************************************
函数功能:左屏位置显示
入口参数:page,column,hzk
出口参数:
*****************************************************************************/
void Bmp_Left_Disp(unsigned char page,unsigned char column, unsigned char code *Bmp)
{
unsigned char j=0,i=0;
for(j=0;j<2;j++)
{
write_com(Page_Add+page+j);
write_com(LCDCol_Add+column);
for(i=0;i<64;i++)
write_data(Bmp[128*j+i]);
}
}
void Bmp_Left_Disp1(unsigned char page,unsigned char column, unsigned char code *Bmp)
{
unsigned char j=0,i=0;
for(j=0;j<2;j++)
{
write_com(Page_Add+page+j);
write_com(LCDCol_Add+column);
for(i=0;i<64;i++)
write_data(Bmp[64*j+i]);
}
}
/*****************************************************************************
函数功能:右屏位置显示
入口参数:page,column,hzk
出口参数:
*****************************************************************************/
void Bmp_Right_Disp(unsigned char page,unsigned char column, unsigned char code *Bmp)
{
unsigned char j=0,i=0;
for(j=0;j<2;j++)
{
write_com(Page_Add+page+j);
write_com(LCDCol_Add+column);
for(i=64;i<128;i++)
write_data(Bmp[128*j+i]);
}
}
void Bmp_Right_Disp1(unsigned char page,unsigned char column, unsigned char code *Bmp)
{
unsigned char j=0,i=0;
for(j=0;j<2;j++)
{
write_com(Page_Add+page+j);
write_com(LCDCol_Add+column);
for(i=0;i<64;i++)
write_data(Bmp[64*j+i]);
}
}
void main()
{
init_lcd();
Clr_Scr();
LCDMcs=0; //左屏开显示
LCDScs=1;
Bmp_Left_Disp1(0,0,Bmp0);
Bmp_Left_Disp1(2,0,Bmp1);
Bmp_Left_Disp1(4,0,Bmp2);
Bmp_Left_Disp1(6,0,Bmp3);
LCDMcs=1; //右屏开显示
LCDScs=0;
Bmp_Right_Disp1(0,0,Bmp4);
Bmp_Right_Disp1(2,0,Bmp5);
Bmp_Right_Disp1(4,0,Bmp6);
Bmp_Right_Disp1(6,0,Bmp7);
while(1)
{
if(test[note] == 0xffff)
{
note = 1;
}
if(test[note]%10 != 0) //音调不为0 【音调为0时表示不发声,但有节拍】
{
tone_h = TH0 = chuzhi[test[note]%100/10][(test[note]%10)*2 ]; //音调高位 【二维数组 第1维表示低中高音,第二维表示音调】
tone_l = TL0 = chuzhi[test[note]%100/10][(test[note]%10)*2 + 1]; //音调低位
TR0 = 1;
}
delay125ms(test[note]/100); //节拍
TR0 = 0;
delayms(1);
note++;
while(a==1)
{
SPK=1;
if(key4==0)
{
LED_R=1;
LED_G=1;
a=0;
note=0;
}
}
}
}
void timer0() interrupt 1
{
TH0 = tone_h;
TL0 = tone_l;
SPK = ~SPK;
if(key1==0)
{
LED_G=0;
a=1;
}
else if(key2==0||key3==0)
{
LED_R=0;
a=1;
}
}
全部资料51hei下载地址:
音乐盒12864(最终).zip
(143.33 KB, 下载次数: 26)
|