2020年底做的一个东西,纯属个人爱好。一直想开源但是因为它是一个很大工程,当时做的时候时间很紧张没有录制过程,而且初次试做过程中也发现了很多可改进的地方,一直想着有朝一日能重做一个版本,但是工程量实在太巨大了,也不方便在家做,只好无限搁置。今天是一个特殊日子,就先把源码拿出来整理一下吧。
设计很简单,一个一键无锁开关,每接通一下播放一次固定音频,第一次接通亮一组LED(两个),第二次接通亮两组LED,第三次接通亮三组LED,第四次熄灭全部LED回到初始状态。
主控是通过8051单片机实现的,选用的是STC12C2052,音频播放则是使用了DFPlayer Mini。电路图待补。
参考一本书里提供的流水灯例程,但它是用Keil μVersion写的工程,Keil免费版对编译完的16进制文件大小有限制……所以我只好换了免费的SDCC编译器+Code Blocks,它俩的一些定义有差别,比如寄存器和位定义。
流程设计没什么难的,就是循环检测一个全局变量,开关接通做外部中断,一次中断修改一下全局变量的值,循环变化。用了I/O接口P1做输出,标准双向输入/输出工作方式,6个引脚连了6个LED,本来把音效也放在8051里控制了,后来发现接线很麻烦且没必要,都是一键无锁开关,不如直接接开关了。主控程序用C语言写的,下面上代码。

/*
Red Queen Exceed and Engine Sound
 */

#include <mcs51/8051.h>

#define DY_PORT     P1      //output
#define DY_SPEED    1000    //led on time, ms

__sfr __at 0xE1 WDT_CONTR;
__sbit __at 0xB3 DY_KEY;    //input signal
unsigned char MENU = 0;

void delay (unsigned int a){ // 1ms time delay
    unsigned int i;
    while( --a != 0){
        for(i = 0; i < 600; i++);
    }
}

void INT1Fun(void) __interrupt 2 __using 3 {    //external interrupt 1 for register bank 3
    EX1 = 0;            //disable INT1
    if(DY_KEY == 0){    //signal in
        delay(20);      //delay 20ms    //anti shake
        if(DY_KEY == 0){ //signal in
            //DY_PORT = 0x3F; //sound//move to switch
            MENU++;
            if(MENU >3){    //three status
                MENU = 0;
            }
            while(DY_KEY == 0); //wait for switch off
        }
    }
       EX1 = 1; //enable INI1
}

void main(void)
{
    EA         = 1;             //enable CPU interrupt
    IT1     = 1;             //enable INT1 falling edge
    EX1     = 1;             //enable INT1
    WDT_CONTR = 0;          //disable watch dog

    /*//reset test
    DY_PORT = 0x7C;
    delay(3000);
    DY_PORT = 0x70;
    delay(3000);*/

    while(1) {
        if (MENU == 0) {
            DY_PORT = 0xFF; //OFF
        }
        if (MENU == 1) {    //Exceed 1
            DY_PORT = 0x7C; //one set of leds
            //delay(5000);
        }
        if (MENU == 2) {    //Exceed 2
            DY_PORT = 0x70; //two sets of leds
            //delay(5000);
        }
        if (MENU == 3) {    //Exceed 3
            DY_PORT = 0x40; //three sets of leds
            //delay(5000);
        }
    }

}

SDCC的位定义和Keil不太一样:

__sbit __at 0xB3 DY_KEY;  //SDCC
sbit DY_KEY = P3 ^ 3;     //Keil

还有寄存器,SDCC里是:
__sfr __at 0xE1 WDT_CONTR;

头文件也不太一样:

#include <mcs51/8051.h>    //SDCC
#include <REG51.h>         //Keil

后面还有一些调试过程中的这样那样的内容。待补充。


locking
4 声望1 粉丝