需要源程序 单片机protues

定时中断控制流水灯。 采用定时中断方法控制LED灯循环显示,fosc约为12MHz,闪烁速率约为2秒/次:亮灯顺序为D0→D1→D2→…→D6→D7→学号,即8只发光二极管依次点亮,之后8只发光二极管显示0119的二进制数, 其中D7D6显示01,D5D4D3D2D1D0显示最后19。

以下是基于51单片机的代码,使用Keil C编译器,同时在Proteus中进行仿真。

#include <reg51.h>

#define FOSC 12000000L
#define TIMER0_RELOAD_VALUE 65536L - (FOSC / 12 / 50)

sbit LED = P1^0; // LED连接到P1.0
sbit D0 = P2^0; // D0连接到P2.0
sbit D1 = P2^1; // D1连接到P2.1
sbit D2 = P2^2; // D2连接到P2.2
sbit D3 = P2^3; // D3连接到P2.3
sbit D4 = P2^4; // D4连接到P2.4
sbit D5 = P2^5; // D5连接到P2.5
sbit D6 = P2^6; // D6连接到P2.6
sbit D7 = P2^7; // D7连接到P2.7

unsigned char LED_state = 0; // LED状态
unsigned char LED_count = 0; // LED计数器
unsigned char LED_direction = 1; // LED方向

void timer0_init() {
    TMOD &= 0xF0; // 清除T0的控制位
    TMOD |= 0x01; // 设置T0为模式1
    TH0 = TIMER0_RELOAD_VALUE / 256; // 设置T0的重载值
    TL0 = TIMER0_RELOAD_VALUE % 256;
    ET0 = 1; // 允许T0中断
    TR0 = 1; // 启动T0
    EA = 1; // 允许中断
}

void timer0_isr() interrupt 1 {
    TH0 = TIMER0_RELOAD_VALUE / 256; // 重新设置T0的重载值
    TL0 = TIMER0_RELOAD_VALUE % 256;
    LED_count++; // LED计数器加1
    if (LED_count >= 25) { // 如果计数器达到25,即0.5秒
        LED_count = 0; // 重置计数器
        if (LED_direction == 1) { // 如果LED方向为正向
            LED_state <<= 1; // LED状态左移1位
            if (LED_state == 0) { // 如果LED状态为0
                LED_state = 1; // 设置LED状态为1
            }
            if (LED_state == 0x80) { // 如果LED状态为0x80
                LED_direction = 0; // 设置LED方向为反向
            }
        } else { // 如果LED方向为反向
            LED_state >>= 1; // LED状态右移1位
            if (LED_state == 0) { // 如果LED状态为0
                LED_state = 0x80; // 设置LED状态为0x80
            }
            if (LED_state == 1) { // 如果LED状态为1
                LED_direction = 1; // 设置LED方向为正向
            }
        }
        LED = LED_state & 0x01; // 更新LED状态
        D0 = (LED_state >> 1) & 0x01; // 更新D0状态
        D1 = (LED_state >> 2) & 0x01; // 更新D1状态
        D2 = (LED_state >> 3) & 0x01; // 更新D2状态
        D3 = (LED_state >> 4) & 0x01; // 更新D3状态
        D4 = (LED_state >> 5) & 0x01; // 更新D4状态
        D5 = (LED_state >> 6) & 0x01; // 更新D5状态
        D6 = (LED_state >> 7) & 0x01; // 更新D6状态
        D7 = 0; // 设置D7状态为0
    }
}

void main() {
    timer0_init(); // 初始化定时器0
    while (1) {
        D7 = 0; // 设置D7状态为0
    }
}

在Proteus中,需要添加一个8051微控制器和8个LED灯,以及连接线路。将编译后的HEX文件加载到8051微控制器中,然后启动仿真即可看到LED灯的循环显示和0119的二进制数的显示。