Aurora_ch 2024-04-19 21:07 采纳率: 33.3%
浏览 17
已结题

C51单片机C语言流水灯

定时/计数器 T0 工作在方式 1 产生周期 2s 矩形波,控制发光二极管亮 1 秒灭
1 秒,并且循环往复。定时/计数器 T1 工作在方式 1 产生周期 1s 矩形波,控制 发光二极管亮 0.5 秒灭 0.5 秒,并且循环往复。

按流程图编辑代码

img

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-19 21:07
    关注

    引自免费微信小程序:皆我百晓生

    首先,为了实现这个功能,我们需要配置T0和T1定时器工作在方式1,并设置它们的预分频系数。这里我们使用C51汇编指令进行配置。以下是详细的步骤:

    1. 初始化硬件(包括时钟、中断系统、T0和T1定时器)
    2. 设置T0定时器工作在方式1,周期为2秒(即1000ms),通过外部晶振12MHz计算出TH0和TL0的初始值。
    3. 设置T1定时器工作在方式1,周期为1秒(即500ms),同样计算出TH1和TL1的初始值。
    4. 定义一个循环,用于控制LED的亮灭状态,根据T0和T1的溢出中断判断时间到达。
    5. 编写中断服务程序(ISR)处理T0和T1的溢出事件,更新LED的状态。

    下面是完整的C51代码示例:

    #include <reg52.h> // 包含头文件,包含C51的寄存器定义
    
    // LED口选择(这里假设P1.0到P1.7为LED接口)
    #define LED_PORT P1
    #define LED_DDR DDR_P1
    
    void delay_ms(int ms); // 延时函数,用于模拟实际操作
    
    void timer0_isr(void) interrupt 1; // T0中断服务程序
    void timer1_isr(void) interrupt 3; // T1中断服务程序
    
    unsigned char j, i;
    
    void main() {
        LED_DDR = 0xFF; // 设置所有LED为输出
        EA = 1; // 开启全局中断
        EX0 = 1; // 开启T0中断
        EX1 = 1; // 开启T1中断
        
        TH0 = 0xFD; // 计算得到的TH0值,使T0定时器周期约为2s
        TL0 = 0x8F;
        
        TH1 = 0xFF; // 计算得到的TH1值,使T1定时器周期约为1s
        TL1 = 0xFF;
        
        while (1) {
            if (j == 20) { // 每当j达到20,切换T0/T1的控制
                j = 0;
                i = 0;
            }
    
            if (j > 0) { // T0控制LED亮灭
                LED_PORT ^= 0x01 << i; // 取反第i个LED
                if (++i == 8) { // 当遍历完所有LED后重置i
                    i = 0;
                }
            } else { // T1控制LED亮灭
                LED_PORT ^= 0x01 << (i % 8); // 取反当前时刻应该亮的LED
            }
            
            j++;
        }
    }
    
    // 中断服务程序
    void timer0_isr(void) {
        TH0 = 0xFD; // 重新加载TH0值
        TL0 = 0x8F; // 重新加载TL0值
        TR0 = !TR0; // 反转TR0,改变T0的工作模式
    }
    
    void timer1_isr(void) {
        TH1 = 0xFF; // 重新加载TH1值
        TL1 = 0xFF; // 重新加载TL1值
        TR1 = !TR1; // 反转TR1,改变T1的工作模式
    }
    
    // 延时函数,用于模拟实际操作
    void delay_ms(int ms) {
        for (int i = 0; i < ms; i++) {
            for (int j = 0; j < 125; j++) {
                __asm__("NOP");
                __asm__("NOP");
            }
        }
    }
    

    这段代码实现了两个定时器的交替控制,其中delay_ms()函数是一个简单的延时函数,用于模拟实际操作。由于篇幅限制,无法提供流程图绘制,但你可以根据代码逻辑自行创建流程图。注意:此代码仅作为概念验证,实际应用可能需要调整参数以适应具体硬件环境。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月23日
  • 创建了问题 4月19日