嵌入式开发技巧:舍弃标志位,用宏定义函数实现程序单次运行

一、介绍

在嵌入式开发过程中,我们经常会使用标志位实现部分代码的单次执行。如下:

cpp 复制代码
uint8_t Flag = 0;//标志位

while(1)
{
    if(Flag == 0)
    {
        LED_ON();//LED点亮
        Flag == 1;
    }
}

这样,我们就实现了只运行一次LED_ON函数,也就是单次执行。

如果复杂一点的程序想实现单次执行,用标志位的话就会让程序就会变得非常不美观,可读性也变得更差了,非常的不优雅。

那如果我使用宏定义函数实现单次执行

cpp 复制代码
while(1)
{
    RunOnce(block1,//单次执行,只运行一次
    {
        LED_ON();
        //可添加其他代码
    });
}

又或者是printf实现单次执行

cpp 复制代码
int main(void) 
{

    RunOnce(block1, {printf("代码块1执行了一次!\n");});// 首次执行代码块
    
    RunOnce(block1, {printf("代码块1执行了一次!\n");});// 已执行过,不执行

    ResetOnce(block1);  // 重置block1的状态
    RunOnce(block1, {printf("代码块1执行了一次!\n");});  // 重置后可再次执行
    
    return 0;
}

怎么样,用了宏定义函数之后,实现程序的单次执行是不是变得更加的优雅了?

话不多说,直接看例程

二、例程

我OnceRun_Port.h这个头文件用来装宏定义函数。引用这个头文件之后,就可以直接使用,有非常强的复用性。

OnceRun_Port.h

cpp 复制代码
#ifndef __OnceRun_Port_h_
#define __OnceRun_Port_h_

#include <stdio.h>

// 宏定义:为代码块生成单次执行功能,需指定唯一标识名name
// block为待执行的代码块(可包含多条语句,用{}括起)
#define RunOnce(name, block) do \
    { \
        static int name##_executed = 0; \
        if (!name##_executed) \
        { \
            block; \
            name##_executed = 1; \
        } \
    } while(0)

// 宏定义:重置指定标识名的代码块执行状态
#define ResetOnce(name) do \
    { \
        static int name##_executed; \
        name##_executed = 0; \
    } while(0)

#endif

使用方法

cpp 复制代码
int main(void) 
{
    // 测试代码块1:单次执行
    printf("代码块1第1次:");
    RunOnce(block1, 
        {  
            printf("代码块1执行了一次!\n");
            // 可添加更多语句,例如:
            // printf("代码块1的第二行语句\n");
        }
    );  // 首次执行代码块
    
    printf("代码块1第2次:");
    RunOnce(block1, 
        {
            printf("代码块1执行了一次!\n");
        }
    );  // 已执行过,不执行
    
    // 测试代码块2:独立于代码块1
    printf("\n代码块2第1次:");
    RunOnce(block2, 
        {  // 标识名block2,独立状态
            printf("代码块2执行了一次!\n");
        }
    );  // 首次执行
    
    printf("代码块2第2次:");
    RunOnce(block2, 
        {
            printf("代码块2执行了一次!\n");
        }
    );  // 已执行过,不执行
    
    // 重置代码块1后再次执行
    printf("\n重置代码块1后:");
    ResetOnce(block1);  // 重置block1的状态
    RunOnce(block1, 
        {
            printf("代码块1执行了一次!\n");
        }
    );  // 重置后可再次执行
    
    return 0;
}

三、注意事项

当你调用ResetOnce函数后,可能会出现警告,显示"block1_executed"从未使用过。这个警告可以无需理会,我调用之后ResetOnce仍然能重置代码块,不影响使用。

相关推荐
执笔论英雄7 小时前
【大模型学习cuda】入们第一个例子-向量和
学习
wdfk_prog7 小时前
[Linux]学习笔记系列 -- [drivers][input]input
linux·笔记·学习
ouliten8 小时前
cuda编程笔记(36)-- 应用Tensor Core加速矩阵乘法
笔记·cuda
孞㐑¥9 小时前
算法——BFS
开发语言·c++·经验分享·笔记·算法
代码游侠10 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Gary Studio10 小时前
rk芯片驱动编写
linux·学习
mango_mangojuice10 小时前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习
工程师老罗10 小时前
YOLOv1 核心知识点笔记
笔记·yolo
lingggggaaaa10 小时前
安全工具篇&动态绕过&DumpLsass凭据&Certutil下载&变异替换&打乱源头特征
学习·安全·web安全·免杀对抗
PP东10 小时前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable