51单片机蜂鸣器通过按键暂停、播放与切换多首音乐
时间: 2023-08-10 10:03:54 浏览: 1056
51单片机之蜂鸣器七音【音乐七音】
好的,下面是一份基于51单片机的蜂鸣器多媒体播放器代码,实现了通过按键暂停、播放和切换多首音乐的功能。代码中使用了定时器和外部中断,具体实现细节已经在注释中说明。代码如下:
```c
#include <reg52.h>
// 定义每首音乐的频率和时长
unsigned int music1[] = {262, 294, 330, 349, 392, 440, 494, 523};
unsigned int music2[] = {523, 494, 440, 392, 349, 330, 294, 262};
unsigned int music3[] = {262, 294, 330, 349, 392, 440, 494, 523};
unsigned int *music = music1; // 当前播放的音乐,默认为第一首
unsigned int music_index = 0; // 当前播放的音符在音乐数组中的下标
unsigned int music_length = 8; // 当前音乐的长度
unsigned char play_flag = 1; // 播放标志位,1为播放,0为暂停
// 定时器0中断服务函数,控制蜂鸣器发声
void timer0_isr() interrupt 1
{
TH0 = 0xFF; // 加载初值
TL0 = 0x00;
if (play_flag) // 如果当前为播放状态
{
unsigned int freq = music[music_index]; // 获取当前音符的频率
if (freq == 0) // 如果当前音符为0,表示音乐播放完毕
{
music_index = 0; // 重新开始播放
}
else
{
unsigned int count = 1000000 / freq; // 根据频率计算定时器计数值
count = count / 2; // 由于每个音符需要两个定时器周期,所以计数值需要除以2
P1 = ~P1; // 反转P1口的状态,产生蜂鸣器声音
TH0 = count / 256; // 加载定时器计数值
TL0 = count % 256;
music_index++; // 播放下一个音符
}
}
}
// 外部中断0服务函数,切换到上一首音乐
void int0_isr() interrupt 0
{
music_index = 0; // 重新开始播放当前音乐
if (music == music1) // 切换到上一首音乐
{
music = music3;
}
else
{
music--; // 指向前一首音乐
}
music_length = 8; // 重新设置当前音乐的长度
}
// 外部中断1服务函数,切换到下一首音乐
void int1_isr() interrupt 2
{
music_index = 0; // 重新开始播放当前音乐
if (music == music3) // 切换到下一首音乐
{
music = music1;
}
else
{
music++; // 指向后一首音乐
}
music_length = 8; // 重新设置当前音乐的长度
}
// 主函数
void main()
{
// 初始化定时器0
TMOD = 0x01; // 定时器0工作在模式1:16位定时器,TH0和TL0分别为高8位和低8位
TH0 = 0xFF; // 初始值设为0xFFFF,定时1ms
TL0 = 0x00;
TR0 = 1; // 启动定时器0
ET0 = 1; // 允许定时器0中断
// 初始化外部中断
IT0 = 1; // INT0下降沿触发
IT1 = 1; // INT1下降沿触发
EX0 = 1; // 允许外部中断0
EX1 = 1; // 允许外部中断1
EA = 1; // 启用总中断
while (1)
{
if (P3 == 0xFE) // 如果P3.0为低电平,表示按键被按下
{
play_flag = !play_flag; // 翻转播放标志位,实现暂停/播放功能
while (P3 == 0xFE); // 等待按键释放
}
}
}
```
上述代码实现了三首音乐的播放,可以通过外部中断切换到上一首或下一首音乐。按下按键,可以实现暂停/播放功能。需要注意的是,由于定时器精度的限制,蜂鸣器发声的音质可能不太理想,可以通过调整定时器计数值来改善。
阅读全文