0
点赞
收藏
分享

微信扫一扫

AI8051U单片机通过BEEP蜂鸣器播放生日快乐歌的完整程序

以下是针对AI8051U单片机通过BEEP蜂鸣器播放生日快乐歌的完整程序及说明:

程序功能

  • 通过BEEP引脚(假设为P1^0)连接蜂鸣器,播放《生日快乐》乐曲。
  • 使用定时器中断控制声调频率,通过延时函数控制节拍。

硬件连接

  1. 蜂鸣器:连接到单片机的P1^0引脚(BEEP)。
  2. 按键(可选):用于触发播放,连接到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();     // 防止重复触发
        }
    }
}

程序说明

  1. 音符与节拍编码
  • TABLE数组存储音符的节拍码,高4位为音符码(对应TABLE1中的定时器初值),低4位为节拍数。
  • TABLE1数组存储每个音符对应的定时器初值(高低字节),用于生成对应频率的方波。
  1. 定时器中断
  • 定时器0工作在模式1(16位定时器),通过中断周期性翻转BEEP引脚电平,产生方波驱动蜂鸣器发声。
  • 定时器初值根据音符频率计算,例如中音DO(523Hz)的初值为0xFB04
  1. 节拍控制
  • delay函数根据节拍码控制每个音符的持续时间,例如0x01表示1/4拍,0x04表示1拍。
  1. 按键触发(可选):
  • 通过K1引脚检测按键按下,触发PlayMusic函数开始播放。

调试与仿真

  1. Proteus仿真
  • 将蜂鸣器接至P1^0,按键接至P3^0
  • 点击按键后,蜂鸣器应依次播放《生日快乐》乐曲。
  1. 频率调整
  • 若实际频率与预期不符,检查TABLE1中的定时器初值是否正确,或调整晶振频率参数。
  1. 扩展功能
  • 添加LED显示当前音符或歌曲进度。
  • 支持多首歌曲切换或音量调节(通过调整方波占空比)。

注意事项

  • 确保TABLETABLE1数组的音符与节拍编码一致,否则会出现旋律错误。
  • 定时器初值需根据单片机晶振频率(如12MHz)重新计算,若使用其他频率需修正TABLE1的值。
  • 蜂鸣器为无源蜂鸣器,需通过方波驱动发声。

通过以上程序,AI8051U可成功播放《生日快乐》乐曲,用户可根据需求进一步优化功能或界面。

举报

相关推荐

0 条评论