【31】单片机编程核心技巧:Switch驱动多任务跑马灯

【31】单片机编程核心技巧:Switch驱动多任务跑马灯

七律 · 双驱

Switch双驱控双灯,状态分治显神通。
步骤变量定乾坤,定时中断显锋芒。
电光石火随心转,程序逻辑自分明。
单片机中真王者,一招一式定乾坤。


摘要

本文以STC8H单片机为例,通过Switch语句实现两路独立的跑马灯控制,系统阐述其多任务并行机制、步骤变量管理及代码实现。Switch语句通过独立的步骤变量(run_step1run_step2)分别控制两路LED的流动状态,结合定时中断实现精准的时间同步,展现了其作为“编程战斗机”的高效性与扩展性。


引言

Switch语句是单片机编程中的“战斗机”,通过独立步骤变量(如run_step1run_step2)可将多任务分解为多个可管理的状态。本文以两路跑马灯为例,通过Switch语句驱动双状态机,并结合定时中断实现精准的时间控制,为开发者提供多任务并行的编程范式。


1. Switch语句的核心地位

1.1 多任务并行的实现逻辑

两路跑马灯需独立控制,Switch语句通过以下方式实现:

  1. 独立步骤变量run_step1run_step2分别控制两路LED的流动状态。
  2. 定时中断计数:通过定时器中断更新两个独立计数器cnt1cnt2,实现精准时间控制。
  3. 状态迁移:每个case分支通过条件判断切换状态,形成独立循环。

1.2 步骤变量的定义规范

  • 命名规则:统一后缀为_step(如run_step1run_step2),明确其作为程序控制核心的角色。
  • 作用:通过修改步骤变量的值,可无缝切换对应LED的流动位置,实现逻辑独立。

2. 状态机设计与Switch实现

2.1 硬件配置

  • LED1组
    • 阳极通过 510Ω 电阻连接至 P1.0~P1.7 引脚。
  • LED2组
    • 阳极通过 510Ω 电阻连接至 P2.0~P2.7 引脚。

2.2 状态机结构

2.2.1 LED1组状态机
  • **状态07**:分别对应LED1LED8的点亮。
  • 流动方向:从LED1到LED8依次点亮。
2.2.2 LED2组状态机
  • **状态07**:分别对应LED8LED1的反向点亮。
  • 流动方向:从LED8到LED1依次点亮。

2.3 代码实现

#include   

// 定义LED1组引脚(P1.0~P1.7)  
#define LED1_PORT   P1  
#define LED1_PINS   8  

// 定义LED2组引脚(P2.0~P2.7)  
#define LED2_PORT   P2  
#define LED2_PINS   8  

// 定义LED亮灯时间(单位:中断次数)  
#define LED1_ON_TIME   1000  // LED1组每灯1秒  
#define LED2_ON_TIME   2000  // LED2组每灯2秒  

// 步骤变量与计数器  
unsigned char run_step1 = 0, run_step2 = 0;  
unsigned long cnt1 = 0, cnt2 = 0;  

// 定时器1中断服务函数  
void timer1_isr() interrupt 3 {  
    TH1 = 0xFC;  // 重装定时器初值(1ms中断周期)  
    TL1 = 0x00;  
    cnt1++;       // 更新LED1组计数器  
    cnt2++;       // 更新LED2组计数器  
}  

