水手 51单片机蜂鸣器播放音乐
时间: 2023-08-15 16:08:38 浏览: 53
51单片机通过控制蜂鸣器发出不同频率的声音来播放音乐,具体实现步骤如下:
1. 定义音符频率和持续时间
首先需要定义每个音符的频率和持续时间,可以通过查找音符频率表来获取。同时也需要定义一些延时时间,用于控制每个音符之间的间隔。
例如,定义两个音符C4和E4,它们的频率分别为262Hz和330Hz,持续时间为200ms,间隔时间为100ms:
```c
#define C4 262
#define E4 330
#define NOTE_DURATION 200
#define NOTE_PAUSE 100
```
2. 控制蜂鸣器发声
控制蜂鸣器发声的方法是通过控制IO口输出高低电平来产生不同的频率。具体实现可以通过使用定时器和中断来完成。
以定时器0为例,可以设置一个周期为1ms的定时器中断,在中断服务程序中控制IO口输出高低电平产生不同频率的声音。在每个音符的持续时间内,定时器中断服务程序持续输出相应频率的声音,然后再在间隔时间内停止输出。
以下是一个简单的示例代码:
```c
#include <reg52.h>
#define C4 262
#define E4 330
#define NOTE_DURATION 200
#define NOTE_PAUSE 100
unsigned int note[] = {C4, E4};
unsigned int duration[] = {NOTE_DURATION, NOTE_DURATION};
unsigned int pause[] = {NOTE_PAUSE, NOTE_PAUSE};
unsigned char current_note = 0;
void timer0_isr() interrupt 1
{
static unsigned int cnt = 0;
static unsigned int period = 0;
cnt++;
if (cnt >= period)
{
P1 = ~P1;
cnt = 0;
}
period = note[current_note] / 2;
}
void delay(unsigned int ms)
{
unsigned int i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 114; j++);
}
}
void main()
{
TMOD = 0x01; // 设置定时器0为16位定时器模式
TH0 = 0xFC; // 定时器计数初值
TL0 = 0x67;
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许中断
TR0 = 1; // 启动定时器0
while (1)
{
if (current_note >= sizeof(note)/sizeof(note[0]))
{
current_note = 0;
delay(500);
}
else
{
delay(pause[current_note]);
current_note++;
}
}
}
```
在上面的代码中,定时器0被设置为16位定时器模式,定时器计数初值为0xFC67,周期为1ms。在定时器中断服务程序中,计数器每次加1,当计数器达到当前音符周期的一半时,就翻转IO口输出高低电平,产生相应频率的声音。
在主函数中,程序不断循环播放预定义的音符序列,当所有音符播放完成后,程序等待500ms再开始播放下一轮。