自学内容网 自学内容网

单片机裸机程序 —— 设计模式


软件设计模式的用途

专业的程序员不会在知道需求后,马上脑热地去敲代码,然后一边调试一边修复bug。好习惯是把前期工作做好再开始敲键盘,比如选定一个合适的设计模式,画好流程图等,正所谓磨刀不误砍柴工。

软件设计模式的重要性体现在以下几点:

一、提高软件质量

  1. 增强可靠性:设计模式经过了大量实践的检验,遵循设计模式可以使软件结构更加稳定,减少潜在的错误和漏洞。例如,使用单例模式可以确保一个类只有一个实例,避免了多个实例可能导致的资源冲突和数据不一致问题。
  2. 提升可维护性:良好的设计模式使得软件代码更易于理解和修改。当软件需要进行功能扩展或修复 bug 时,开发人员可以更快速地定位问题所在,并进行有效的修改。比如,采用策略模式可以将不同的算法封装在独立的策略类中,当需要更换算法时,只需修改少量的代码,而不会影响到整个系统的结构。

二、提高开发效率

  1. 加速开发过程:开发人员可以直接应用成熟的设计模式,而不必从头开始设计解决方案。这大大节省了开发时间,特别是在面对复杂问题时。例如,在开发一个图形界面应用时,使用观察者模式可以轻松实现界面元素与数据模型的同步更新,无需为每个界面元素单独编写更新逻辑。
  2. 促进团队协作:设计模式提供了一种通用的语言和方法,使得团队成员之间能够更好地沟通和协作。大家对设计模式的理解和应用可以使代码风格更加统一,降低了团队协作的难度。

三、增强软件的可扩展性

  1. 轻松应对变化:随着业务需求的不断变化,软件需要不断进行功能扩展和改进。设计模式使得软件具有更好的扩展性,能够更容易地适应新的需求。例如,使用装饰器模式可以在不修改原有代码的基础上,为对象动态地添加新的功能,满足不断变化的业务需求。
  2. 支持软件的进化:软件在其生命周期中会不断发展和演变,设计模式为软件的进化提供了坚实的基础。通过合理地应用设计模式,可以使软件在面对新的挑战和机遇时,能够更加灵活地进行调整和改进。

四、实现软件的可复用性

  1. 代码复用:设计模式本身就是一种可复用的解决方案,开发人员可以在不同的项目中复用相同的设计模式。这不仅提高了开发效率,还减少了代码的重复编写,降低了出错的可能性。例如,工厂模式可以根据不同的条件创建不同类型的对象,在多个项目中,如果都有创建对象的需求,就可以复用工厂模式的代码。
  2. 设计复用:设计模式所代表的设计思想也可以被复用。开发人员可以借鉴设计模式的理念,应用到新的问题领域中,创造出更加优秀的软件设计。

一、轮询模式

这是一种简单直接的设计模式,从上往下,一步一步来执行,必须等待上一步执行结束才到这步执行。程序不断地循环检查各个输入设备或事件源的状态,当检测到特定条件满足时,执行相应的处理操作。

void main(void)
{
while(1)//轮询程序
{
led();
key();
...
}
}

通常每个裸机程序的主程序都有一个while循环,这个循环的主要作用是什么?

保持程序持续运行

单片机在启动后需要持续执行特定的任务。如果没有 while 循环,主程序在执行完一次后就会结束,无法实现对外部事件的持续监测和响应。例如,在一个温度监测系统中,单片机需要不断读取温度传感器的数据并进行处理。如果没有循环,程序只会读取一次温度值后就停止运行,无法持续监测温度变化。

等待中断事件

在很多情况下,单片机需要等待外部中断事件的发生。while 循环可以让程序处于一种等待状态,直到中断被触发。当中断发生时,单片机将暂停当前的主程序执行,转而去处理中断服务程序。处理完中断后,又会回到主程序的 while 循环继续等待下一个中断。例如,当有按键按下时产生中断,单片机可以在中断服务程序中进行相应的处理,如改变某个输出状态或执行特定的操作。

实现周期性任务

通过在 while 循环中设置适当的延迟或定时器,可以实现周期性的任务执行。例如,每隔一定时间发送一次数据、刷新显示屏或者进行传感器数据采集等。这样可以确保系统按照预定的时间间隔进行操作,保证系统的稳定性和可靠性。

便于程序调试和扩展

有了 while 循环,程序的执行流程更加清晰,便于调试和修改。开发人员可以在循环中设置断点,逐步跟踪程序的执行过程,找出问题所在。同时,在需要添加新功能时,可以方便地在 while 循环中插入相应的代码,而不会对整个程序的结构造成太大的影响。

轮询模式的优缺点:

优点 —— 实现简单,容易理解和调试。
缺点 —— 效率较低,当需要处理多个事件时,可能会因为频繁的循环检查而浪费 CPU 资源。还有如果某一步执行耗时长,其它步执行周期得不到保证。

二、前后台模式

单片机可以响应外部中断请求。当特定的外部事件发生时,如定时器溢出、按键按下等,会触发中断,那么优先去中断服务程序执行相应的处理。这种模式可以及时响应外部事件,提高系统的实时性。

void main()
{
    while (1)
    {
        // 后台程序
        led();
    }
}
 
// 前台程序
void 按键_中断()
{
    key();
}

中断模式的优缺点:

优点 —— 能够快速响应紧急事件,不占用 CPU 资源在等待事件发生上。
缺点 —— 中断处理程序需要尽量简洁,否则可能会影响系统的稳定性。比如,中断程序要是执行过长,将会导致迟迟离不开中断,并且要是创建多个中断还会出现抢占优先级的情况。

三、时间片模式

时间片模式采用定时器驱动,是前后台模式的一种,可以按照不用的频率执行各种任务函数。

void main()
{
    while (1)
    {
        // 后台程序
    }
}
 
// 前台程序: 每1秒触发一次中断
void 定时器_中断()
{
    static int cnt = 0;
    cnt++;
    if (cnt % 2 == 0)
    {
        led();
    }
    else if (cnt % 5 == 0)
    {
        beep();
    }
}

时间片模式的优缺点:

优点 —— 比较适用于严格调用周期性的函数,并且每一个函数执行的时间不能超过一个定时器周期。
缺点 —— 函数之间互相影响,比如周期性函数执行时间长影响另一个周期性函数的执行。

四、状态机模式

将系统或功能模块的运行状态抽象为不同的状态,根据不同的输入和当前状态进行状态转移,并执行相应的操作。例如,一个简单的流水灯控制系统可以分为不同的状态,如灯亮、灯灭、闪烁等,根据按键输入或定时器事件进行状态转移。

typedef enum {
    OFF_STATE,
    ON_STATE
} LightState;

void controlLight(bool buttonPressed) {
    static LightState state = OFF_STATE;
    switch (state) {
        case OFF_STATE:
            if (buttonPressed) {
                state = ON_STATE;
                // 打开灯的操作
            }
            break;
        case ON_STATE:
            if (buttonPressed) {
                state = OFF_STATE;
                // 关闭灯的操作
            }
            break;
    }
}

状态机模式的优缺点:

优点 —— 结构清晰,易于理解和维护,特别适合处理复杂的逻辑流程。
缺点 —— 对于状态较多的系统,状态转移图可能会变得复杂。


原文地址:https://blog.csdn.net/wu19870319/article/details/142981547

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!