void main() {  
    // 初始化IO口  
    P1M0 = 0xFF; P1M1 = 0x00;  // P1为推挽输出  
    P2M0 = 0xFF; P2M1 = 0x00;  // P2为推挽输出  

    // 定时器1配置(1ms中断周期)  
    TMOD |= 0x01;          // 设置定时器1为模式1(16位)  
    TH1 = 0xFC;            // 初值计算:系统时钟11.0592MHz,定时1ms  
    TL1 = 0x00;  
    ET1 = 1;               // 使能定时器1中断  
    EA = 1;                // 全局中断使能  
    TR1 = 1;               // 启动定时器  

    // 初始状态:所有LED灭  
    LED1_PORT = 0x00;  
    LED2_PORT = 0xFF;      // LED2组初始状态为反向流动起点  

    while(1) {  
        // Switch语句驱动LED1组状态机  
        switch(run_step1) {  
            case 0: // LED1亮  
                if(cnt1 > LED1_ON_TIME) {  
                    cnt1 = 0;  
                    LED1_PORT = 0x01; // 只点亮LED1(P1.0)  
                    run_step1 = 1;  
                }  
                break;  
            // 其他状态(1~7)类似,依次点亮LED2~LED8  
            // ...(代码省略,逻辑与前文类似)  
            case 7: // LED8亮  
                if(cnt1 > LED1_ON_TIME) {  
                    cnt1 = 0;  
                    LED1_PORT = 0x80; // 只点亮LED8(P1.7)  
                    run_step1 = 0;  
                }  
                break;  
        }  

        // Switch语句驱动LED2组状态机  
        switch(run_step2) {  
            case 0: // LED8亮  
                if(cnt2 > LED2_ON_TIME) {  
                    cnt2 = 0;  
                    LED2_PORT = 0x80; // 只点亮LED8(P2.7)  
                    run_step2 = 1;  
                }  
                break;  
            // 其他状态(1~7)类似,依次点亮LED7~LED1  
            // ...(代码省略,逻辑与前文类似)  
            case 7: // LED1亮  
                if(cnt2 > LED2_ON_TIME) {  
                    cnt2 = 0;  
                    LED2_PORT = 0x01; // 只点亮LED1(P2.0)  
                    run_step2 = 0;  
                }  
                break;  
        }  
    }  
}  

2.4 关键代码解析

  • 步骤变量控制
    • run_step1控制LED1组的流动方向(正向)。
    • run_step2控制LED2组的流动方向(反向)。
  • 定时中断计数:通过定时器1中断每1ms触发一次,更新两个独立计数器cnt1cnt2
  • 状态迁移逻辑:每个case分支通过条件判断切换状态,形成独立循环。

3. 实验验证

3.1 硬件连接

  • LED1组
    • 阳极通过 510Ω 电阻连接至 P1.0~P1.7 引脚。
    • 阴极接地。
  • LED2组
    • 阳极通过 510Ω 电阻连接至 P2.0~P2.7 引脚。
    • 阴极接地。

3.2 预期结果

  • LED1组
    • LED依次从 P1.0P1.7 逐个点亮,每个LED亮1秒。
  • LED2组
    • LED依次从 P2.7P2.0 反向流动,每个LED亮2秒。

4. 扩展应用

Switch语句的“战斗机”特性可扩展至复杂场景:

  1. 多任务同步:通过修改计数器阈值实现不同速度的流动效果。
  2. 动态模式切换:通过按键输入动态改变流动方向或速度。
  3. 组合控制:结合传感器输入(如光敏电阻)实现环境自适应流动模式。

5. 结论

Switch语句通过独立的步骤变量(run_step1run_step2),将多任务分解为有序状态,结合定时中断实现精准时间控制,是单片机程序的灵魂与支点。本文通过双跑马灯案例验证了其高效性与可扩展性,开发者可基于此范式快速构建多任务并行程序,实现“以Switch为支点,撬动程序设计”的目标。


附录:STC8H定时器配置说明

  1. 定时器1配置
    • TMOD |= 0x01:设置定时器1为模式1(16位定时)。
    • TH1 = 0xFC; TL1 = 0x00:初值计算公式:
      初值 = 65536 − 系统时钟 定时周期 × 12 \text{初值} = 65536 - \frac{\text{系统时钟}}{\text{定时周期} \times 12} 初值=65536定时周期×12系统时钟
      (此处系统时钟为11.0592MHz,定时1ms)。
  2. 中断使能
    • ET1 = 1:使能定时器1中断。
    • EA = 1:全局中断使能。

你可能感兴趣的:(【编程技巧】,单片机,嵌入式硬件,#STC8,#STM32)