音乐是人类生活中不可或缺的一部分,利用电子设备播放简单的音乐可以应用于许多场景,如报警系统、电子玩具等。本项目使用ATmega16单片机和蜂鸣器,通过编程实现了一首简短的音乐《天空之城》的播放。通过这个项目,可以加深对单片机定时器、PWM(脉宽调制)以及蜂鸣器等硬件的理解和应用。
本系统由以下主要部分组成:
ATmega16单片机:核心控制器,负责音乐数据的处理、定时器的设置以及蜂鸣器的控制。
蜂鸣器:通过PWM信号驱动发声,播放指定频率的音符。
LCD1602显示屏:用于显示当前播放的音乐名称或其他提示信息。
音符频率定义:根据音乐的音阶,定义各个音符的频率。使用宏定义简化音符的频率设置。
定时器设置:利用单片机的定时器1产生PWM信号,驱动蜂鸣器发出不同频率的声音。
音乐播放控制:通过数组存储音乐音符和对应的节拍长度,根据数组内容依次播放各个音符,并控制节拍时长。
蜂鸣器:连接到ATmega16的PD5引脚,通过PWM信号控制发声。
LCD1602显示屏:连接到单片机的PORTD,用于显示当前播放的音乐名称。
I/O口配置:
将PD5配置为输出模式,用于输出PWM信号驱动蜂鸣器。
将PORTB配置为输出模式,用于控制音符的频率显示。
定时器配置:
初始化模块:初始化LCD显示屏、蜂鸣器及定时器。
音乐数据模块:定义音乐音符及对应的节拍长度。
播放控制模块:根据音乐数据,依次播放每个音符并控制节拍时长。
显示模块:在LCD显示屏上显示当前播放的音乐名称。
timer1_init():初始化定时器1,配置为CTC模式,设置PWM信号输出。
contorl_A():根据音符频率,设置PORTB的输出状态,用于调试和显示。
delay1():实现节拍控制的延时函数。
main():主函数,初始化系统并循环播放音乐。
系统初始化:初始化LCD显示屏、蜂鸣器及定时器,并显示初始信息。
音乐播放:从音乐数组中读取音符频率和节拍长度,设置定时器输出PWM信号驱动蜂鸣器发声。
节拍控制:根据节拍数组控制每个音符的播放时长,通过延时函数实现。
使用宏定义各个音符的频率,简化代码编写:
c#define L1 262
#define L2 286
#define L3 311
#define L4 349
#define L5 392
#define L6 440
#define L7 494
#define Z1 523
#define Z2 587
#define Z3 659
#define Z4 698
#define Z5 784
#define Z6 880
#define Z7 987
#define H1 1046
#define H2 1174
#define H3 1318
#define H4 1396
#define H5 1567
#define H6 1760
#define H7 1975
配置定时器1为CTC模式,设置PWM输出:
cvoid timer1_init(void) {
DDRD |= 0x20; // PD5 (OCR1A) 输出模式 脉冲驱动发声
TCCR1B = 0x00; // 关闭 T1
TCNT1H = 0x00;
TCNT1L = 0x00;
OCR1AH = 0x00;
OCR1AL = 0x00;
OCR1BH = 0x00;
}
通过数组存储音乐音符和节拍长度,并依次播放:
cconst unsigned int music0[] = {
L6, Z3, L7,
L6, Z1, Z2, Z1, Z3,
L6, Z6, Z5, Z6, Z5, Z2,
Z4, Z3, Z3,
L6, Z6, Z5, Z2, Z3, Z4,
Z3, Z1,
L6, Z3, Z2, L7,
L6,
0xff
};
const unsigned char music0_JP[] = {
8, 8, 16,
4, 4, 4, 2, 16,
8, 8, 4, 4, 4, 4,
4, 4, 16,
8, 8, 4, 4, 4, 4,
16, 16,
8, 8, 8, 4,
24
};
void main(void) {
LCD_init();
timer1_init();
DDRB = 0XFF;
LCD_write_str(0, 0, "Beautiful myth ");
while (1) {
delay_nms(10);
u = 0;
while (music0[u] != 0xff) {
OCR1A = 1000000 / music0[u] / 2;
contorl_A(music0[u]);
for (t = 0; t < music0_JP[u]; t++)
delay1();
u++;
}
}
}
根据当前音符频率,设置PORTB的输出状态:
cvoid contorl_A(unsigned int munum) {
if (munum == L1 || munum == Z1 || munum == H1) {
PORTB = 0x01;
} else if (munum == L2 || munum == Z2 || munum == H2) {
PORTB = 0x03;
} else if (munum == L3 || munum == Z3 || munum == H3) {
PORTB = 0x07;
} else if (munum == L4 || munum == Z4 || munum == H4) {
PORTB = 0x0f;
} else if (munum == L5 || munum == Z5 || munum == H5) {
PORTB = 0x1f;
} else if (munum == L6 || munum == Z6 || munum == H6) {
PORTB = 0x3f;
} else if (munum == L7 || munum == Z7 || munum == H7) {
PORTB = 0x7f;
}
}
通过本项目的设计与实现,学习者可以深入理解如何利用单片机和蜂鸣器播放音乐,掌握定时器的配置及PWM信号的应用。同时,通过编写代码实现音乐播放过程,提高了编程能力和解决问题的能力。该项目不仅是一种理论知识的实践应用,也是一次有趣的电子制作体验。
https://docs.qq.com/sheet/DUEdqZ2lmbmR6UVdU?u=bdf8eeb84961492ba2b62f7bfee641ea&tab=BB08J2
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!