仿真原理圖如下(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)
2019-10-21 19:30 上傳
點擊文件名下載附件
|