//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]; } else { TH0=STH0; TL0=STL0; } sound=~sound; //蜂鸣器取反(产生脉冲) }
上一篇:矩阵键盘加电子时钟(c51)
下一篇:课程设计:矩阵键盘(c51,使用扫描法实现)
推荐阅读最新更新时间:2024-03-16 15:09
设计资源 培训 开发板 精华推荐
- 提交创意【免费赢取600元DIY物料】,参赛冲击万元大奖!2022得捷电子创新设计大赛火热报名中
- TI DLP 有奖创意征集
- 夏末狂欢,观看TI 课程有好礼!
- 手印签到,共同见证 TI 中国大学计划20周年
- TI SensorTag创意设计大赛重磅开启!
- 【EEWORLD第三十六届】2012年03月社区明星人物揭晓!
- 夏末狂欢,观看TI 课程有好礼!
- 了解Keithley 4200-SCS参数分析仪,下载技术文章,抽奖赢礼!
- 【EEWORLD第三十届】2011年09月社区明星人物揭晓!
- Maxim 利用nanoPower创新技术,致力于降低系统的静态功耗 看视频答题赢好礼! 还有免费开发板等你拿