基于51单片机的简易音乐盒仿真

仿真图:

在这里插入图片描述

芯片/模块的特点:

AT89C52简介:
AT89C52是一款经典的8位单片机,是意法半导体(STMicroelectronics)公司生产的一系列单片机之一。它基于8051内核,并具有许多与其兼容的特性。

AT89C52的主要特点如下:

内部存储器:AT89C52具有8KB的闪存(Flash)存储器,可用于存储用户程序和数据。这些存储器的内容可以通过编程器进行编程和擦除。

RAM存储器:AT89C52配备了256字节的随机存取存储器(RAM),用于暂存数据和程序的变量。

外部扩展性:AT89C52支持多种外部扩展设备的连接,包括外部存储器(如RAM、EEPROM)和外设(如ADC、LCD、UART等),通过外部硬件连接,可以扩展单片机的功能和应用。

通用I/O引脚:AT89C52拥有32个可编程的通用输入/输出引脚,可用于连接外部设备和与其他芯片进行通信。

定时器/计数器:AT89C52内置了3个16位定时器/计数器和一个可编程的串行定时器/计数器。这些计时器/计数器可用于实现定时功能、生成脉冲信号、测量时间间隔等。0

串行通信:AT89C52支持串行通信接口,包括UART(串行异步通信)和SPI(串行外设接口),便于与其他设备进行数据通信和交互。

低功耗模式:AT89C52具有多种低功耗模式,如空闲模式和电源下模式,在不需要执行任务的时候可以将CPU进入低功耗状态以节省能量。

宽电源电压范围:AT89C52的工作电压范围通常为4.0V至5.5V,可以满足大多数应用需求。

DS1302特点:
高精度时间计数:DS1302能够提供高精度的实时时钟计数,可以记录年、月、日、星期、小时、分钟和秒等时间信息。它内部集成了晶体振荡器,提供稳定的时钟信号。

低功耗设计:DS1302采用低功耗设计,可以在低功耗模式下运行,有效延长电池寿命。即使在停电情况下,它也能保持时间数据,并通过外部连接电池继续提供计时功能。

串行接口:DS1302通过串行实时时钟接口(SPI)进行通信和控制。使用少数几个引脚,可以与主控器件进行数据交换和时钟同步。

容易集成:DS1302集成了时钟计数和RAM存储器功能,并具有简单的接口和命令,容易与各种微控制器和单片机集成。它不需要复杂的控制信号,可以通过简单的读写命令进行操作。

可编程控制功能:DS1302具有可编程的控制功能,可以设置闹钟、写保护等特殊功能。它还支持多种时间格式的选择,例如24小时制或12小时制。

温度补偿:DS1302内置温度补偿功能,可以校正温度对时钟频率的影响,提高时钟计数的准确性。

高稳定性和抗震动能力:DS1302具有高稳定性和抗震动能力,适用于各种工业和消费类应用场景。

主程序:

//
//51单片机音乐播放器程序
//STC89C52+11.0592MHz+蜂鸣器
//共三个按键:上一曲、一下曲、播放\暂停
//注意:按键必须按下约1S才有相应动作,播放完一首歌曲无按键按下时顺序播放

//
#include <REG52.H>
#include <stdio.h>
#include "delay.h"
#include "lcd1602.h"
#include "ds1302.h"

#define MUSIC_AMOUNT 8 //歌曲的数量
sbit SPEAKER = P3^2;     //蜂鸣器
sbit KEY_PAUSE = P3^5;
sbit KEY_SELECT = P3^3;
sbit KEY_PREVIOUS = P3^4;
sbit KEY_NEXT = P3^6;

//
unsigned char g_beatTime = 0;    //T0RH,T0RL为定时器T0的高低位初值,g_beatTime为对应的节拍时间
unsigned char g_musicNum = 1;              //g_musicNum为歌曲编号,g_noteCnt是查找歌曲数据表的地址
unsigned int g_noteCnt;
signed int g_fre;                      //对应频率数据表的地址
bit g_playEn = 1;                          //歌曲播放的使能标志位,用于播放\暂停
unsigned char g_keyValue;
unsigned char dispRow0[] = "  /  /  ";
unsigned char dispRow1[] = "  :  ";
bit g_switchSong = 1;
bit g_refreshTime = 1;
bit g_setTime = 0;
bit g_playFlag = 0;
unsigned char g_setLocation = 0;

void SetTime();
void DispTime();
void KeyScan();	                           //按键处理
void DelayOfBeat(unsigned char t);	   //延时子函数,控制发音的时间长度
void PlayOneNote(void);		           //演奏一个音符
void PlayMusic(void);	               //播放歌曲
void DispMusic(void);
void Timer0_Init();
void Timer1_Init();
//
//每三个数字,代表一个音符
//第一个数字是音符的数值1234567之一(第几个音),代表哆来咪发...
//第二个数字是0123之一,代表低音\中音\高音\超高音(第几个八度)
//第三个数字是时间长度,以半拍为单位,乐曲数据表的结尾是三个0
//



//《烟花易冷》
unsigned char code song1[]={
    5,2,1, 3,2,1, 2,2,2, 2,2,4, 3,2,1, 1,2,1, 2,2,1, 3,2,4, 
    5,2,1, 3,2,1, 2,2,2, 2,2,2, 5,1,1, 3,2,1, 4,2,1, 3,2,4, 
    3,2,1, 3,2,1, 7,2,1, 3,2,1, 2,2,2, 1,2,1, 7,1,1, 1,2,1, 
    2,2,1, 3,2,1, 6,2,3, 6,1,1, 1,2,1, 3,2,1, 2,2,1, 6,1,1, 
    1,2,1, 7,1,1, 5,1,1, 6,1,6, 5,2,1, 3,2,1, 2,2,2, 2,2,1, 
    2,2,1, 3,2,1, 1,2,1, 2,2,1, 3,2,4, 5,2,1, 3,2,1, 2,2,2, 
    2,2,1, 2,2,1, 5,1,1, 3,2,1, 4,2,1, 3,2,4, 3,2,1, 3,2,1, 
    7,2,3, 3,2,1, 2,2,2, 1,2,1, 7,1,1, 1,2,1, 2,2,1, 3,2,1, 
    6,2,3, 6,1,1, 1,2,1, 3,2,1, 2,2,1, 6,1,1, 1,2,1, 7,1,2, 
    5,1,2, 6,1,6, 0,0,0 };

//《发如雪》
unsigned char code song2[]={
    5,1,1, 2,2,1, 3,2,2, 2,2,1, 3,2,1, 5,2,1, 6,2,1, 5,2,3, 1,2,1, 2,2,1, 
    3,2,1, 6,2,1, 5,2,1, 3,2,1, 5,2,3, 5,2,1, 6,2,1, 1,3,2, 6,2,1, 5,2,1, 
    3,2,1, 5,2,1, 3,2,2, 1,2,1, 2,2,1, 3,2,1, 1,2,1, 6,1,1, 3,2,1, 2,2,1, 
    5,1,1, 2,2,1, 3,2,2, 2,2,1, 3,2,1, 5,2,1, 6,2,1, 5,2,3, 1,2,1, 2,2,1, 
    3,2,1, 6,2,1, 5,2,3, 5,2,1, 6,2,1, 1,3,2, 6,2,1, 
    5,2,1, 3,2,1, 5,2,1, 3,2,2, 1,2,1, 6,1,1, 3,2,1, 2,2,1, 1,2,1, 6,1,1, 
    1,2,1, 2,2,1, 2,2,1, 1,2,4, 0,0,0 };

//《简单爱》
unsigned char code song3[]={
    5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1, 
    4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 
    5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1, 
    3,2,1, 3,2,1, 1,2,1, 5,2,1, 1,2,1, 5,2,1, 1,2,1, 7,1,1, 1,2,1, 1,2,1, 6,1,1, 
    2,2,1, 2,2,1, 3,2,1, 3,2,1, 5,2,1, 5,2,1, 
    5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2,  
    5,1,1, 1,2,1, 2,1,2, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1, 
    4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 
    5,2,1, 5,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1, 
    3,2,1, 3,2,1, 1,2,2, 5,2,1, 1,2,1, 5,2,1, 5,2,1, 7,1,1, 1,2,1, 0,0,0 };

//《世上只有妈妈好》
unsigned char code song4[]={
    6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1,
     //6,2,3代表6,中音,3个半拍;
     //5,2,1代表5,中音,1个半拍;
     //3,2,2代表3,中音,2个半拍;
     //5,2,2代表5,中音,2个半拍;
     //1,3,2代表1,高音,2个半拍;
     //...
    5,2,1,6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,6,1,1, 5,2,1, 
    3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2, 5,2,1, 6,2,1, 3,2,2, 2,2,2, 
    1,2,4, 5,2,3, 3,2,1,2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0};

//《当你孤单你会想起谁》
unsigned char code song5[]={
    3,2,2, 3,2,1, 4,2,1, 3,2,2, 2,2,1, 1,2,1,  2,2,2, 5,2,2, 2,2,2, 2,2,3,
    1,2,2, 1,2,1, 2,2,1, 1,2,2, 7,1,1, 6,1,1, 7,1,2, 3,2,2, 7,1,2, 7,1,3, 
    6,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,2, 5,1,2, 2,2,1, 3,2,1, 2,2,1, 
    1,2,1, 6,1,2, 6,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,1, 7,1,1, 1,2,6, 0,0,0 };

//《乡间小路》
unsigned char code song6[]={
    3,1,2, 3,1,1, 3,1,1, 6,0,1, 6,0,1, 1,1,2,
    6,0,1, 5,0,1, 6,0,4, 6,0,2, 6,0,1 ,6,0,1, 6,0,2, 6,0,1, 1,1,1, 
    2,1,2, 2,1,1, 3,1,1, 2,1,4, 3,1,1, 3,1,1, 3,1,1, 2,1,1, 4,1,2,
    4,1,2, 3,1,2, 2,1,1, 1,1,1, 2,1,4, 7,0,1, 7,0,1, 7,0,1, 6,0,1, 
    5,0,1, 5,0,1, 6,0,1, 7,0,1, 7,0,1, 6,0,1, 5,0,1, 6,0,4, 6,1,2,
    3,1,1, 6,1,1, 7,1,1, 6,1,1, 5,1,1, 5,1,2, 5,1,1, 2,1,1, 5,1,1, 
    6,1,1, 5,1,1, 4,1,1, 4,1,2, 4,1,1, 3,1,1, 2,1,2, 1,1,1, 2,1,1, 
    3,1,1, 2,1,1, 1,1,1, 2,1,1, 3,1,4, 6,1,2, 3,1,1, 6,1,1, 7,1,1, 
    6,1,1, 5,1,1, 5,1,2, 2,1,1, 5,1,1, 6,1,1, 5,1,1, 4,1,1, 0,0,0};     

//《送别》
unsigned char code song7[]={
    5,1,2, 3,1,3, 5,1,1, 1,2,3, 6,1,2, 1,2,2, 
    5,1,4, 5,1,2, 1,1,1, 2,1,1, 3,1,2, 2,1,1, 1,1,1, 2,1,4, 5,1,2, 
    3,1,1, 5,1,1, 1,2,2, 7,1,1, 6,1,2, 1,2,2, 5,1,4, 5,1,2, 2,1,1, 
    3,1,1, 4,1,2, 7,0,1, 1,1,4, 6,1,2, 1,2,2, 1,2,4, 7,1,2, 6,1,1,
    7,1,1, 1,2,4, 6,1,1, 7,1,1, 1,2,1, 6,1,1, 6,1,1, 5,1,1, 3,1,1, 
    1,1,1, 2,1,8, 5,1,2, 3,1,1, 5,1,1, 1,2,2, 7,1,1, 6,1,2, 1,2,2, 
    5,1,4, 5,1,2, 2,1,1, 3,1,1, 4,1,2, 7,0,2, 1,1,4, 0,0,0};

