微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 课程设计:电子琴(世上只有妈妈好)

课程设计:电子琴(世上只有妈妈好)

时间:09-13 来源:互联网 点击:

//proteus仿真

//单片机发生,就是用蜂鸣器简单的模拟歌曲的音调(用定时器来实现),并不是唱出歌曲(目前51我还没有听说过)

//主程序如下,实现功能是按下某个键后,数码管显示对应的按键号,如果是前三个键的话,发出(dao,ruai,mi)音符

//如果是第四个键的话,发出(世上只有妈妈好的歌曲音调)

//程序如下

#include

#define uchar unsigned char

sbit dula=P2^6; //如果是用实物的话,用到了

sbit wela=P2^7; //锁存器如果是proteu的话,就不需要了

sbit sound=P2^3; //定义蜂鸣器引脚

unsigned char i,j,key,k,m,time;

uchar STH0,STL0;

//共阳极数码管编码值

uchar code table[]={

0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,

0xc6,0xa1,0x86,0x8e};

//1,2,3,4对应的编码值

unsigned char code music[]={0x25,0x57,0x84,0x98};

//位选编码(这个也是如果是proteus的话,就不需要了,如果是实物的话,需要)

uchar code table1[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

//世上只有妈妈好数据表

code unsigned char sszymmh[]={

6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,

6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,

6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,

5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,

2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0

};

// 音阶频率表 高八位

code unsigned char FREQH[]={

0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,

0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i

0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,

0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF,

} ;

// 音阶频率表 低八位

code unsigned char FREQL[]={

0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,

0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i

0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,

0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16,

};

//函数声明

void display(uchar Duan_value,uchar Wei_value);

void delay(unsigned char t);

void delay1(uchar );

void display1(uchar value);

//播放歌曲音符函数

void song()

{

TH0=STH0;

TL0=STL0;

TR0=1;

delay1(time); //这个延时很重要,用来使某个音符放多长时间

}

//设置对应按键定时器初值函数

void key_on(unsigned char key)

{

m=0;

if(key!=3)

{

TMOD=0x01; //设置定时工作方式位t0方式1(16位定时器)

TH0=0xfe;

TL0=music[key]; //定时器附初值(根据音符对应的编码)

EA=1; //一次打开各个中断

ET0=1;

TR0=1;

display1(key+1);

while(P3!=0xff); //按键按起去抖动

TR0=0;

}

else //第四个键按下之后,来播放歌曲

{

TMOD=0x01; //设置定时工作方式位t0方式1(16位定时器)

TH0=0xfe;

TL0=music[key]; //定时器附初值(根据音符对应的编码)

EA=1; //一次打开各个中断

ET0=1;

TR0=0;

display1(key+1);

while(P3!=0xff); //按键按起去抖动

time=1;

while(time!=0) //歌曲播放完之后,time=0退出(终止符)

{

k=sszymmh[m]+7*sszymmh[m+1]-1;

STH0=FREQH[k];

STL0=FREQL[k];

time=sszymmh[m+2]; //这个模式是固定的,不用过多研究为啥+2

m=m+3;

song();

}

}

}

/*函数功能:播放音乐的节拍控制*/

void delay1(unsigned char t)

{

unsigned char t1;

unsigned long t2;

for(t1=0;t1

{

for(t2=0;t2<8000;t2++)

{

;

}

}

TR0=0;

}

//延时函数(单位ms)

void delay(unsigned char t)

{

unsigned char x,y;

for(x=t;t>0;t--)

for(y=111;y>0;y--);

}

//显示对应位选的数码管按键值(如果是实物的话所用到的)

/*void display(uchar Duan_value,uchar Wei_value)

{

dula=1;

P0=table[Duan_value];

dula=0;

wela=1;

P0=table1[Wei_value];

wela=0;

delay(3);

}*/

//显示函数

void display1(uchar value)

{

P0=table[value];

}

void main()

{

display1(key);

while(1)

{

if(P3==0xef) //第一个键按下

{

delay(10); //按键按下消抖

if(P3==0xef)

{

key=0;

key_on(key); //检测按键按下(并且在函数中来显示数据)

}

}

if(P3==0xdf) //第二个键按下

{

delay(10); //按键按下消抖

if(P3==0xdf)

{

key=1;

key_on(key);

}

}

if(P3==0xbf) //第三个键按下

{

delay(10);

if(P3==0xbf)

{

key=2;

key_on(key);

}

}

if(P3==0x7f) //第四个键按下

{

delay(10);

if(P3==0x7f)

{

key=3;

key_on(key);

}

}

}

}

//定时器1中断函数

void t0() interrupt 1

{

if(key!=3)

{

TH0=0xfe;

TL0=music[key

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top