当前位置:网站首页>分享几种管理C程序中标志位的方法
分享几种管理C程序中标志位的方法
2022-07-28 05:08:00 【小何在线】
一、简介
在嵌入式开发中,难免会涉及到非常多的标志位处理,特别是玩单片机、裸机开发的朋友,比如跟一些模块配合联调会遇到各种信号是否到位、成功等等状态,而这些信号大多都是bool类型,1个bit即可进行标识。当然,如果仅仅是几个标志,直接拿个uint8_t的整形来进行标识也不会影响什么,但如果特别多的话似乎就比较废RAM了。为了更好的管理这些标志位等,有个如下几种方式供大家更好的管理这些标志位 。
二、位域直接标识
采用位域是管理这些标志位比较直接且方便的方式,代码如下所示:
typedef union _tag_SystemFlag
{
uint16_t all;
struct
{
uint16_t Run :1;
uint16_t Alarm :1;
uint16_t Online :1;
uint16_t TimerOver :1;
uint16_t Reserver :12;
}bit;
} uSystemFlag;
uSystemFlag unSystemFlag;
int main(int argc, char *argv[]) {
unSystemFlag.all = 0x00; //系统标志清除
unSystemFlag.bit.Run = 1; //置位
unSystemFlag.bit.Alarm = 1;
unSystemFlag.bit.Online = 1;
unSystemFlag.bit.TimerOver = 1;
unSystemFlag.bit.Run = 0; //清零
unSystemFlag.bit.Alarm = 0;
unSystemFlag.bit.Online = 0;
unSystemFlag.bit.TimerOver = 0;
return 0;
}
这些标志位的操作无非就是置位、清零,以及读取三种方式。
但如代码中这样的操作方式在语句或语义表达上还是不够直观。
我经常谈到,代码可以不写注释,不过你的每个变量、函数名称等需要足够的直观,所以很多朋友习惯把这些标志封装起来。
三、枚举+移位
为了更好的表达一般会对标志位进行进一步的封装,如下代码所示:
typedef enum _tag_Flag {
cEmRun = 0,
cEmAlarm,
cEmOnline,
cEmTimerOver
}emSystemFlag;
uint16_t SystemFlag ;
//置位
void SetFlag(emSystemFlag flag)
{
SystemFlag |= ((uint16_t)0x01) << flag;
}
//清除
void ClrFlag(emSystemFlag flag)
{
SystemFlag &= ~(((uint16_t)0x01) << flag);
}
//获得状态
uint8_t GetFlag(emSystemFlag flag)
{
return (((SystemFlag & (((uint16_t)0x01) << flag)) != 0)? true:false);
}
int main(int argc, char *argv[]) {
SetFlag(cEmAlarm);
if(GetFlag(cEmAlarm) == true)
{
printf("ClrFlag\r\n");
ClrFlag(cEmAlarm);
}
else
{
printf("SetFlag\r\n");
SetFlag(cEmAlarm);
}
return 0;
}
当然,封装成函数是相对比较耗时的,不过代码也会更加的易懂,如果确实容忍不了函数封装带来的时间消耗,把函数修改为宏代码片段或者内敛函数(前提是编译器支持)也是可行的。
四、宏列表
以前跟大家介绍过,用宏自动化的生成各种代码片段,以使得代码更加的紧凑。当然可读性会相对降低一点,但对于重复性代码就不需要太多考虑了。
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char uint8_t;
typedef unsigned int uint16_t;
typedef signed char int8_t;
typedef int int16_t;
#define true 1
#define false 0
//宏列表
#define TAG_LIST(tag) \ tag(Run)\ tag(Alarm)\ tag(Online)\ tag(TimerOver)
//枚举处理
#define DEFINE_TAG(_tag) _tag,
enum Flag {
None = 0,
TAG_LIST(DEFINE_TAG)
EmMAX
};
#undef DEFINE_TAG
//位定义变量
uint16_t SysFlag = 0x0000;
//通用方法定义
uint8_t GetFlags(uint16_t mask)
{
return ((SysFlag & mask) != 0)? true:false;
}
void SetFlags(uint16_t mask)
{
SysFlag |= mask;
}
void ClrFlags(uint16_t mask)
{
SysFlag &= ~mask;
}
//自动生成三类函数定义
#define FLAG_Operater(flag) \ uint8_t get##flag() {
\ return GetFlags(1 << flag);\ }\ void set##flag() {
\ SetFlags(1 << flag);\ }\ void clr##flag() {
\ ClrFlags(1 << flag);\ }
//反向函数关联
TAG_LIST(FLAG_Operater)
int main(int argc, char *argv[]) {
setRun();
setAlarm();
if(getAlarm() == true)
{
printf("set \r\n");
}
else
{
printf("clr \r\n");
}
return 0;
}
如果以前有过类似代码处理的朋友,应该看这段代码还是比较轻松的吧,如果有点生疏,可以一层一层展开了解。
其主要的功能是,通过宏替换和代码拼接符号,自动的生成通用的代码片段。这样做的好处是,不再需要我们在代码中定义一大堆setflag、clrflag、getflag等函数。
通过上面的代码当我们向TAGLIST宏中添加一个标识符,即可生成一系列相关的操作函数等。
这样一方面可以及简化代码,同时也能避免一些人工编码带来的错误。
边栏推荐
- Paper reading notes -- crop yield prediction using deep neural networks
- Implementation of simple upload function in PHP development
- 【ARXIV2205】EdgeViTs: Competing Light-weight CNNs on Mobile Devices with Vision Transformers
- How does Alibaba use DDD to split microservices?
- 阿里怎么用DDD来拆分微服务?
- 塑料可以执行GB/T 2408 -燃烧性能的测定吗
- Dynamic SQL and paging
- [learning record] data enhancement 1
- What is the reason why the easycvr national standard protocol access equipment is online but the channel is not online?
- Redis configuration file explanation / parameter explanation and elimination strategy
猜你喜欢