//《最浪漫的事》
unsigned char code song8[]={
    5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 3,1,1, 5,1,5, 
    5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 6,1,1, 1,1,5, 
    1,1,1, 2,1,1, 3,1,1, 2,1,1, 2,1,1, 2,1,1, 1,1,1, 2,1,1, 1,1,1, 6,1,1, 
    3,1,2, 2,1,3, 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 
    6,1,1, 1,1,5, 1,1,1, 2,1,1, 3,1,1, 4,1,2, 4,1,1, 5,1,1, 6,1,1, 6,1,1, 
    5,1,1, 6,1,2, 1,2,1, 6,1,3, 1,2,1, 6,1,1, 5,1,1, 5,1,4, 1,1,1, 6,1,1, 
    5,1,5, 5,1,1, 6,1,1, 1,2,1, 3,1,1, 2,1,1, 3,1,1, 1,1,6, 0,0,0}; 

// 频率-半周期数据表 高八位  共保存了四个八度的28个频率数据
unsigned char code FREQH[]={
    0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8,    //低音1234567
    0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
    0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE,            //高音 234567
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF};   //超高音 1234567

// 频率-半周期数据表 低八位
unsigned char code FREQL[]={
    0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6,    //低音1234567
    0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
    0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D,             //高音 234567
    0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16};   //超高音 1234567

void main(void)
{

    Timer0_Init();
    Timer1_Init();
    DS1302_Init();
    // DS1302_Write_Time();
    LcdReset();
    DelayMs(10);
    LcdClear();
    DispStr(0, 0, "    MusicBox    ");
    DelaySecond(2);
    LcdClear();

    while (1)
    {

        if (g_setTime == 1)
        {
            SetTime();
        }
        else
        {
            DS1302_Read_Time();
            DispMusic();
        }

        if (g_playFlag == 1)
        {
            PlayMusic(); //根据当前状态播放相应歌曲的某个音符
        }



        if (g_refreshTime == 1) //每200ms刷新一次屏幕
        {
            DispTime();
            g_refreshTime = 0;
        }

        KeyScan();
    }
}

void DelayOfBeat(unsigned char t) //延时子函数,控制发音的时间长度,每个节拍0.4S
{
    unsigned char t1;
    unsigned long t2;
    for (t1 = 0; t1 < t; t1++) //嵌套循环, 共延时t个半拍
    {
        for (t2 = 0; t2 < 8000; t2++) //延时期间, 可进入T0中断去发音
        {
            ;
        }
    }
    TR0 = 0; //关闭T0, 停止发音
}

void PlayOneNote(void) //演奏一个音符
{
    TH0 = FREQH[g_fre];      //下次的中断时间,这个时间控制音调高低
    TL0 = FREQL[g_fre];
    TR0 = 1;     //启动T0, 由T0输出方波发音
    DelayOfBeat(g_beatTime); //每个音符的演奏时间
}

