3. 流水灯效果

流水灯效果 学习卡片

任务说明

在单片机开发板上连接8个LED(分别接P1.0~P1.7),编写程序使LED从P1.0到P1.7依次点亮,每个LED点亮200ms后熄灭并点亮下一个,形成流水效果。当最后一个LED点亮结束后,从头开始循环。本案例使用Keil C51编写,目标芯片为STC89C52(兼容AT89C52),晶振11.0592MHz。

硬件连接

STC89C52 P1.0 ~ P1.7 P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 330Ω 330Ω 330Ω 330Ω 330Ω 330Ω LED1 LED2 LED3 LED4 LED5 LED6 GND P1口输出低电平时LED点亮(共阳接法) LED7、LED8接P1.6、P1.7,连接方式同上

代码实现

采用循环移位方式实现流水灯。定义延时函数delay_ms(),通过双重循环实现约1ms延时。主循环中,将0xFE(二进制11111110,即P1.0输出低电平)赋给P1口,使LED1点亮,延时200ms后,通过左移操作将低电平移到下一位,实现LED依次点亮。

#include <reg52.h>

// 延时函数:约延时1ms(晶振11.0592MHz)
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 123; j++);
    }
}

void main() {
    unsigned char led = 0xFE;  // 初始值:1111 1110,P1.0输出低电平
    
    while (1) {
        P1 = led;              // 将当前值输出到P1口
        delay_ms(200);         // 延时200ms
        
        led = (led << 1) | 0x01;  // 左移一位,最低位置1
        // 当低电平移到最高位后(led = 0x7F),下一次左移变为0xFF
        // 此时需要重新赋值为0xFE,形成循环
        if (led == 0xFF) {
            led = 0xFE;        // 重新从P1.0开始
        }
    }
}

代码说明

代码中led = (led << 1) | 0x01实现左移一位并将最低位置1。例如:0xFE(11111110)左移一位后为0xFC(11111100),按位或0x01后变为0xFD(11111101),即低电平从P1.0移到P1.1。当led变为0x7F(01111111)时,下一次左移得到0xFE(11111110),按位或0x01后为0xFF(11111111),此时所有LED熄灭,通过if判断重新赋值为0xFE,实现循环。

编译与烧录

在Keil C51中新建工程,选择Atmel AT89C52或STC89C52芯片,创建源文件输入上述代码,编译生成HEX文件。使用STC-ISP软件通过串口将HEX文件烧录到单片机中。

验证方法

烧录完成后,给开发板上电,观察8个LED是否从LED1到LED8依次点亮,每个LED点亮约200ms后熄灭并点亮下一个。当LED8点亮结束后,LED1重新开始点亮,形成循环流水效果。若观察到LED依次循环点亮,则本案例实现成功。