【ARIXV2204】Neighborhood attention transformer

FreeRTOS learning (I)

Introduction to testcafe

【ARXIV2203】CMX: Cross-Modal Fusion for RGB-X Semantic Segmentation with Transformers

这种动态规划你见过吗——状态机动态规划之股票问题(中)

What is the reason why the easycvr national standard protocol access equipment is online but the channel is not online?

100 lectures on Excel practical application cases (XI) - tips for inserting pictures in Excel

What SaaS architecture design do you need to know?

猿辅导技术进化论:助力教与学 构想未来学校

From the basic concept of micro services to core components - explain and analyze through an example
随机推荐
How to send and receive reports through outlook in FastReport VCL?
FPGA: use PWM wave to control LED brightness
Leetcode 15. sum of three numbers
HDU 2874 connections between cities
RT based_ Distributed wireless temperature monitoring system of thread (I)
100 lectures on Excel practical application cases (XI) - tips for inserting pictures in Excel
Jsonp single sign on permission verification
Activation functions sigmoid, tanh, relu in convolutional neural networks
(3.1) [Trojan horse synthesis technology]
The research group passed the thesis defense successfully
Have you ever seen this kind of dynamic programming -- the stock problem of state machine dynamic programming (Part 2)
【ARXIV2205】EdgeViTs: Competing Light-weight CNNs on Mobile Devices with Vision Transformers
HDU 3666 the matrix problemdifferential constraint + stack optimization SPFA negative ring
Data imbalance: comprehensive sampling of anti fraud model (data imbalance)
Inspire domestic students to learn robot programming education for children
RT based_ Distributed wireless temperature monitoring system based on thread
Interpretation of afnetworking4.0 request principle
Redux basic syntax
Applet import project
Easycvr Video Square snapshot adding device channel offline reason display