void PlayMusic(void) //播放相应歌曲的某个音符
{

    if ((g_musicNum == 1) && (g_playEn == 1))
    {
        g_fre = song1[g_noteCnt] + 7 * song1[g_noteCnt + 1] - 1; //第i个是音符,第i+1个是第几个八度
        g_beatTime = song1[g_noteCnt + 2]; //读出时间长度数值
        g_noteCnt += 3;
        if (g_fre < 0) //判断歌曲的结束位,结束后转到下一首
        {
            g_noteCnt = 0; //下一首从头播放
            g_musicNum = 2;
        }
        PlayOneNote(); //发出一个音符
        
    }
    
    if ((g_musicNum == 2) && (g_playEn == 1))
    {
        g_fre = song2[g_noteCnt] + 7 * song2[g_noteCnt + 1] - 1;
        g_beatTime = song2[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 3;
        }
        PlayOneNote();
    }
    
    if ((g_musicNum == 3) && (g_playEn == 1))
    {
        g_fre = song3[g_noteCnt] + 7 * song3[g_noteCnt + 1] - 1;
        g_beatTime = song3[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 4;
        }
        PlayOneNote();
    }
    
    if ((g_musicNum == 4) && (g_playEn == 1))
    {
        g_fre = song4[g_noteCnt] + 7 * song4[g_noteCnt + 1] - 1;
        g_beatTime = song4[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 5;
        }
        PlayOneNote();
    }
    
    if ((g_musicNum == 5) && (g_playEn == 1))
    {
        g_fre = song5[g_noteCnt] + 7 * song5[g_noteCnt + 1] - 1;
        g_beatTime = song5[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 6;
        }
        PlayOneNote();
    }
    
    if ((g_musicNum == 6) && (g_playEn == 1))
    {
        g_fre = song6[g_noteCnt] + 7 * song6[g_noteCnt + 1] - 1;
        g_beatTime = song6[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 7;
        }
        PlayOneNote();
    }
    
    if ((g_musicNum == 7) && (g_playEn == 1))
    {
        g_fre = song7[g_noteCnt] + 7 * song7[g_noteCnt + 1] - 1;
        g_beatTime = song7[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 8;
        }
        PlayOneNote();
    }
    
    if ((g_musicNum == 8) && (g_playEn == 1))
    {
        g_fre = song8[g_noteCnt] + 7 * song8[g_noteCnt + 1] - 1;
        g_beatTime = song8[g_noteCnt + 2];
        g_noteCnt += 3;
        if (g_fre < 0)
        {
            g_noteCnt = 0;
            g_musicNum = 1;
        }
        PlayOneNote();
    }
    
}

void KeyScan() //按键程序
{
    /*********************歌曲播放*********************/
    if (!KEY_SELECT)
    {
        DelayMs(10); //按键去抖动
        if (!KEY_SELECT)
        {
            g_playFlag = 0;
            g_setTime = 1;
            g_setLocation++;
        }

        while (!KEY_SELECT)
            ;
    }

    if (!KEY_PAUSE)
    {
        DelayMs(5);
        if (!KEY_PAUSE)
        {
            g_playFlag = ~g_playFlag;
        }
        while (!KEY_PAUSE)
            ;
    }

    if (!KEY_PREVIOUS)
    {
        DelayMs(5);
        if (!KEY_PREVIOUS)
        {
            if (g_setTime == 1)
            {
                switch (g_setLocation)
                {
                case 1:
                {
                    if (timeBufDec[1] == 0)
                    {
                        timeBufDec[1] = 100;
                    }
                    timeBufDec[1]--;
                    break;
                }
                case 2:
                {
                    timeBufDec[2]--;
                    if (timeBufDec[2] < 1)
                    {
                        timeBufDec[2] = 12;
                    }
                    break;
                }
                case 3:
                {
                    timeBufDec[3]--;
                    if (timeBufDec[3] < 1)
                    {
                        timeBufDec[3] = YDay(timeBufDec[1], timeBufDec[2]);
                    }
                    break;
                }
                case 4:
                {
                    if (timeBufDec[4] == 0)
                    {
                        timeBufDec[4] = 24;
                    }
                    timeBufDec[4]--;
                    break;
                }
                case 5:
                {
                    if (timeBufDec[5] == 0)
                    {
                        timeBufDec[5] = 60;
                    }
                    timeBufDec[5]--;
                    break;
                }
                case 6:
                {
                    timeBufDec[7]--;
                    if (timeBufDec[7] < 1)
                    {
                        timeBufDec[7] = 7;
                    }
                    break;
                }
                default:;
                }
            }
            else
            {
                g_musicNum--;
                g_noteCnt = 0;
                if (g_musicNum < 1)
                {
                    g_musicNum = MUSIC_AMOUNT;
                    TR0 = 0;
                }
            }
            while (!KEY_PREVIOUS)
                ;
        }
    }

    if (!KEY_NEXT)
    {
        DelayMs(5);
        if (!KEY_NEXT)
        {
            if (g_setTime == 1)
            {
                switch (g_setLocation)
                {
                case 1:
                {
                    timeBufDec[1]++;
                    if (timeBufDec[1] >= 100)
                    {
                        timeBufDec[1] = 0;
                    }
                    break;
                }
                case 2:
                {
                    timeBufDec[2]++;
                    if (timeBufDec[2] >= 13)
                    {
                        timeBufDec[2] = 1;
                    }
                    break;
                }
                case 3:
                {
                    timeBufDec[3]++;
                    if (timeBufDec[3] >= YDay(timeBufDec[1], timeBufDec[2]) + 1)
                    {
                        timeBufDec[3] = 1;
                    }
                    break;
                }
                case 4:
                {
                    timeBufDec[4]++;
                    if (timeBufDec[4] >= 24)
                    {
                        timeBufDec[4] = 0;
                    }
                    break;
                }
                case 5:
                {
                    timeBufDec[5]++;
                    if (timeBufDec[5] >= 60)
                    {
                        timeBufDec[5] = 0;
                    }
                    break;
                }
                case 6:
                {
                    timeBufDec[7]++;
                    if (timeBufDec[7] > 7)
                    {
                        timeBufDec[7] = 1;
                    }
                    break;
                }
                default:;
                }
            }
            else
            {
                g_musicNum++;
                g_noteCnt = 0;
                if (g_musicNum >= MUSIC_AMOUNT + 1)
                {
                    g_musicNum = 1;
                    TR0 = 0;
                }
            }
            while (!KEY_NEXT)
                ;
        }
    }
}

