以下是针对AI8051U单片机通过BEEP蜂鸣器播放生日快乐歌的完整程序及说明:
程序功能
- 通过BEEP引脚(假设为
P1^0
)连接蜂鸣器,播放《生日快乐》乐曲。 - 使用定时器中断控制声调频率,通过延时函数控制节拍。
硬件连接
- 蜂鸣器:连接到单片机的
P1^0
引脚(BEEP)。 - 按键(可选):用于触发播放,连接到
P3^0
引脚(K1)。
程序代码
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
// 定义蜂鸣器引脚
sbit BEEP = P1^0;
// 定义按键引脚(可选)
sbit K1 = P3^0;
// 音符节拍码表(高4位:音符码,低4位:节拍)
uchar TABLE[] = {
0x82, 0x01, 0x81, 0x94, 0x84, 0xB4, 0xA4, 0x04, // 前半段
0x82, 0x01, 0x81, 0x94, 0x84, 0xC4, 0xB4, 0x04, // 副歌
0x82, 0x01, 0x81, 0xF4, 0xD4, 0xB4, 0xA4, 0x94, // 高潮
0xE2, 0x01, 0xE1, 0xD4, 0xB4, 0xC4, 0xB4, 0x04, // 结尾
0x00 // 结束标志
};
// 音符对应的定时器初值表(假设12MHz晶振,定时器模式1)
uchar TABLE1[] = {
0xFB, 0x04, 0xFB, 0x90, 0xFC, 0x09, 0xFC, 0x44, // C5, D5, E5, F5等
0xFC, 0xAC, 0xFD, 0x09, 0xFD, 0x34, 0xFD, 0x82, // G4, A4, B4, C5等
0xFD, 0xC8, 0xFE, 0x06, 0xFE, 0x22, 0xFE, 0x56, // D5, E5, F5, G5等
0xFE, 0x85, 0xFE, 0x9A, 0xFE, 0xC1 // A5, B4, C6等
};
// 全局变量
uchar tick, tl, th;
// 定时器0中断服务函数
void timer0_isr(void) interrupt 1 using 1 {
TL0 = tl; // 重装低8位初值
TH0 = th; // 重装高8位初值
BEEP = ~BEEP; // 翻转蜂鸣器电平
}
// 基本单位延时(约1ms)
void delay1() {
uint i;
for (i = 0; i < 20000; i++);
}
// 节拍延时函数
void delay(uchar tt) {
uchar i;
for (i = 0; i < tt; i++) delay1();
}
// 播放音乐函数
void PlayMusic() {
uchar k = 0; // 音符索引
while (TABLE[k] != 0) { // 未到结束标志
// 获取节拍码(低4位)
tick = TABLE[k] & 0x0F;
// 获取音符码(高4位)
uchar note_code = _crol_(TABLE[k], 4) & 0x0F;
if (note_code != 0) { // 非休止符
// 计算定时器初值索引(假设每个音符对应两个表项)
tl = TABLE1[2 * note_code];
th = TABLE1[2 * note_code + 1];
TMOD = 0x01; // 定时器0模式1
IE = 0x82; // 启用中断
TR0 = 1; // 启动定时器
} else {
TR0 = 0; // 休止符关闭定时器
}
delay(tick); // 节拍延时
k++; // 下一个音符
}
TR0 = 0; // 播放结束关闭定时器
}
// 主函数
void main() {
while (1) {
if (K1 == 1) { // 检测按键触发(可选)
PlayMusic(); // 播放音乐
delay1(); // 防止重复触发
}
}
}
程序说明
- 音符与节拍编码:
TABLE
数组存储音符的节拍码,高4位为音符码(对应TABLE1
中的定时器初值),低4位为节拍数。TABLE1
数组存储每个音符对应的定时器初值(高低字节),用于生成对应频率的方波。
- 定时器中断:
- 定时器0工作在模式1(16位定时器),通过中断周期性翻转BEEP引脚电平,产生方波驱动蜂鸣器发声。
- 定时器初值根据音符频率计算,例如中音DO(523Hz)的初值为
0xFB04
。
- 节拍控制:
delay
函数根据节拍码控制每个音符的持续时间,例如0x01
表示1/4拍,0x04
表示1拍。
- 按键触发(可选):
- 通过
K1
引脚检测按键按下,触发PlayMusic
函数开始播放。
调试与仿真
- Proteus仿真:
- 将蜂鸣器接至
P1^0
,按键接至P3^0
。 - 点击按键后,蜂鸣器应依次播放《生日快乐》乐曲。
- 频率调整:
- 若实际频率与预期不符,检查
TABLE1
中的定时器初值是否正确,或调整晶振频率参数。
- 扩展功能:
- 添加LED显示当前音符或歌曲进度。
- 支持多首歌曲切换或音量调节(通过调整方波占空比)。
注意事项
- 确保
TABLE
和TABLE1
数组的音符与节拍编码一致,否则会出现旋律错误。 - 定时器初值需根据单片机晶振频率(如12MHz)重新计算,若使用其他频率需修正
TABLE1
的值。 - 蜂鸣器为无源蜂鸣器,需通过方波驱动发声。
通过以上程序,AI8051U可成功播放《生日快乐》乐曲,用户可根据需求进一步优化功能或界面。