单片机:实现生日快乐歌(附带源码)

单片机实现《生日快乐歌》

实现一个"生日快乐歌"是单片机应用中的一个经典项目,通过它可以学习如何控制声音输出、使用定时器、以及如何处理按键输入等功能。本项目将利用单片机生成《生日快乐歌》的音频信号,并通过蜂鸣器播放出来。

项目目标

本项目的目标是设计并实现一个基于8051单片机的"生日快乐歌"播放系统。系统会通过蜂鸣器输出《生日快乐歌》的旋律,当按下一个按键时,系统播放这首歌。

一、硬件设计
1.1 单片机选择

本项目采用8051单片机,它具备丰富的I/O端口,可以与蜂鸣器连接,并且支持定时器,可以用来产生音频信号。

1.2 外部硬件
  • 蜂鸣器:作为输出设备,通过蜂鸣器发出不同频率的音符,模拟乐曲的旋律。
  • 按键:用于触发《生日快乐歌》的播放。假设使用一个简单的按键,按下时开始播放歌曲。
  • 定时器:用定时器来产生一定频率的脉冲信号,以控制蜂鸣器发出不同的音高。
  • 电源和电阻:用于电路的供电和保护。
1.3 硬件连接
  1. 蜂鸣器连接:蜂鸣器连接到P1.0端口,利用PWM信号驱动蜂鸣器发出声音。
  2. 按键连接:按键连接到P3.0端口,用来触发播放《生日快乐歌》。
二、系统设计
2.1 功能模块
  1. 音符生成模块:通过定时器产生不同频率的脉冲信号,驱动蜂鸣器发出不同频率的声音,形成音符。
  2. 按键触发模块:通过按键输入,触发歌曲的播放。
  3. 歌曲存储和播放模块:存储《生日快乐歌》中的音符频率和时长,依次播放。
2.2 数据结构
  • 音符频率:将歌曲中的每个音符频率(如C4、D4等)存储为一个数组,方便播放。
  • 音符时长:每个音符的时长也可以通过数组存储,控制每个音符的持续时间。
  • 当前音符:当前播放的音符。
2.3 歌曲结构

《生日快乐歌》的音符和时长如下(以C4为基础音符):

音符 频率(Hz) 时长(ms)
C4 261.63 400
C4 261.63 400
D4 293.66 400
C4 261.63 800
F4 349.23 400
F4 349.23 400
E4 329.63 400
C4 261.63 800
C4 261.63 400
C4 261.63 400
D4 293.66 400
C4 261.63 800
三、程序设计
3.1 定时器中断

利用定时器中断来生成频率对应的音符。通过设置定时器初值,可以生成一定频率的脉冲信号,从而控制蜂鸣器发出相应的音符。

3.2 主程序框架
  1. 初始化定时器和蜂鸣器
  2. 按键扫描:监听按键的输入,当按下按键时触发歌曲播放。
  3. 音符生成和播放:根据音符的频率和时长,通过定时器产生相应的脉冲信号,控制蜂鸣器的鸣响。
  4. 音符播放结束后继续播放下一音符,直到歌曲播放完毕。
3.3 代码实现
cpp 复制代码
#include <reg51.h>   // 包含8051的寄存器定义

// 定义蜂鸣器连接端口
#define BEEP P1_0

// 定义按键连接端口
#define BUTTON P3_0

// 定义音符的频率(单位:Hz)
#define C4 261
#define D4 293
#define E4 329
#define F4 349

// 定义音符时长(单位:毫秒)
#define NOTE_DURATION 400  // 默认音符时长

// 定义音符数组,按照《生日快乐歌》的音符顺序
unsigned int melody[] = {C4, C4, D4, C4, F4, F4, E4, C4, C4, C4, D4, C4};
unsigned int melody_duration[] = {NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION, NOTE_DURATION};