void SetTime()
{
    TR1 = 0;
    LcdWriteCommand(0x0F, 0); //打开闪烁
    // LCD_WriteCommand(0x0C, 0);
    switch (g_setLocation)
    {
        case 1: LcdWriteCommand(0x80 + 1, 0); break;
        case 2: LcdWriteCommand(0x80 + 4, 0); break;
        case 3: LcdWriteCommand(0x80 + 7, 0); break;
        case 4: LcdWriteCommand(0x80 + 0x40 + 1, 0); break;
        case 5: LcdWriteCommand(0x80 + 0x40 + 4, 0); break;
        case 6: LcdWriteCommand(0x80 + 14, 0); break;
        case 7: 
        {
            LcdWriteCommand(0x0C, 0);
            LcdWriteCommand(0x0C, 0);
            DS1302_Write_Time();
            g_setLocation = 0;
            g_setTime = 0;
            break;
        }
        default: ;
    }
    TR1 = 1;
}

void DispTime()
{

    dispRow0[0] = timeBufDec[1] / 10 +'0';
    dispRow0[1] = timeBufDec[1] % 10 +'0';
    dispRow0[3] = timeBufDec[2] / 10 +'0';
    dispRow0[4] = timeBufDec[2] % 10 +'0';
    dispRow0[6] = timeBufDec[3] / 10 +'0';
    dispRow0[7] = timeBufDec[3] % 10 +'0';

    dispRow1[0] = timeBufDec[4] / 10 +'0';
    dispRow1[1] = timeBufDec[4] % 10 +'0';
    dispRow1[3] = timeBufDec[5] / 10 +'0';
    dispRow1[4] = timeBufDec[5] % 10 +'0';
    // dispRow1[6] = timeBufDec[6] / 10 +'0';
    // dispRow1[7] = timeBufDec[6] % 10 +'0';

    DispStr(0, 0, dispRow0);
    DispStr(0, 1, dispRow1);

    switch (timeBufDec[7])
    {
        case 1: DispStr(10, 0, " Mon."); break;
        case 2: DispStr(10, 0, " Tue."); break;
        case 3: DispStr(10, 0, " Wed."); break;
        case 4: DispStr(10, 0, "Thur."); break;
        case 5: DispStr(10, 0, " Fri."); break;
        case 6: DispStr(10, 0, " Sat."); break;
        case 7: DispStr(10, 0, " Sun."); break;
        default: DispStr(10, 0, " Sun."); break;;
    }
}

