当前位置:网站首页>STC-B学习板蜂鸣器播放音乐
STC-B学习板蜂鸣器播放音乐
2022-07-06 09:24:00 【芜湖韩金轮】
功能:单片机烧录好程序后,按key1按键播放《IF YOU》,再次按key1可暂停播放,按key2可切换歌曲到《国际歌》,再按key3可切换歌曲到《孤勇者》
芯片:STC15F2K61S2
完整工程文件和hex文件在这
提取码:1111
前言:相信大家焊好板子后最喜欢玩的就是蜂鸣器播放音乐,路过每个教室基本都是各种杂音,毕竟这玩意真挺好玩的,于是我就根据老师的代码和谱子写了播放其他歌曲的文件(国际歌是我直接拿往届学长的音乐代码,来凑个数的),说实话这玩意看起来挺简单的,实际上挺难的,还得学一遍乐理知识,然后对着各种拍子和音调不断调试才能得到一个比较理想的状态,但是if you和孤勇者这两首曲子总感觉有些地方不是很完美,但对于摆烂人来说能听就行了。反正也是娱乐娱乐
废话不多说,代码如下:(谱子在最后)
/**********************
文件名称:beep.c
说明:进行音乐播放的例程,按下key1键后开始播放音乐
修改记录:
***********************/
/**********************
基于STC15F2K60S2系列单片机C语言编程实现
使用如下头文件,不用另外再包含"REG51.H"
***********************/
#include <STC15F2K60S2.h>
#define uint unsigned int
#define uchar unsigned char
sbit beep=P3^4; //蜂鸣器
sbit key1=P3^2; //按键1
sbit key2=P3^3; //按键2
uchar timeh,timel,jindu=0,gequ=0; //定义定时器的重装值
bit flag; //播放标志位
uchar code music1[] = //音乐代码,歌曲为《IF YOU》,格式为: 音符, 节拍, 音符, 节拍,
{
0x26,0x10,
0x25,0x10,
0x23,0x10,
0x21,0x10,
0x22,0x10,
0x23,0x10,
0x16,0x20,
0x22,0x08,
0x21,0x08,
0x22,0x08,
0x21,0x08,
0x22,0x08,
0x21,0x08,
0x22,0x10,
0x21,0x08,
0x22,0x08,
0x22,0x08,
0x21,0x08,
0x23,0x20,
0x26,0x10,
0x25,0x10,
0x23,0x10,
0x21,0x10,
0x22,0x10,
0x23,0x10,
0x16,0x20,
0x16,0x08,
0x17,0x10,
0x21,0x08,
0x21,0x08,
0x16,0x08,
0x21,0x08,
0x16,0x08,
0x21,0x08,
0x22,0x08,
0x23,0x08,
0x22,0x08,
0x22,0x10,
0x21,0x08,
0x21,0x08,
0x21,0x10,
0x15,0x08,
0x21,0x20,
0x31,0x10,
0x31,0x08,
0x31,0x08,
0x27,0x08,
0x26,0x08,
0x21,0x10,
0x32,0x10,
0x33,0x10,
0x36,0x10,
0x35,0x10,
0x33,0x10,
0x32,0x10,
0x31,0x10,
0x32,0x30,
0x32,0x08,
0x31,0x08,
0x32,0x08,
0x23,0x08,
0x32,0x10,
0x25,0x24,
0x25,0x08,
0x32,0x08,
0x31,0x08,
0x32,0x08,
0x33,0x24,
0x31,0x08,
0x31,0x10,
0x32,0x10,
0x33,0x10,
0x36,0x10,
0x35,0x10,
0x33,0x10,
0x32,0x10,
0x31,0x08,
0x31,0x08,
0x32,0x10,
0x31,0x30,
0x26,0x08,
0x26,0x08,
0x31,0x08,
0x26,0x08,
0x31,0x08,
0x31,0x24,
0x31,0x08,
0x31,0x08,
0x32,0x08,
0x31,0x08,
0x31,0x08,
0x31,0x24,
0x00,0x10,
};
uchar code music2[] = //歌曲为国际歌
{
0x25, 0x10, 0x31, 0x18, 0x27, 0x08, 0x32, 0x08, 0x31, 0x08, 0x25, 0x08, 0x23, 0x08, 0x26, 0x18, 0x26, 0x08, 0x24, 0x10, 0x20, 0x08,
0x26, 0x08, 0x32, 0x18, 0x31, 0x08, 0x27, 0x08, 0x26, 0x08, 0x25, 0x08, 0x24, 0x08, 0x23, 0x30,
0x25, 0x10, 0x31, 0x18, 0x27, 0x08, 0x32, 0x08, 0x31, 0x08, 0x25, 0x08, 0x23, 0x08, 0x26, 0x20, 0x24, 0x08,
0x26, 0x08, 0x32, 0x08, 0x31, 0x08, 0x27, 0x10, 0x32, 0x10, 0x34, 0x10, 0x27, 0x10, 0x31, 0x20, 0x31, 0x08, 0x30, 0x08,
0x33, 0x08, 0x32, 0x08, 0x27, 0x20, 0x26, 0x08, 0x27, 0x08, 0x31, 0x08, 0x26, 0x08, 0x27, 0x20, 0x25, 0x08,
0x25, 0x08, 0x24, 0x08, 0x25, 0x08, 0x26, 0x18, 0x26, 0x08, 0x32, 0x18, 0x31, 0x08, 0x27, 0x20, 0x27, 0x08, 0x20, 0x08,
0x32, 0x10, 0x32, 0x18, 0x27, 0x08, 0x25, 0x08, 0x25, 0x08, 0x24, 0x08, 0x25, 0x08, 0x33, 0x20, 0x31, 0x08,
0x26, 0x08, 0x27, 0x08, 0x31, 0x08, 0x27, 0x10, 0x32, 0x10, 0x31, 0x10, 0x26, 0x10, 0x25, 0x20, 0x25, 0x08, 0x20, 0x08,
0x33, 0x08, 0x32, 0x08, 0x31, 0x20, 0x25, 0x18, 0x23, 0x08, 0x26, 0x20, 0x24, 0x08, 0x20, 0x08,
0x32, 0x0c, 0x31, 0x04, 0x27, 0x20, 0x26, 0x10, 0x25, 0x10, 0x25, 0x20, 0x25, 0x08, 0x20, 0x08,
0x25, 0x10, 0x33, 0x20, 0x32, 0x10, 0x25, 0x10, 0x31, 0x20, 0x27, 0x18,
0x27, 0x08, 0x26, 0x18, 0x25, 0x08, 0x26, 0x10, 0x32, 0x10, 0x32, 0x20, 0x32, 0x08, 0x30, 0x08,
0x33, 0x0c, 0x32, 0x04, 0x31, 0x20, 0x25, 0x18, 0x23, 0x08, 0x26, 0x20, 0x24, 0x08, 0x20, 0x08,
0x32, 0x0c, 0x31, 0x04, 0x27, 0x20, 0x26, 0x10, 0x25, 0x10, 0x33, 0x30,
0x33, 0x10, 0x35, 0x20, 0x34, 0x10, 0x33, 0x10, 0x32, 0x18, 0x33, 0x08, 0x34, 0x10, 0x30, 0x08,
0x34, 0x08, 0x33, 0x18, 0x33, 0x08, 0x32, 0x18, 0x32, 0x08, 0x31, 0x30,
0x00, 0x00
};
uchar code music3[] = //歌曲为孤勇者
{
0x16,0x08,0x17,0x08,
0x21,0x08,0x22,0x08,
0x17,0x08,0x21,0x08,
0x21,0x10,0x21,0x08,
0x17,0x08,0x21,0x08,
0x22,0x08,0x17,0x08,
0x21,0x08,0x21,0x10,
0x21,0x08,0x22,0x08,
0x23,0x08,0x22,0x08,
0x23,0x08,0x22,0x08,
0x23,0x10,0x23,0x08,
0x22,0x08,0x23,0x10,
0x25,0x10,0x23,0x10,
0x16,0x08,0x17,0x08,
0x21,0x08,0x22,0x08,
0x17,0x08,0x21,0x08,
0x21,0x10,0x21,0x08,
0x17,0x08,0x21,0x08,
0x22,0x08,0x17,0x08,
0x21,0x08,0x21,0x10,
0x21,0x08,0x22,0x08,
0x23,0x08,0x22,0x08,
0x23,0x08,0x22,0x08,
0x23,0x10,0x23,0x08,
0x22,0x08,0x23,0x10,
0x25,0x10,0x23,0x10,
0x25,0x10,0x23,0x14,
0x25,0x08,0x23,0x14,
0x25,0x08,0x23,0x08,
0x25,0x08,0x26,0x08,
0x23,0x08,0x25,0x10,
0x25,0x08,0x23,0x14,
0x25,0x08,0x23,0x14,
0x25,0x08,0x23,0x08,
0x25,0x08,0x26,0x08,
0x23,0x08,0x25,0x10,
0x25,0x08,0x25,0x08,
0x23,0x08,0x22,0x08,
0x22,0x10,0x22,0x10,
0x21,0x08,0x23,0x08,
0x23,0x08,0x22,0x08,
0x22,0x10,0x22,0x10,
0x21,0x08,0x21,0x08,
0x16,0x20,0x25,0x08,
0x25,0x08,0x23,0x08,
0x22,0x08,0x22,0x10,
0x22,0x10,0x21,0x08,
0x23,0x08,0x23,0x08,
0x22,0x08,0x22,0x10,
0x22,0x10,0x21,0x08,
0x21,0x08,0x16,0x20,
0x00
};
uchar code quzi[] = //此数组数据为各个音符在定时器中的重装值,第一列是高位,第二列是低位 //时间
{
0xf8,0x8c, //低八度,低1
0xf9,0x5b,
0xfa,0x15, //低3
0xfa,0x67,
0xfb,0x04, //低5
0xfb,0x90,
0xfc,0x0c, //低7
0xfc,0x44, //中央C调
0xfc,0xac, //中2
0xfd,0x09,
0xfd,0x34, //中4
0xfd,0x82,
0xfd,0xc8, //中6
0xfe,0x06,
0xfe,0x22, //高八度,高1
0xfe,0x56,
0xfe,0x6e, //高3
0xfe,0x9a,
0xfe,0xc1, //高5
0xfe,0xe4,
0xff,0x03 //高7
};
/**********************
函数名称:void delay(unsigned int xms)
功能描述:延时
入口参数:xms:输入需要延时的毫秒值
出口参数:无
备注:
***********************/
void delay(unsigned int xms)
{
uint i,j;
for(i=xms; i>0; i--)
for(j=124; j>0; j--);
}
/**********************
函数名称:uchar quyin(uchar tem)
功能描述:在quzi数组中,找到music数组定义的简谱音符的重装值,并返回其在quzi数组中的位置
入口参数:tem:music数组中定义的简谱音符
出口参数:返回的是tem音符在quzi数组中的位置值
备注:
***********************/
uchar quyin(uchar tem)
{
uchar qudiao,jp,weizhi; //定义曲调,音符和位置
qudiao=tem/16; //高4位是曲调值
jp=tem%16; //低4位是音符
if(qudiao==1) //当曲调值为1时,即是低八度,低八度在quzi数组中基址为0
qudiao=0;
else if(qudiao==2) //当曲调值为2时,即是中八度,中八度在quzi数组中基址为14
qudiao=14;
else if(qudiao==3) //当曲调值为3时,即是高八度,高八度在quzi数组中,基址为28
qudiao=28;
weizhi=qudiao+(jp-1)*2; //通过基址加上音符作为偏移量,即可定位此音符在quzi数组中的位置
return weizhi; //返回这一个位置值
}
/**********************
函数名称:void playmusic()
功能描述:播放音乐
入口参数:无
出口参数:无
备注:
***********************/
void playmusic()
{
uchar p,m,tem; //m为节拍
while(1)
{
if(flag==1) //若播放的标志位为1则播放音乐
{
if(gequ==0) //歌曲选择位为0,则播放同一首歌
{
p=music1[jindu];
if(p==0x00) //如果碰到结束符,延时1秒,回到开始再来一遍
{
jindu=0;
delay(1000);
break;
}
else if(p==0xff) //若碰到休止符,延时100ms,继续取下一音符
{
jindu=jindu+1;
delay(100);
TR0=0;
break;
}
else //正常情况下取音符和节拍
{
tem=quyin(music1[jindu]); //取出当前音符在quzi数组中的位置值
timeh=quzi[tem]; //把音符相应的计时器重装载值赋予timeh和timel
timel=quzi[tem+1];
jindu++;
TH0=timeh; //把timeh和timel赋予计时器
TL0=timel;
m=music1[jindu]; //取得节拍
jindu++;
}
TR0=1; //开定时器1
delay(m*180); //等待节拍完成, 通过P3^4口输出音频
TR0=0; //关定时器1
beep=0; //使beep端口置0,起保护蜂鸣器作用
}
else if(gequ==1) //歌曲选择位为1,则播放小毛驴
{
p=music2[jindu];
if(p==0x00) //如果碰到结束符,延时1秒,回到开始再来一遍
{
jindu=0;
delay(1000);
break;
}
else if(p==0xff) //若碰到休止符,延时100ms,继续取下一音符
{
jindu=jindu+1;
delay(100);
TR0=0;
break;
}
else //正常情况下取音符和节拍
{
tem=quyin(music2[jindu]); //取出当前音符在quzi数组中的位置值
timeh=quzi[tem]; //把音符相应的计时器重装载值赋予timeh和timel
timel=quzi[tem+1];
jindu++;
TH0=timeh; //把timeh和timel赋予计时器
TL0=timel;
m=music2[jindu]; //取得节拍
jindu++;
}
TR0=1; //开定时器1
delay(m*300); //等待节拍完成, 通过P3^4口输出音频
TR0=0; //关定时器1
beep=0; //使beep端口置0,起保护蜂鸣器作用
}
else if(gequ==2) //歌曲选择位为2,则播放天空之城
{
p=music3[jindu];
if(p==0x00) //如果碰到结束符,延时1秒,回到开始再来一遍
{
jindu=0;
delay(1000);
break;
}
else if(p==0xff) //若碰到休止符,延时100ms,继续取下一音符
{
jindu=jindu+1;
delay(100);
TR0=0;
break;
}
else //正常情况下取音符和节拍
{
tem=quyin(music3[jindu]); //取出当前音符在quzi数组中的位置值
timeh=quzi[tem]; //把音符相应的计时器重装载值赋予timeh和timel
timel=quzi[tem+1];
jindu++;
TH0=timeh; //把timeh和timel赋予计时器
TL0=timel;
m=music3[jindu]; //取得节拍
jindu++;
}
TR0=1; //开定时器1
delay(m*200); //等待节拍完成, 通过P3^4口输出音频
TR0=0; //关定时器1
beep=0; //使beep端口置0,起保护蜂鸣器作用
}
}
else //播放标志位不为1时,暂停播放音乐
while(flag!=1);
}
}
/**********************
函数名称:void init_sys()
功能描述:系统初始化,功能是配置IO口
入口参数:无
出口参数:无
备注:
***********************/
void init_sys()
{
P0M0=0xff; //设置推挽模式
P0M1=0x00;
P2M0=0x08;
P2M1=0x00;
P3M0=0x10;
P3M1=0x00;
P4M0=0x00;
P4M1=0x00;
P5M0=0x00;
P5M1=0x00;
}
/**********************
函数名称:void init()
功能描述:定时器和外部中断的初始化
入口参数:无
出口参数:无
备注:
***********************/
void init()
{
TMOD=0x01; //设置定时器0,定时方式1,16位手动重装模式
TH0=0xD8; //设置定时初值
TL0=0xEF;
IE=0x87; // 1000 0111 EA=1,EX0=1,ET0=1,EX1=0;
IP=0x02; // 0000 0010 PT0=1; 定时器0优先级高
TR0=0; //定时器0开始运行
beep=0; //使beep端口置0,起保护蜂鸣器作用
}
void main()
{
init_sys(); //系统初始化
init();
P0=0x00;
key1=1; //两个按键设为输入状态,检测中断
key2=1;
flag=0; //播放标志位清零
while(1)
{
playmusic(); //播放音乐函数
}
}
/**********************
函数名称:void tim1() interrupt 1
功能描述:定时器0中断处理,重新装值,并把beep值取反,产生方波
入口参数:无
出口参数:无
备注:
***********************/
void tim1() interrupt 1 //计时器控制频率
{
TH0=timeh; //赋初值
TL0=timel;
beep=~beep; //中断使得beep翻转产生方波
}
/**********************
函数名称:void ex1() interrupt 0
功能描述:按下按键1的外部中断,对标志位取反,功能是暂停和播放音乐
入口参数:无
出口参数:无
备注:
***********************/
void ex1() interrupt 0
{
delay(5);
if(key1==0) //判断key1是否按下
{
delay(5);
if(key1==0)
{
while(!key1);
flag=~flag; //播放中断位取反,播放或者暂停
}
}
}
/**********************
函数名称:void ex2() interrupt 2
功能描述:按下按键2的外部中断,作用为切换歌曲
入口参数:无
出口参数:无
备注:
***********************/
void ex2() interrupt 2
{
delay(5);
if(key2==0) //按键key2按下,切换歌曲
{
jindu=0; //歌曲的进度清零,从头开始演唱
gequ++; //下一曲
if(gequ==3) //到达最后一首调到第一首
gequ=0;
}
}
边栏推荐
- High concurrency programming series: 6 steps of JVM performance tuning and detailed explanation of key tuning parameters
- Statistics 8th Edition Jia Junping Chapter 12 summary of knowledge points of multiple linear regression and answers to exercises after class
- SystemVerilog discusses loop loop structure and built-in loop variable I
- 《统计学》第八版贾俊平第一章课后习题及答案总结
- 【指针】统计一字符串在另一个字符串中出现的次数
- Uibutton status exploration and customization
- Quaternion -- basic concepts (Reprint)
- 关于交换a和b的值的四种方法
- Matplotlib绘图快速入门
- How to learn automated testing in 2022? This article tells you
猜你喜欢
《统计学》第八版贾俊平第十一章一元线性回归知识点总结及课后习题答案
《统计学》第八版贾俊平第四章总结及课后习题答案
1.支付系统
Statistics 8th Edition Jia Junping Chapter 3 after class exercises and answer summary
Don't you even look at such a detailed and comprehensive written software test question?
移植蜂鸟E203内核至达芬奇pro35T【集创芯来RISC-V杯】(一)
Based on authorized access, cross host, and permission allocation under sqlserver
Login the system in the background, connect the database with JDBC, and do small case exercises
Query method of database multi table link
Statistics, 8th Edition, Jia Junping, Chapter 6 Summary of knowledge points of statistics and sampling distribution and answers to exercises after class
随机推荐
Pointers: maximum, minimum, and average
Mysql的事务是什么?什么是脏读,什么是幻读?不可重复读?
1.支付系统
What is an index in MySQL? What kinds of indexes are commonly used? Under what circumstances will the index fail?
函数:字符串反序存放
Fundamentals of digital circuits (II) logic algebra
【指针】求字符串的长度
Résumé des points de connaissance et des réponses aux exercices après la classe du chapitre 7 de Jia junping dans la huitième édition des statistiques
Statistics, 8th Edition, Jia Junping, Chapter VIII, summary of knowledge points of hypothesis test and answers to exercises after class
Flash implements forced login
My first blog
Wang Shuang's detailed learning notes of assembly language II: registers
函数:求1-1/2+1/3-1/4+1/5-1/6+1/7-…+1/n
[pointer] solve the last person left
[issue 18] share a Netease go experience
Binary search tree concept
New version of postman flows [introductory teaching chapter 01 send request]
Interview Essentials: what is the mysterious framework asking?
Uibutton status exploration and customization
Statistics 8th Edition Jia Junping Chapter 2 after class exercises and answer summary