// 定时器初始化,产生固定频率的脉冲
void timer0_init() {
    TMOD = 0x01;  // 设置定时器0为模式1(16位定时器)
    IE = 0x82;    // 使能定时器中断
    TR0 = 1;      // 启动定时器0
}

// 延时函数(单位:毫秒)
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 120; j++) {
            // 空循环,产生延时
        }
    }
}

// 播放音符
void play_tone(unsigned int frequency, unsigned int duration) {
    unsigned int i;
    unsigned int delay_time = 1000000 / frequency;  // 计算每个周期的延时
    unsigned int cycles = frequency * duration / 1000;  // 计算音符持续的周期数
    
    for (i = 0; i < cycles; i++) {
        BEEP = 1;  // 启动蜂鸣器
        delay_ms(delay_time / 2);  // 延时一半周期
        BEEP = 0;  // 关闭蜂鸣器
        delay_ms(delay_time / 2);  // 延时另一半周期
    }
}

// 按键扫描函数
unsigned char key_scan() {
    if (BUTTON == 0) {
        delay_ms(20);  // 去抖动
        return 1;  // 按键被按下
    }
    return 0;
}

// 主程序
void main() {
    unsigned int i;
    timer0_init();  // 初始化定时器
    
    while (1) {
        if (key_scan()) {  // 如果按键被按下
            for (i = 0; i < sizeof(melody) / sizeof(melody[0]); i++) {
                play_tone(melody[i], melody_duration[i]);  // 播放音符
                delay_ms(100);  // 音符之间的间隔
            }
        }
    }
}
四、程序说明
  1. 定时器初始化timer0_init()函数初始化定时器0为模式1(16位定时器),启用定时器中断来产生音频信号。
  2. 按键扫描key_scan()函数用来检测按键是否被按下,若按键按下,则启动播放《生日快乐歌》。
  3. 音符播放play_tone()函数根据音符的频率和时长,生成脉冲信号,控制蜂鸣器发出相应的音符。
  4. 音符和时长数组melody[]数组存储《生日快乐歌》的音符,melody_duration[]数组存储每个音符的时长。
五、优化与扩展
  1. 多音符支持:可以扩展音符数组,增加更多的音符和歌曲。
  2. 使用LCD显示:通过LCD显示屏显示歌曲的进度或歌曲名。
  3. 音量调节:通过PWM信号控制蜂鸣器的音量,提供音量调节功能。
  4. 多段歌曲支持:将不同的歌曲分段存储,增加多种歌曲选择功能。
六、总结

通过本项目,我们学习了如何通过单片机控制蜂鸣器发出不同频率的声音,模拟乐曲的旋律。同时,这个项目也展示了如何用8051单片机处理定时器、按键输入和音符生成等基本功能。

相关推荐
代码游侠10 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
CODECOLLECT14 小时前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen15 小时前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠17 小时前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件
Lsir10110_17 小时前
【Linux】中断 —— 操作系统的运行基石
linux·运维·嵌入式硬件
深圳市九鼎创展科技20 小时前
瑞芯微 RK3399 开发板 X3399 评测:高性能 ARM 平台的多面手
linux·arm开发·人工智能·单片机·嵌入式硬件·边缘计算
辰哥单片机设计20 小时前
STM32项目分享:车辆防盗报警系统
stm32·单片机·嵌入式硬件
小龙报21 小时前
【51单片机】从 0 到 1 玩转 51 蜂鸣器:分清有源无源,轻松驱动它奏响新年旋律
c语言·数据结构·c++·stm32·单片机·嵌入式硬件·51单片机
范纹杉想快点毕业21 小时前
嵌入式与单片机开发核心学习指南——从思维转变到第一性原理的深度实践
单片机·嵌入式硬件
Industio_触觉智能21 小时前
瑞芯微RK3566开发板规格书,详细参数配置,型号EVB3566-V1,基于RK3566核心板SOM3566邮票孔封装
嵌入式硬件·开发板·rk3568·rk3566·核心板·瑞芯微