void DispMusic()
{
    unsigned char table[] = "Music   ";

    table[6] = g_musicNum / 10 + '0';
    table[7] = g_musicNum % 10 + '0';
    DispStr(7, 1, table);
}

void Timer0_Init()
{
    TMOD &= 0xF0;
    TMOD |= 0x01; //T0 T1 均在工作方式1
    PT0 = 1;     //优先级设置
    TR0 = 0;
    ET0 = 1;     //T0开中断
    EA = 1;      //CPU开中断
}

void Timer1_Init()
{
    TMOD &= 0x0F;
    TMOD |= 0x10; //T0 T1 均在工作方式1
    TH1 = (65536 - 18432) / 256; //定时20ms
    TL1 = (65536 - 18432) % 256;
    TR1 = 1;
    ET1 = 1;     //T0开中断
    EA = 1;      //CPU开中断
}

void Timer0(void) interrupt 1 //T0中断程序,控制发音的音调
{
    SPEAKER = !SPEAKER; //输出方波, 发音
    TH0 = FREQH[g_fre];      //下次的中断时间,这个时间控制音调高低
    TL0 = FREQL[g_fre];
}

void Timer1(void) interrupt 3 //T1中断程序
{
    static unsigned char cnt = 0;

    TH1 = (65536 - 18432) / 256; //定时20ms
    TL1 = (65536 - 18432) % 256;

    cnt++;

    if (cnt >= 10)
    {
        g_refreshTime = 1;
        cnt = 0;
    }
}
//程序结束

设计文件:

链接:https://pan.baidu.com/s/1nh6DdiSaKaFpSW9-uJyC8g?pwd=uqxx

  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的51单片机数字音乐盒的代码示例: ``` #include <reg51.h> // 包含51单片机头文件 // 定义IO口 sbit key1 = P1^0; sbit key2 = P1^1; sbit key3 = P1^2; sbit key4 = P1^3; sbit beep = P2^3; // 定义全局变量 unsigned char musicIndex = 0; // 当前播放的音乐编号 // 声明函数 void delay(unsigned int time); void playMusic(unsigned char music); void main() { while(1) { if(key1 == 0) // 按下按键1 { musicIndex = 1; playMusic(musicIndex); } else if(key2 == 0) // 按下按键2 { musicIndex = 2; playMusic(musicIndex); } else if(key3 == 0) // 按下按键3 { musicIndex = 3; playMusic(musicIndex); } else if(key4 == 0) // 按下按键4 { musicIndex = 4; playMusic(musicIndex); } else // 没有按键按下 { beep = 0; // 关闭蜂鸣器 } } } void delay(unsigned int time) { unsigned int i, j; for(i = 0; i < time; i++) { for(j = 0; j < 125; j++); } } void playMusic(unsigned char music) { switch(music) { case 1: beep = 1; // 打开蜂鸣器 delay(500); // 播放500ms beep = 0; // 关闭蜂鸣器 break; case 2: beep = 1; // 打开蜂鸣器 delay(1000); // 播放1000ms beep = 0; // 关闭蜂鸣器 break; case 3: beep = 1; // 打开蜂鸣器 delay(1500); // 播放1500ms beep = 0; // 关闭蜂鸣器 break; case 4: beep = 1; // 打开蜂鸣器 delay(2000); // 播放2000ms beep = 0; // 关闭蜂鸣器 break; default: break; } } ``` 这段代码使用了4个按键控制播放不同的音乐,每个音乐的播放时间不同。当按下按键后,会调用`playMusic()`函数播放相应的音乐。要注意的是,需要将蜂鸣器连接到P2.3口。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值