3. 流水灯效果
任务说明
在单片机开发板上连接8个LED(分别接P1.0~P1.7),编写程序使LED从P1.0到P1.7依次点亮,每个LED点亮200ms后熄灭并点亮下一个,形成流水效果。当最后一个LED点亮结束后,从头开始循环。本案例使用Keil C51编写,目标芯片为STC89C52(兼容AT89C52),晶振11.0592MHz。
硬件连接
代码实现
采用循环移位方式实现流水灯。定义延时函数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依次循环点亮,则本案例实现成功。