一、简介

基于8051微控制器用于控制LED显示和音乐播放,同时具备按键输入功能。程序通过不同的模式控制LED的显示效果,使用定时器中断来切换显示模式,并能够根据按键输入来改变运行模式、播放音乐或调整系统速度。

二、头文件选择,变量定义

2.1头文件:

头文件:包含了针对8051微控制器的头文件REG52.H和自定义的SoundPlay.h

2.2全局变量:

RunMode:用于控制程序的运行模式

2.3定时器初始化:

InitialTimer2:初始化定时器2,用于系统速度控制

2.4主要外设接口:

P3:连接数码管,来显示当前所选择的模式
P1 & P0:连接八个LED,用来显示循环彩灯现象
P2.1:连接按钮,该按钮用来控制模式
P2.4:连接按钮,该按钮用来控制循环速度(加速)
P2.5:连接按钮,该按钮用来控制循环速度(减速)
P2.6:连接扬声器,在模式9时播放音乐

三、音乐编码:

音乐编码是通过一系列数组来表示的,这些数组包含了用于生成音乐旋律的指令。每个数组的元素由两部分组成:音调和持续时间。音乐编码通常用于简单的声音合成器或者音乐播放器,它们可以是微控制器上的蜂鸣器或其他声音输出设备。

每个数组的元素格式通常是:

高字节(高8位)表示音调或音符的编号。
低字节(低8位)表示每个音符的持续时间。
//*****************************Music******************************************************
//挥着翅膀的女孩
unsigned char code Music_Girl[]={
0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x03,                                  0x16,0x03, 0x17,0x03, 0x17,0x03, 0x17,0x03, 0x18,0x03,                                  0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x02, 0x18,0x03,                                  0x17,0x03, 0x15,0x02, 0x18,0x03, 0x17,0x03, 0x18,0x02,                                  0x10,0x03, 0x15,0x03, 0x16,0x02, 0x15,0x03, 0x16,0x03,                                  0x17,0x02, 0x17,0x03, 0x18,0x03, 0x19,0x02, 0x1A,0x03,                                  0x1B,0x03, 0x1F,0x03, 0x1F,0x03, 0x17,0x03, 0x18,0x03,                                  0x19,0x02, 0x16,0x03, 0x17,0x03, 0x18,0x03, 0x17,0x03,                                  0x18,0x03, 0x1F,0x03, 0x1F,0x02, 0x16,0x03, 0x17,0x03,                                  0x18,0x03, 0x17,0x03, 0x18,0x03, 0x20,0x03, 0x20,0x02,                                  0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,                                  0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,                                  0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,                                  0x1A,0x03, 0x19,0x03, 0x15,0x03, 0x15,0x03, 0x17,0x03,                                  0x16,0x66, 0x17,0x04, 0x18,0x04, 0x18,0x03, 0x19,0x03,                                  0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x20,0x03, 0x21,0x03,                                  0x20,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66, 0x1F,0x03,                                  0x1B,0x03, 0x19,0x03, 0x19,0x03, 0x15,0x03, 0x1A,0x66,                                  0x1A,0x03, 0x19,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,                                  0x1F,0x00, 0x1A,0x03, 0x1A,0x03, 0x1A,0x03, 0x1B,0x03,                                  0x1B,0x03, 0x1A,0x03, 0x19,0x03, 0x19,0x02, 0x17,0x03,                                  0x15,0x17, 0x15,0x03, 0x16,0x03, 0x17,0x03, 0x18,0x03,                                  0x17,0x04, 0x18,0x0E, 0x18,0x03, 0x17,0x04, 0x18,0x0E,                                  0x18,0x66, 0x17,0x03, 0x18,0x03, 0x17,0x03, 0x18,0x03,                                  0x20,0x03, 0x20,0x02, 0x1F,0x03, 0x1B,0x03, 0x1F,0x66,                                  0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03, 0x1B,0x03,                                  0x1F,0x66, 0x1F,0x04, 0x1B,0x0E, 0x1B,0x03, 0x19,0x03,                                  0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,                                  0x15,0x03, 0x15,0x03, 0x17,0x03, 0x16,0x66, 0x17,0x04,                                  0x18,0x04, 0x18,0x03, 0x19,0x03, 0x1F,0x03, 0x1B,0x03,                                  0x1F,0x66, 0x20,0x03, 0x21,0x03, 0x20,0x03, 0x1F,0x03,                                  0x1B,0x03, 0x1F,0x66, 0x1F,0x03, 0x1B,0x03, 0x19,0x03,                                  0x19,0x03, 0x15,0x03, 0x1A,0x66, 0x1A,0x03, 0x19,0x03,                                  0x19,0x03, 0x1F,0x03, 0x1B,0x03, 0x1F,0x00, 0x18,0x02,                                  0x18,0x03, 0x1A,0x03, 0x19,0x0D, 0x15,0x03, 0x15,0x02,                                  0x18,0x66, 0x16,0x02, 0x17,0x02, 0x15,0x00, 0x00,0x00};

