在C51单片机上实现蜂鸣器播放《两只老虎》和《世上只有妈妈好》,并能够切换曲目及暂停功能,可以通过按键来控制。以下是一个简化的示例代码,实现了基本功能:
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
// 定义音符频率(这里只是举例,实际频率请根据实际情况调整)
#define DO 262
#define RE 294
#define MI 330
#define FA 349
#define SO 392
#define LA 440
#define SI 494
// 按键端口定义
sbit KEY_PAUSE = P1^0; // 暂停按键
sbit KEY_CHANGE = P1^1; // 切换曲目按键
// 蜂鸣器端口定义
sbit BEEP = P2^3;
// 全局变量
uchar code music_1[] = {DO, RE, MI, DO, DO, RE, MI, DO, MI, FA, SO, MI, FA, SO}; // 两只老虎音符
uchar code music_2[] = {SO, SO, LA, SO, FA, MI, SO, SO, LA, SO, RE, DO}; // 世上只有妈妈好音符
uchar code rhythm_1[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // 两只老虎节奏
uchar code rhythm_2[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; // 世上只有妈妈好节奏
uchar index = 0, speed = 5;
bit pause = 0;
bit change = 0;
void Delay(uint z) {
uint x, y;
for(x=z; x>0; x--)
for(y=110; y>0; y--);
}
void Play(uchar tone, uchar rhythm) {
uint i;
for(i=0; i< rhythm*speed; i++) {
BEEP = ~BEEP;
Delay(tone);
}
BEEP = 1; // 停止声音,产生间隔效果
Delay(500); // 音符间隔
}
void main() {
uchar *current_music, *current_rhythm, music_len;
EA = 1; // 开启总中断
while(1) {
if(change) {
current_music = (index / 2) % 2 == 0 ? music_1 : music_2;
current_rhythm = (index / 2) % 2 == 0 ? rhythm_1 : rhythm_2;
music_len = (index / 2) % 2 == 0 ? sizeof(music_1) : sizeof(music_2);
index = 0;
change = 0;
}
if(!pause) {
Play(current_music[index], current_rhythm[index]);
if(++index >= music_len) {
index = 0;
}
}
if(!KEY_PAUSE) {
Delay(1000); // 消抖
if(!KEY_PAUSE) {
pause = !pause;
while(!KEY_PAUSE); // 等待按键释放
}
}
if(!KEY_CHANGE) {
Delay(1000); // 消抖
if(!KEY_CHANGE) {
change = 1;
while(!KEY_CHANGE); // 等待按键释放
}
}
}
}
这段代码是非常基础的实现,没有考虑太多的优化和功能。这只是一个框架,具体的音符频率、节奏时长等参数需要根据实际的蜂鸣器和个人喜好调整。此外,这里的按键检测是通过简单的轮询方式进行的,实际应用中可能需要使用中断来提高响应速度和减少CPU占用。
记得在实际编写程序时,配合相应的硬件电路,将按键和蜂鸣器连接到单片机的正确引脚上,并确保按键电路设计可以正确地被单片机识别。