源代码+仿真音乐:两只老虎,生日快乐
stc15f20k60s2+按键+数码管+蜂鸣器
按k4开始播放 按k1选择功能
制作出来的实物图如下:
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #include "ds1302.h"
- #include "lcd1602.h"
- #include "music.h"
- #include "shumaguan.h"
- //74HC595-数码管
- sbit SDA1=P3^6;//串行数据输入,对应595的14脚SER
- sbit SCL1=P3^5;//移位寄存器时钟输入,对应595的11脚SCK
- sbit SCL2=P3^4;//存储寄存器时钟输入,对应595的12脚RCK
- sbit W1=P3^7;
- //发音按键
- sbit k1=P1^0; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- sbit k2=P1^1; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- sbit k3=P1^2; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- sbit k4=P1^3; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- sbit k5=P1^4; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- sbit k6=P1^5; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- sbit k7=P1^6; //哆1 啦2 咪3 发4 嗦5 啦6 西7 哆
- //LED模块
- sbit D1=P2^3; //播放音乐模式
- sbit D2=P2^4; //弹奏模式
- //模式切换与音调选择按键
- sbit k8=P3^2; //功能切换键
- sbit k9=P3^1; //低音
- sbit k10=P3^0; //中音
- sbit k11=P3^3; //高音
- sbit beep=P1^7;//蜂鸣器接口
- uchar code table1[]={ //共阴极数码管
- 0x3F,/*0*/
- 0x06,/*1*/
- 0x5B,/*2*/
- 0x4F,/*3*/
- 0x66,/*4*/
- 0x6D,/*5*/
- 0x7D,/*6*/
- 0x07,/*7*/
- 0x7F,/*8*/
- 0x6F,/*9*/
- 0x37,/*N*///中音
- 0x38,/*L*///低音
- 0x76,/*H*///高音
- 0x79 /*E*/
- };
- /////////////////////////////格式为: 频率常数, 节拍常数, 频率常数, 节拍常数///////////////////
- uchar code table2[]={ //音阶频率表 低八位
- 0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,//中音
- 0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,//低音的高8位
- 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,
- };
- uchar code table3[]={
- 0x8E,0xED,0x44,0x6B,0xB4,0xF4,0x2D,//中音
- 0x21,0xDB,0x87,0xD7,0x68,0xE8,0x5B,//低音的低8位
- 0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,
- };
- //祝你生日快乐
- uchar code music_tab1[]=
- {
- 1, 1, 2, 1, 4, 3, //第一节
- 1, 1, 2, 1, 5, 4, //第二节
- 1, 1, 8, 6, 4, 3, 2, //第三节
- 7, 7, 6, 4, 5, 4, //第四节
- };
- uchar code music_tab1a[]=
- {
- 2, 2, 4, 4, 4, 8, //第一节
- 2, 2, 4, 4, 4, 8, //第二节
- 2, 2, 4, 4, 4, 4, 4, //第三节
- 2, 2, 4, 4, 4, 8, //第四节
- 0XFF
- };
- //两只老虎
- uchar code music_tab2[]=
- {
- 1, 2, 3, 1, //第一节
- 3, 2, 3, 1, //第二节
- 3, 4, 5, //第三节
- 3, 4, 5, //第四节
- 5, 6, 5, 4, 3, 1, //第五节
- 5, 6, 5, 4, 3, 1, //第六节
- 1, 8, 1, //第七节
- 1, 8, 1 //第八节
- };
- uchar code music_tab2a[]=
- {
- 4, 4, 4, 4, //第一节
- 4, 4, 4, 4, //第二节
- 4, 4, 8, //第三节
- 4, 4, 8, //第四节
- 3, 1, 3, 1, 4, 4, //第五节
- 3, 1, 3, 1, 4, 4, //第六节
- 4, 4, 8, //第七节
- 4, 4, 8, //第八节
- 0Xff //结束
- };
- //世上只有妈妈好
- uchar code music_tab3[]=
- {
- 6, 5, 6, 5, 1, 6, 5,
- 6, 3, 5, 6, 5, 3, 1,
- 6, 5, 3, 2, 2, 3, 5,
- 5, 6, 3, 2, 1, 5, 3,
- 2, 1, 6, 1, 5, 0
- };
- uchar code music_tab3a[]=
- {
- 6, 2, 4, 4, 4, 2, 2,
- 8, 4, 2, 2, 4, 4, 2,
- 2, 2, 2, 8, 6, 2, 4,
- 2, 2, 4, 4, 8, 6, 2,
- 2, 2, 2, 2, 12,0,0XFF
- };
- //Fly bird
- uchar code music_tab4[]={ //音调
- 1,2,3,1,
- 1,2,3,1,
- 3,4,5,
- 3,4,5,
- 5,6,5,4,3,1,
- 5,6,5,4,3,1,
- 1,12,1,
- 1,12,1
- };
- uchar code music_tab4a[]={ //节拍
- 4,4,4,4,
- 4,4,4,4,
- 4,4,8,
- 4,4,8,
- 2,1,2,1,4,4,
- 2,1,2,1,4,4,
- 4,4,6,
- 4,4,6,0xff
- };
- //铃儿响叮当
- uchar code music_tab5[]=
- {
- 3, 3, 3, 3, 3, 3, //第一节
- 3, 4, 2, 3, 3, //第二节
- 4, 4, 4, 4, 4, 3, 3, 3, 3, //第三节
- 3, 2, 3, 2, 3, 4, //第四节
-
- 3, 3, 3, 3, 3, 3, //第五节
- 3, 4, 2, 3, 3, //第六节
- 4, 4, 4, 4, 4, 3, 3, 3, 3, //第七节
- 3, 2, 3, 2, 3, 4, 0xff //第八节
- };
- uchar code music_tab5a[]=
- {
- 2, 2, 4, 2, 2, 4, //第一节
- 2, 2, 3, 1, 8, //第二节
- 2, 2, 3, 1, 2, 2, 2, 1, 1, //第三节
- 2, 2, 2, 2, 4, 4, //第四节
- 2, 2, 4, 2, 2, 4, //第五节
- 2, 2, 3, 1, 8, //第六节
- 2, 2, 3, 1, 2, 2, 2, 1, 1, //第七节
- 2, 2, 2, 2, 6, //第八节
- 0XFF //结束
- };
- //DS1302相关
- uchar times[9];
- uchar date[11];
-
- uchar i=0;
- uchar key,aa=0;
- uchar bb,cc;
- bit flag=0;
- uchar music=0;//第几首音乐
- //初始化子函数
- void init()
- {
- beep=0; //蜂鸣器关闭
- D1=0; //开始演奏音乐
- D2=1; //关闭弹奏功能
- EA=1; //开总中断
- TCON=0x05; //外部中断0,1设置为边沿触发
- EX0=1; //开外部中断0
- EX1=1; //开外部中断1
- ET0=1; //定时器0的中断打开
- ET1=1; //定时器1的中断打开
- TMOD=0x11; //定时器0,1工作在定时状态,均为方式1
- }
- //播放音乐子函数
- void display_music()
- {
- if(music==1){
- TH0=table2[music_tab1[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab1[i]-1];
- while(flag==0)
- {
- gotoxy(2,1);
- LCD_display("Happy birthday");
- if(music_tab1a[i]!=0xff)
- {
- TR0=1;
- delay(57*music_tab1a[i]);
- i++;
- if(music!=1){
- TR0=0;
- break;
- }
- }
- // if(i==32) i=0;
- else{
- i=0;
- TR0=0;
- // flag=1;
- music++;
- break;
- }
-
-
- }
- }
- else if(music==2){
- TH0=table2[music_tab2[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab2[i]-1];
- while(flag==0)
- {
- gotoxy(2,1);
- LCD_display("Two tiggers");
- if(music_tab2a[i]!=0xff)
- {
- TR0=1;
- delay(57*music_tab2a[i]);
- i++;
- if(music!=2){
- TR0=0;
- break;
- }
- }
- // if(i==32) i=0;
- else{
- i=0;
- TR0=0;
- music++;
- break;
- }
- }
- }
-
- else if(music==3){
- TH0=table2[music_tab3[i]-1];
- TL0=table3[music_tab3[i]-1];
- while(flag==0)
- {
- gotoxy(2,1);
- LCD_display("Only mom good");
- if(music_tab3a[i]!=0xff)
- {
- TR0=1;
- delay(57*music_tab3a[i]);
- i++;
- if(music!=3){
- TR0=0;
- break;
- }
- }
- else{
- i=0;
- TR0=0;
- music++;
- break;
- }
- }
- }
-
- else if(music==4){
- TH0=table2[music_tab4[i]-1];
- TL0=table3[music_tab4[i]-1];
- while(flag==0)
- {
- gotoxy(2,1);
- LCD_display("Fly bird");
- if(music_tab4a[i]!=0xff)
- {
- TR0=1;
- delay(57*music_tab4a[i]);
- i++;
- if(music!=4){
- TR0=0;
- break;
- }
- }
- else{
- i=0;
- TR0=0;
- music++;
- break;
- }
- }
- }
-
- else if(music==5){
- TH0=table2[music_tab5[i]-1];
- TL0=table3[music_tab5[i]-1];
- while(flag==0)
- {
- gotoxy(2,1);
- LCD_display("Jingle bells");
- if(music_tab5a[i]!=0xff)
- {
- TR0=1;
- delay(57*music_tab5a[i]);
- i++;
- if(music!=5){
- TR0=0;
- break;
- }
- }
- else{
- i=0;
- TR0=0;
- music++;
- break;
- }
- }
- }
- }
- //演奏模式子函数
- void display_play()
- {
- TR0=0;
- TR1=0;
- yinjie();
- in(table1[aa]); //再传段码
- out();
- W1=0;;
- delay(1); //延迟时间2ms以内
- W1=1;
- if(aa!=13&&flag==1)
- {
- if(k1==0)
- {
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k1==0)
- {
- cc=0;
- display1();
- }
- }
- if(k2==0)
- {
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k2==0)
- {
- cc=1;
- display1();
- }
- }
- if(k3==0)
- {
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k3==0)
- {
- cc=2;
- display1();
- }
- }
- if(k4==0)
- { //取频率常数 和 节拍常数
- TH1=table2[7*bb+cc];
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k4==0)
- {
- cc=3;
- display1();
- }
- }
- if(k5==0)
- {
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k5==0)
- {
- cc=4;
- display1();
- }
- }
- if(k6==0)
- {
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k6==0)
- {
- cc=5;
- display1();
- }
- }
- if(k7==0)
- {
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
- TL1=table3[7*bb+cc];
- TR1=1;
- while(k7==0)
- {
- cc=6;
- display1();
- }
- }
- }
- }
- //主函数
- void main()
- {
- init(); //初始化子函数
- //init_1302(time_1302);
- LCD_init();//LCD初始化
-
- times[8]='\0';//
- date[10]='\0';
- while(1)
- {
- if(flag==0){
- if(music!=0){
- LCD_write_command(0x01);//清屏显示
- delay(50);
- }
- else{
- gotoxy(1,1);
- LCD_display("Plese push K4");
- gotoxy(1,2);
- LCD_display("to play music!");
- }
- if(music!=0){
- LCD_write_command(0x01);//清屏显示
- delay(50);
- }
- display_music(); //演奏音乐
-
- }
-
- else{
- gotoxy(1,1);
- LCD_display("Date ");
- gotoxy(1,2);
- LCD_display("Time ");
-
- get_1302(time_1302);
- change();
- gotoxy(6,1);
- LCD_display(date);
- gotoxy(6,2);
- LCD_display(times);
-
- display_play(); //弹奏音乐
- }
- }
- }
- //外部0中断子函数
- void int0() interrupt 0
- {
- if(k8==0)
- {
- delay(5);
- while(k8==0);
- flag=~flag;
- D1=~D1;
- D2=~D2;
- }
- }
- //外部1中断子函数
- void int1() interrupt 2
- {
- if(k11==0&&flag==0)
- {
- delay(5);
- while(k11==0);
- TR0=0;
- i=0;
- music++;
- if(music>5)
- {
- music=0;
- }
- }
- }
- //定时器0中断子函数
- void t0() interrupt 1
- {
- TR0=0;
- if(music==1){
- TH0=table2[music_tab1[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab1[i]-1];
- }
- else if(music==2){
- TH0=table2[music_tab2[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab2[i]-1];
- }
- else if(music==3){
- TH0=table2[music_tab3[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab3[i]-1];
- }
- else if(music==4){
- TH0=table2[music_tab4[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab4[i]-1];
- }
- else if(music==5){
- TH0=table2[music_tab5[i]-1]; //取频率常数 和 节拍常数
- TL0=table3[music_tab5[i]-1];
- }
- beep=~beep;
- TR0=1;
- }
- //定时器1中断子函数
- void t1() interrupt 3
- {
- TR1=0;
- TH1=table2[7*bb+cc]; //取频率常数 和 节拍常数
-
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
Keil代码与Proteus仿真下载:
电子琴最终版.7z
(88.39 KB, 下载次数: 80)
|