//同一首歌
unsigned char code Music_Same[]={
0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x66, 0x18,0x03,                                  0x17,0x02, 0x15,0x02, 0x16,0x01, 0x15,0x02, 0x10,0x02,                                  0x15,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x02,                                  0x17,0x03, 0x18,0x03, 0x19,0x02, 0x15,0x02, 0x18,0x66,                                  0x17,0x03, 0x19,0x02, 0x16,0x03, 0x17,0x03, 0x16,0x00,                                  0x17,0x01, 0x19,0x02, 0x1B,0x02, 0x1B,0x70, 0x1A,0x03,                                  0x1A,0x01, 0x19,0x02, 0x19,0x03, 0x1A,0x03, 0x1B,0x02,                                  0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x18,0x66, 0x18,0x03,                                  0x19,0x02, 0x1A,0x02, 0x19,0x0C, 0x18,0x0D, 0x17,0x03,                                  0x16,0x01, 0x11,0x02, 0x11,0x03, 0x10,0x03, 0x0F,0x0C,                                  0x10,0x02, 0x15,0x00, 0x1F,0x01, 0x1A,0x01, 0x18,0x66,                                  0x19,0x03, 0x1A,0x01, 0x1B,0x02, 0x1B,0x03, 0x1B,0x03,                                  0x1B,0x0C, 0x1A,0x0D, 0x19,0x03, 0x17,0x00, 0x1F,0x01,                                  0x1A,0x01, 0x18,0x66, 0x19,0x03, 0x1A,0x01, 0x10,0x02,                                  0x10,0x03, 0x10,0x03, 0x1A,0x0C, 0x18,0x0D, 0x17,0x03,                                  0x16,0x00, 0x0F,0x01, 0x15,0x02, 0x16,0x02, 0x17,0x70,                                  0x18,0x03, 0x17,0x02, 0x15,0x03, 0x15,0x03, 0x16,0x66,                                  0x16,0x03, 0x16,0x02, 0x16,0x03, 0x15,0x03, 0x10,0x02,                                  0x10,0x01, 0x11,0x01, 0x11,0x66, 0x10,0x03, 0x0F,0x0C,                                  0x1A,0x02, 0x19,0x02, 0x16,0x03, 0x16,0x03, 0x18,0x66,                                  0x18,0x03, 0x18,0x02, 0x17,0x03, 0x16,0x03, 0x19,0x00,                                  0x00,0x00 };

