标题:
51单片机电子琴毕业答辩程序
[打印本页]
作者:
十二期话费
时间:
2018-5-16 21:40
标题:
51单片机电子琴毕业答辩程序
51单片机电子琴毕业答辩源程序
单片机源程序如下:
#include <reg52.h>
#define SONG 4 // 歌曲的数量
#define uchar unsigned char // 以后unsigned char就可以用uchar代替
#define uint unsigned int // 以后unsigned int 就可以用uint 代替
#define ulong unsigned long // 以后unsigned long就可以用ulong代替
sbit Key1_P = P1^0; // 弹奏键1的管脚
sbit Key2_P = P1^1; // 弹奏键2的管脚
sbit Key3_P = P1^2; // 弹奏键3的管脚
sbit Key4_P = P1^3; // 弹奏键4的管脚
sbit Key5_P = P1^4; // 弹奏键5的管脚
sbit Key6_P = P1^5; // 弹奏键6的管脚
sbit Key7_P = P1^6; // 弹奏键7的管脚
sbit Key8_P = P1^7; // 弹奏键8的管脚
sbit Key9_P = P2^0; // 播放内置歌曲的按键管脚
sbit Beep_P = P3^7; // 扬声器管脚
uchar gTone=0; // gTone代表当前要播放的音调
uchar gPlayStatus; // gPlayStatus代表当前的播放状态,0是停止,1是播放
uchar gSong; // gSong代表当前播放到第几首歌
/* 定时器初值 低1 低2 低3 低4 低5 低6 低7 中1 中2 中3 中4 中5 中6 中7 高1 高2 高3 高4 高5 高6 高7 */
uchar code ArrTL0[]={ 140, 91, 21, 103, 4, 144, 12, 68, 121, 220, 52, 130, 200, 6, 34, 86, 133, 154, 193, 228, 3 };
uchar code ArrTH0[]={ 248, 249, 250, 250, 251, 251, 252, 252, 252, 252, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 255 };
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* 数码管的显示值 1 2 3 4 5 6 7 */
uchar code ArrDig[]={ 0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8};
/* 《水手》的乐谱 */
uchar code Music1[]={
5,4, 9,2, 8,2, 9,4, 8,2, 9,2,
10,3, 11,1, 10,2, 8,2, 9,8, 9,1,
10,2, 10,1, 9,1, 8,2, 7,1, 7,1, 8,2, 7,1, 7,1, 8,2, 9,2,
7,2, 6,2, 5,2, 7,2, 6,8,
5,4, 9,2, 8,2, 9,4, 8,2, 9,2,
10,2, 10,1, 11,1, 9,2, 8,2, 9,8,
10,3, 9,1, 8,2, 7,2, 8,2, 8,1, 7,1, 8,2, 8,1, 9,1,
6,2, 6,2, 5,2, 4,2, 5,8,
8,3, 8,1, 8,2, 8,2, 10,2, 10,1, 9,1, 8,2, 7,1, 7,1,
9,3, 8,1, 7,2, 8,1, 7,1, 5,8,
8,3, 8,1, 8,2, 8,2, 8,2, 8,1, 8,1, 8,2, 7,1, 8,1,
9,2, 9,2, 9,1, 8,1, 7,1, 8,1, 9,8,
8,3, 8,1, 8,2, 8,2, 10,2, 9,2, 8,2, 8,2,
9,2, 8,2, 7,2, 8,1, 7,1, 5,7, 5,1,
8,3, 8,1, 8,2, 8,1, 8,1, 8,2, 8,2, 7,2, 8,2,
9,2, 9,2, 8,2, 7,2, 9,4, 9,2, 11,2,
12,4, 11,4, 9,4, 8,2, 7,2,
8,2, 9,1, 8,1, 7,2, 6,2, 5,4, 5,2, 6,2,
7,4, 7,2, 9,2, 8,4, 6,1, 5,1, 4,2,
5,3, 5,1, 7,2, 8,2, 9,4, 9,2, 11,2,
12,4, 11,4, 9,4, 8,2, 7,2,
8,2, 9,1, 8,1, 7,2, 6,2, 5,4, 5,2, 6,2,
7,4, 7,2, 9,2, 8,4, 7,2, 6,2, 5,12
};
/* 《挥着翅膀的女孩》的乐谱 */
uchar code Music2[]={
9,4, 9,2, 10,2, 11,4, 7,2, 8,2,
9,2, 9,2, 9,2, 10,2, 11,4, 8,2, 9,2,
10,4, 10,2, 9,2, 7,4, 10,2, 9,2,
10,4, 5,2, 7,2, 8,4, 7,2, 8,2,
9,4, 9,2, 10,2, 11,4, 12,2, 13,2,
14,2, 14,2, 9,2, 10,2, 11,4, 8,2, 9,2,
10,2, 9,2, 10,2, 14,2, 14,4, 8,2, 9,2,
10,2, 9,2, 10,2, 15,2, 15,4, 14,2, 13,2,
14,6, 15,2, 16,2, 15,2, 14,2, 13,2,
14,6, 14,2, 13,2, 11,2, 11,2, 7,2,
12,6, 12,2, 11,2, 7,2, 7,2, 9,2,
8,6, 9,1, 10,1, 10,2, 11,2, 14,2, 13,2,
14,6, 15,2, 16,2, 15,2, 14,2, 13,2,
14,6, 14,2, 13,2, 11,2, 11,2, 7,2,
12,6, 12,2, 11,2, 11,2, 14,2, 13,2,
14,16
};
/* 《茉莉花》的乐谱 */
uchar code Music3[]={
9,4, 9,2, 11,2, 12,2, 14,2, 14,2, 12,2,
11,4, 11,2, 12,2, 11,8,
9,4, 9,2, 11,2, 12,2, 14,2, 14,2, 12,2,
11,4, 11,2, 12,2, 11,8,
11,4, 11,4, 11,4, 9,2, 11,2,
12,4, 12,4, 11,8,
9,4, 8,2, 9,2, 11,4, 9,2, 8,2,
7,4, 7,2, 8,2, 7,8,
9,2, 8,2, 7,2, 9,2, 8,6, 9,2,
11,4, 12,2, 14,2, 11,8,
8,4, 9,2, 11,2, 8,2, 9,2, 7,2, 5,2,
4,8, 5,4, 7,4,
8,6, 9,2, 7,2, 8,2, 7,2, 5,2,
4,12
};
/* 《欢乐颂》的乐谱 */
uchar code Music4[]={
9,2, 9,2, 10,2, 11,2,
11,2, 10,2, 9,2, 8,2,
7,2, 7,2, 8,2, 9,2,
9,3, 8,1, 8,4,
9,2, 9,2, 10,2, 11,2,
11,2, 10,2, 9,2, 8,2,
7,2, 7,2, 8,2, 9,2,
8,3, 7,1, 7,4,
8,2, 8,2, 9,2, 7,2,
8,2, 9,1, 10,1, 9,2, 7,2,
8,2, 9,1, 10,1, 9,2, 8,2,
7,2, 8,2, 4,2, 9,2,
9,2, 9,2, 10,2, 11,2,
11,2, 10,2, 9,2, 10,1, 8,1,
7,2, 7,2, 8,2, 9,2,
8,3, 7,1, 7,4
} ;
/*********************************************************/
// 毫秒级的延时函数,time是要延时的毫秒数
/*********************************************************/
void DelayMs(uint time)
{
uint i,j;
for(i=time;i>0;i--)
for(j=110;j>0;j--);
}
/*********************************************************/
// 发出指定音调及其节拍的声音,tone代表音调,beat代表节拍
/*********************************************************/
void PlayTone(uchar tone,float beat)
{
int i;
P0=ArrDig[tone%7]; // 数码管显示当前音调值
gTone=tone; // 将音调值赋给全局变量gTone
TH0 = ArrTH0[tone]; // 装入定时器TH0的初值
TL0 = ArrTL0[tone]; // 装入定时器TL0的初值
TR0=1; // 启动定时器
for(i=0;i<beat;i++)
{
DelayMs(200);
}
TR0=0; // 停止定时器
P0=0xff; // 关闭数码管显示
}
/*********************************************************/
// 播放内置的音乐
// arr[]是要播放的乐谱数组,num是数组里面的元素个数
/*********************************************************/
void PlayMusic(uchar music[],uint num)
{
uint i=0;
while(i<num)
{
if(gPlayStatus==1) // 判断播放状态是否为播放还是暂停
{
PlayTone(music[i],music[i+1]); // 开始演奏一个节拍
i+=2; // 进入下一个节拍,因为每2个数为1组,所以每次要加2
if(i==num) // 判断歌曲是否播放完了
{
gPlayStatus=0; // 播放完了的话,则把播放状态改为暂停,否则会循环播放
}
}
if(Key9_P==0) // 下一曲
{
DelayMs(10); // 消除按键按下的抖动
while(!Key9_P); // 等待按键释放
DelayMs(10); // 消除按键松开的抖动
gSong++; // 把当前播放到第几首歌的变量gSong加1,即切到下一曲
if(gSong>SONG) // 如果gSong为SONG,说明到后面的尽头了,则转为第一首
gSong=1;
break;
}
}
}
/*********************************************************/
// 定时器初始化函数
/*********************************************************/
void TimerInit()
{
TMOD=1; // 定时器0,工作方式1
TH0=0; // 装定时器TH0的初值
TL0=0; // 装定时器TL0的初值
ET0=1; // 开启定时器0中断
EA=1; // 开启总中断
}
/*********************************************************/
// 弹奏键扫描函数
/*********************************************************/
uchar KeyScanf()
{
if(Key1_P==0) // 按键1被按下,返回1
return 1;
if(Key2_P==0) // 按键2被按下,返回2
return 2;
if(Key3_P==0) // 按键3被按下,返回3
return 3;
if(Key4_P==0) // 按键4被按下,返回4
return 4;
if(Key5_P==0) // 按键5被按下,返回5
return 5;
if(Key6_P==0) // 按键6被按下,返回6
return 6;
if(Key7_P==0) // 按键7被按下,返回7
return 7;
if(Key8_P==0) // 按键8被按下,返回8
return 8;
return 0; // 8个按键都没被按下,返回0
}
/*********************************************************/
// 主函数,程序从这里开始执行
/*********************************************************/
void main()
{
uchar ret; // 用于保存音调键函数的返回值
TimerInit();
gSong=0; // 上电默认第一首歌
gPlayStatus=0; // 上电默认是0停止状态(1为播放状态)
while(1)
{
if(gPlayStatus==1) // 如果处于播放状态,则判断是哪一首歌曲需要播放
{
switch(gSong)
{
case 1 : PlayMusic(Music1,sizeof(Music1)); break;
case 2 : PlayMusic(Music2,sizeof(Music2)); break;
case 3 : PlayMusic(Music3,sizeof(Music3)); break;
case 4 : PlayMusic(Music4,sizeof(Music4)); break;
default: break;
}
}
if(Key9_P==0) // 开始播放
{
DelayMs(10); // 消除按键按下的抖动
while(!Key9_P); // 等待按键释放
DelayMs(10); // 消除按键松开的抖动
gSong++; // 把当前播放到第几首歌的变量gSong加1,即切到下一曲
if(gSong>SONG) // 如果gSong为SONG,说明到后面的尽头了,则转为第一首
gSong=1;
gPlayStatus=1; // 播放状态改为1,即播放
}
ret=KeyScanf();
if(ret!=0)
{
P0=ArrDig[(ret-1)%7]; // 数码管显示当前音调值
TH0 = ArrTH0[ret+6]; // 装入定时器TH0的初值
TL0 = ArrTL0[ret+6]; // 装入定时器TL0的初值
gTone=ret+6;
TR0=1;
while(KeyScanf()); // 等待按键释放
DelayMs(70); // 按键释放之后,再播放70毫秒,达到余音的效果
TR0=0; // 停止定时器
P0=0xff; // 关闭数码管显示
}
}
}
/*********************************************************/
// 功能:定时器0中断处理函数
/*********************************************************/
void time0() interrupt 1
{
Beep_P=!Beep_P; // 将控制扬声器的管脚取反
TH0=ArrTH0[gTone]; // 重装定时器TH0的初值
TL0=ArrTL0[gTone]; // 重装定时器TL0的初值
}
复制代码
所有资料51hei提供下载:
keil 版.zip
(33.86 KB, 下载次数: 17)
2018-5-16 21:39 上传
点击文件名下载附件
程序
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1