//两只蝴蝶
unsigned char code Music_Two[] ={
0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,                                  0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,                                  0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,                                  0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x16,0x03,                                  0x17,0x01, 0x16,0x03, 0x17,0x03, 0x16,0x03, 0x15,0x01,                                  0x10,0x03, 0x15,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,                                  0x16,0x03, 0x15,0x03, 0x10,0x03, 0x15,0x03, 0x16,0x01,                                  0x17,0x03, 0x16,0x03, 0x17,0x01, 0x16,0x03, 0x17,0x03,                                  0x16,0x03, 0x15,0x01, 0x10,0x03, 0x15,0x03, 0x16,0x02,                                  0x16,0x0D, 0x17,0x03, 0x16,0x03, 0x15,0x03, 0x10,0x03,                                  0x10,0x0E, 0x15,0x04, 0x0F,0x01, 0x17,0x03, 0x19,0x03,                                  0x19,0x01, 0x19,0x03, 0x1A,0x03, 0x19,0x03, 0x17,0x01,                                  0x16,0x03, 0x16,0x03, 0x16,0x02, 0x16,0x0D, 0x17,0x03,                                  0x16,0x03, 0x15,0x03, 0x10,0x03, 0x10,0x0D, 0x15,0x00,                                  0x19,0x03, 0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03,                                  0x1B,0x03, 0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03,                                  0x16,0x0D, 0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03,                                  0x1A,0x02, 0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03,                                  0x16,0x01, 0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03,                                  0x19,0x02, 0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E,                                  0x1B,0x04, 0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E,                                  0x1B,0x04, 0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03,                                  0x17,0x0D, 0x16,0x03, 0x17,0x03, 0x19,0x01, 0x19,0x03,                                  0x19,0x03, 0x1A,0x03, 0x1F,0x03, 0x1B,0x03, 0x1B,0x03,                                  0x1A,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x03, 0x16,0x03,                                  0x17,0x01, 0x17,0x03, 0x17,0x03, 0x19,0x03, 0x1A,0x02,                                  0x1A,0x02, 0x10,0x03, 0x17,0x0D, 0x16,0x03, 0x16,0x01,                                  0x17,0x03, 0x19,0x03, 0x19,0x03, 0x17,0x03, 0x19,0x03,                                  0x1F,0x02, 0x1B,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,                                  0x17,0x02, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,                                  0x17,0x16, 0x1A,0x03, 0x1A,0x03, 0x1A,0x0E, 0x1B,0x04,                                  0x1A,0x03, 0x19,0x03, 0x17,0x03, 0x16,0x03, 0x0F,0x02,                                  0x10,0x03, 0x15,0x00, 0x00,0x00 };
//***********************************************************************************

模块介绍:

3.1延时函数:

Delay1ms:用来实现毫秒级的延迟,其中count参数用来调整时间长度

主要作用:数码管消影,以及避免运行速度过快导致的显示错误

void Delay1ms(unsigned int count)
{
    unsigned int i,j;
    for(i=0;i<count;i++)
    for(j=0;j<120;j++);
}

3.2定时器中断

定时器2的中断服务程序,用于处理LED模式的切换

定时器初始化函数:

unsigned int Timer0Count,SystemSpeed,SystemSpeedIndex;
void InitialTimer2(void)
{
    T2CON  = 0x00;            //16 Bit Auto-Reload Mode
     TH2 = RCAP2H = 0xFC;      //重装值,初始值    TL2 = RCAP2L = 0x18;
    ET2=1;                    //定时器 2 中断允许
    TR2 = 1;                //定时器 2 启动
    EA=1;
}

定时器中断函数:

void Timer2(void) interrupt 5 using 3
{
    TF2 = 0;     //中断标志清除( Timer2 必须软件清标志!)
    if(++Timer0Count>=SystemSpeed)
    {
        Timer0Count = 0;
        Timer0EventRun();
       }
}

中断处理函数:

void Timer0EventRun(void)
{
    if(RunMode==0x00)
    {
        Mode_0();
    }
    else if(RunMode ==0x01)
    {
        Mode_1();
    }
    else if(RunMode ==0x02)
    {
        Mode_2();
    }
    else if(RunMode ==0x03)
    {
        Mode_3();
    }
    else if(RunMode ==0x04)
    {
        Mode_4();
    }
    else if(RunMode ==0x05)
    {
        Mode_5();
    }
    else if(RunMode ==0x06)
    {
        Mode_6();
    }
    else if(RunMode ==0x07)
    {
        Mode_7();
    }
    else if(RunMode ==0x08)
    {
        Mode_8();
    }
}

3.3初始化函数:

void InitialCPU(void)
{
    RunMode = 0x00;
    Timer0Count = 0;
    SystemSpeedIndex = 9;

    P1 = 0x00;
    P0 = 0x00;
    P2 = 0xFF;
    P3 = 0x00;
    Delay1ms(500);
    P1 = 0xFF;
    P0 = 0xFF;
    P2 = 0xFF;
    P3 = 0xFF;
    SetSpeed(SystemSpeedIndex);
    Display(RunMode);
}

3.4LED显示函数:

LEDDisplayCode:定义了用于LED显示的编码数组

unsigned char code LEDDisplayCode[] = {
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,    //0~7    0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};

Display:控制LED显示数字

void Display(unsigned char Value)
{
    P3 = LEDDisplayCode[Value];
}

LEDFlash:实现LED闪烁效果

void LEDFlash(unsigned char Count)
{
    unsigned char i;
    bit Flag;
    for(i = 0; i<Count;i++)
    {
        Flag = !Flag;
        if(Flag)
            Display(RunMode);
        else
            Display(0x10);
        Delay1ms(100);
    }
    Display(RunMode);
}

3.5按键读取函数:

GetKey:读取按键状态的函数。

参数说明:

该函数不接受任何参数。

返回值说明:

返回值是unsigned char类型的值,表示按键的状态。如果所有按键都未被按下,返回0x00。

函数逻辑:

函数初始化三个局部变量:KeyTemp、CheckValue 和 Key。
读取P2端口的值并与0x32进行AND操作,以检测特定的按键状态,并将结果存储在CheckValue中。
如果CheckValue等于0x32,表示没有按键被按下,函数立即返回0x00。
为了消除按键抖动,调用Delay1ms函数进行短暂延时。
延时后,再次读取按键状态并存入KeyTemp。
如果KeyTemp与CheckValue不同,表示按键状态发生了变化,这可能是由于按键抖动,因此函数返回0x00。
如果检测到按键按下(即KeyTemp不等于CheckValue),则通过AND操作和NOT操作更新Key的相应位,以反映哪些按键被按下。
最后,函数返回表示按键状态的Key值。

unsigned char GetKey(void)
{
    unsigned char KeyTemp, CheckValue, Key = 0x00;
    CheckValue = P2 & 0x32;  // 读取P2端口,并与0x32进行AND操作
    if(CheckValue == 0x32)
        return 0x00;  // 如果所有相关位都是高电平,表示没有按键按下

    Delay1ms(10);  // 短暂延时去抖动
    KeyTemp = P2 & 0x32;  // 再次读取按键状态

    if(KeyTemp != CheckValue)
        return 0x00;  // 如果第二次读取的状态与第一次不同,表示按键抖动,不处理按键

    Key |= ~(CheckValue & 0x02);  // 检查第二位,如果为低电平,设置Key的第二位
    Key |= ~(CheckValue & 0x10);  // 检查第五位,如果为低电平,设置Key的第五位
    Key |= ~(CheckValue & 0x20);  // 检查第六位,如果为低电平,设置Key的第六位

    return Key;  // 返回按键状态的Key值
}

3.6速度控制:

SpeedCode:定义了速度代码数组

unsigned int code SpeedCode[]={
1,   2,   3,   5,   8,  10,  14,  17,  20,  30,
40,  50,  60,  70,  80,  90, 100, 120, 140, 160,
180, 200, 300, 400, 500, 600, 700, 800, 900,1000};//30

SetSpeed:设置系统速度的函数

void LEDShow(unsigned int LEDStatus)
{
    P1 = ~(LEDStatus&0x00FF);
    P0 = ~((LEDStatus>>8)&0x00FF);
}

3.7LED显示模式函数:

八种模式:

//Mode 0 从左往右循环显示
unsigned int LEDIndex = 0;
bit LEDDirection = 1,LEDFlag = 1;
void Mode_0(void)
{
    LEDShow(0x0001<<LEDIndex);
    LEDIndex = (LEDIndex+1)%16;
}
//Mode 1 从右往左循环显示
void Mode_1(void)
{
    LEDShow(0x8000>>LEDIndex);
    LEDIndex = (LEDIndex+1)%16;
}
//Mode 2 从左往右后从右往左交替
void Mode_2(void)
{
    if(LEDDirection)
        LEDShow(0x0001<<LEDIndex);
    else
        LEDShow(0x8000>>LEDIndex);
    if(LEDIndex==15)
        LEDDirection = !LEDDirection;
   LEDIndex = (LEDIndex+1)%16;
}
//Mode 3 与模式0亮灯相反
void Mode_3(void)
{
    if(LEDDirection)
        LEDShow(~(0x0001<<LEDIndex));
    else
        LEDShow(~(0x8000>>LEDIndex));
    if(LEDIndex==15)
        LEDDirection = !LEDDirection;
   LEDIndex = (LEDIndex+1)%16;
}

//Mode 4 循环方式与模式2相同,但亮后不灭
void Mode_4(void)
{
    if(LEDDirection)
    {
        if(LEDFlag)
            LEDShow(0xFFFE<<LEDIndex);
           else
            LEDShow(~(0x7FFF>>LEDIndex));
    }
    else
    {
        if(LEDFlag)
            LEDShow(0x7FFF>>LEDIndex);
        else
            LEDShow(~(0xFFFE<<LEDIndex));
    }
    if(LEDIndex==15)
    {
        LEDDirection = !LEDDirection;
        if(LEDDirection)    LEDFlag = !LEDFlag;
    }
       LEDIndex = (LEDIndex+1)%16;
}

//Mode 5 四个灯同时亮,循环方式与模式2相同
void Mode_5(void)
{
    if(LEDDirection)
        LEDShow(0x000F<<LEDIndex);
    else
        LEDShow(0xF000>>LEDIndex);
    if(LEDIndex==15)
        LEDDirection = !LEDDirection;
    LEDIndex = (LEDIndex+1)%16;
}

//Mode 6 与模式5亮灯相反
void Mode_6(void)
{
    if(LEDDirection)
        LEDShow(~(0x000F<<LEDIndex));
    else
        LEDShow(~(0xF000>>LEDIndex));
    if(LEDIndex==15)
        LEDDirection = !LEDDirection;
       LEDIndex = (LEDIndex+1)%16;
}

//Mode 7 六个灯同时亮,循环方式与模式2相同
void Mode_7(void)
{
    if(LEDDirection)
        LEDShow(0x003F<<LEDIndex);
    else
        LEDShow(0xFC00>>LEDIndex);
    if(LEDIndex==9)
        LEDDirection = !LEDDirection;
    LEDIndex = (LEDIndex+1)%10;
}

//Mode 8 二进制规则亮灯
void Mode_8(void)
{
    LEDShow(++LEDIndex);
}

KeyDispose:按键处理

参数说明:

Key:一个无符号字符(unsigned char),表示用户的按键操作。值是通过位运算得到的,不同的位代表不同的按键状态。

函数逻辑:

函数首先检查Key参数的各个位是否被设置(即对应的按键是否被按下)。
使用&运算符与0x01、0x02、0x04等进行位运算来检查特定按键的状态。

如果第一位(LSB)被设置,表示一个按键被按下,函数将:

重置LEDDirection为1。
将LEDIndex设置为0,表示LED的起始位置。
将LEDFlag设置为1。
增加RunMode的值,并用10作为模数来循环(即切换模式)。
根据RunMode的值,可能停止或启动定时器2(TR2)。

如果第二位被设置,函数将:

如果当前是音乐播放模式(RunMode为9),则在音乐列表中向前或向后切换音乐曲目。
如果不是音乐播放模式,则增加或减少系统速度索引,并调用SetSpeed来更新系统速度。
如果速度索引超出范围,则调用LEDFlash函数来闪烁LED作为提示。
该函数通过修改全局变量来改变系统的行为,这些变量随后会影响主循环中LED的显示模式和音乐播放。

void KeyDispose(unsigned char Key)
{
    if(Key&0x01)
    {
        LEDDirection = 1;
        LEDIndex = 0;
        LEDFlag = 1;
        RunMode = (RunMode+1)%10;
        Display(RunMode);
        if(RunMode==0x09)
            TR2 = 0;
        else
            TR2 = 1;
    }
    if(Key&0x02)
    {
        if(RunMode==0x09)
        {
            MusicIndex =(MusicIndex+MUSICNUMBER-1)%MUSICNUMBER;
        }
        else
        {
            if(SystemSpeedIndex>0)
            {
                --SystemSpeedIndex;
                SetSpeed(SystemSpeedIndex);
            }
            else
            {
                LEDFlash(6);
            }
         }
    }
    if(Key&0x04)
    {
        if(RunMode==0x09)
        {
            MusicIndex =(MusicIndex+1)%MUSICNUMBER;
        }
        else
        {
            if(SystemSpeedIndex<28)
            {
                ++SystemSpeedIndex;
                SetSpeed(SystemSpeedIndex);
            }
            else
            {
                LEDFlash(6);
            }
        }
    }
}

3.8音乐播放函数:

SelectMusic:索引选择音乐

函数参数说明:

SoundIndex:一个无符号字符(unsigned char),用作音乐选择的索引。

函数返回值:

函数返回一个指向unsigned char的指针,该指针指向被选中音乐数组的第一个元素的地址。

函数逻辑:

根据SoundIndex的值,switch语句将选择相应的音乐数组。
每个case对应一个可能的索引值,当索引匹配时,将MusicAddress设置为对应音乐数组的起始地址。
如果没有匹配的索引,default分支将不会执行任何操作,函数将返回一个空指针(0)。
选中的音乐数组的地址随后可以被用于播放函数,以按顺序播放音乐数组中的音符。

unsigned char * SelectMusic(unsigned char SoundIndex)
{
    unsigned char *MusicAddress = 0;
    switch (SoundIndex)
    {    
        case 0x00:
            MusicAddress = &Music_Girl[0];    //挥着翅膀的女孩
            break;
        case 0x01:
            MusicAddress = &Music_Same[0];    //同一首歌
            break;
        case 0x02:
            MusicAddress = &Music_Two[0];    //两只蝴蝶
            break;
        case 0x03:
            break;
        case 0x04:
            break;
        case 0x05:
            break;
        case 0x06:
            break;
        case 0x07:
            break;
        case 0x08:
            break;
        case 0x09:
            break;
        default:break;
    }
    return MusicAddress;
}

PlayMusic:播放音乐

void PlayMusic(void)
{
    Delay1ms(200);
    Play(SelectMusic(MusicIndex),0,3,360);
}

四.主函数说明:

初始化CPU、声音和定时器。
循环检测按键输入,根据按键调用KeyDispose函数处理不同的按键事件。
如果RunMode是0x09,调用PlayMusic播放音乐。

main()
{
    unsigned char Key;
    InitialCPU();
    InitialSound();
    InitialTimer2();

    while(1)
    {
        Key = GetKey();
        if(RunMode==0x09)
        {
            PlayMusic();
        }
        if(Key!=0x00)
        {
            KeyDispose(Key);
        }
    }
}

五.仿真电路图

5.1电路图设计:

5.2八种模式:

MODE0 & MODE1 & MODE2:

MODE3:

MODE4:

MODE5:

MODE6:

MODE7:

MODE8:

六.总结

该项目主要用于控制LED显示和音乐播放,同时具备按键输入功能。程序通过不同的模式控制LED的显示效果,使用定时器中断来切换显示模式,并能够根据按键输入来改变运行模式、播放音乐或调整系统速度。

通过该项目,学会了如何显示数码管,学会了用按键来改变模式,改变数码管显示模式。

通过该项目,学会了如何定义定时器,如何用定时器进行中断。

通过该项目,学会了如何定义音乐编码,以及用扬声器来播放音乐。