0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

管理C程序中标志位的方法

Q4MP_gh_c472c21 来源:最后一个bug 作者:bug菌 2022-05-24 15:33 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嵌入式开发中,难免会涉及到非常多的标志位处理,特别是玩单片机、裸机开发的朋友,比如跟一些模块配合联调会遇到各种信号是否到位、成功等等状态,而这些信号大多都是bool类型,1个bit即可进行标识。

当然,如果仅仅是几个标志,直接拿个uint8_t的整形来进行标识也不会影响什么,但如果特别多的话似乎就比较废RAM了。然而,为了更好的管理这些标志位等,有个如下几种方式供大家更好的管理这些标志位 :

1

位域直接标识

采用位域是管理这些标志位比较直接且方便的方式,代码如下所示:


		

1typedefunion_tag_SystemFlag 2{ 3uint16_tall; 4struct 5{ 6uint16_tRun:1; 7uint16_tAlarm:1; 8uint16_tOnline:1; 9uint16_tTimerOver:1; 10uint16_tReserver:12; 11}bit; 12 13}uSystemFlag; 14 15uSystemFlagunSystemFlag; 16 17intmain(intargc,char*argv[]){ 18 19unSystemFlag.all=0x00;//系统标志清除 20 21unSystemFlag.bit.Run=1;//置位 22unSystemFlag.bit.Alarm=1; 23unSystemFlag.bit.Online=1; 24unSystemFlag.bit.TimerOver=1; 25 26unSystemFlag.bit.Run=0;//清零 27unSystemFlag.bit.Alarm=0; 28unSystemFlag.bit.Online=0; 29unSystemFlag.bit.TimerOver=0; 30 31return0; 32}

这些标志位的操作无非就是置位、清零,以及读取三种方式。

但如代码中这样的操作方式在语句或语义表达上还是不够直观。

我经常谈到,代码可以不写注释,不过你的每个变量、函数名称等需要足够的直观,所以很多朋友习惯把这些标志封装起来。

2

枚举+移位

为了更好的表达一般会对标志位进行进一步的封装,如下代码所示:


		

1typedefenum_tag_Flag{ 2cEmRun=0, 3cEmAlarm, 4cEmOnline, 5cEmTimerOver 6}emSystemFlag; 7 8uint16_tSystemFlag; 9//置位 10voidSetFlag(emSystemFlagflag) 11{ 12SystemFlag|=((uint16_t)0x01)<< flag; 13} 14//清除 15voidClrFlag(emSystemFlagflag) 16{ 17SystemFlag&=~(((uint16_t)0x01)<< flag); 18} 19//获得状态 20uint8_tGetFlag(emSystemFlagflag) 21{ 22return(((SystemFlag&(((uint16_t)0x01)<< flag)) != 0)?true:false); 23} 24 25intmain(intargc,char*argv[]){ 26 27SetFlag(cEmAlarm); 28 29if(GetFlag(cEmAlarm)==true) 30{ 31printf("ClrFlag "); 32ClrFlag(cEmAlarm); 33} 34else 35{ 36printf("SetFlag "); 37SetFlag(cEmAlarm); 38} 39return0; 40}

当然,封装成函数是相对比较耗时的,不过代码也会更加的易懂,如果确实容忍不了函数封装带来的时间消耗,把函数修改为宏代码片段或者内敛函数(前提是编译器支持)也是可行的。

3

宏列表

或许这里才是本文的重中之重~

前跟大家介绍过,用宏自动化的生成各种代码片段,以使得代码更加的紧凑。当然可读性会相对降低一点,但对于重复性代码就不需要太多考虑了。


		

1#include 2#include 3 4typedefunsignedcharuint8_t; 5typedefunsignedintuint16_t; 6typedefsignedcharint8_t; 7typedefintint16_t; 8 9#definetrue1 10#definefalse0 11 12 13//宏列表 14#defineTAG_LIST(tag) 15tag(Run) 16tag(Alarm) 17tag(Online) 18tag(TimerOver) 19 20 21//枚举处理 22#defineDEFINE_TAG(_tag)_tag, 23enumFlag{ 24None=0, 25TAG_LIST(DEFINE_TAG) 26EmMAX 27}; 28#undefDEFINE_TAG 29 30//位定义变量 31uint16_tSysFlag=0x0000; 32 33 34//通用方法定义 35uint8_tGetFlags(uint16_tmask) 36{ 37return((SysFlag&mask)!=0)?true:false; 38} 39 40voidSetFlags(uint16_tmask) 41{ 42SysFlag|=mask; 43} 44 45voidClrFlags(uint16_tmask) 46{ 47SysFlag&=~mask; 48} 49 50 51//自动生成三类函数定义 52#defineFLAG_Operater(flag) 53uint8_tget##flag(){ 54returnGetFlags(1<< flag); 55} 56voidset##flag(){ 57SetFlags(1<< flag); 58} 59voidclr##flag(){ 60ClrFlags(1<< flag); 61} 62 63//反向函数关联 64TAG_LIST(FLAG_Operater) 65 66intmain(intargc,char*argv[]){ 67 68setRun(); 69setAlarm(); 70 71if(getAlarm()==true) 72{ 73printf("set "); 74} 75else 76{ 77printf("clr "); 78} 79 80return0; 81}

如果以前有过类似代码处理的朋友,应该看这段代码还是比较轻松的吧,如果有点生疏,可以一层一层展开了解。

其主要的功能是,通过宏替换和代码拼接符号,自动的生成通用的代码片段。这样做的好处是,不再需要我们在代码中定义一大堆setflag、clrflag、getflag等函数。

通过上面的代码当我们向TAGLIST宏中添加一个标识符,即可生成一系列相关的操作函数等。

这样一方面可以及简化代码,同时也能避免一些人工编码带来的错误。

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73151
  • C程序
    +关注

    关注

    4

    文章

    255

    浏览量

    37424

原文标题:教你3种管理C程序中标志位的方法

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    CW32L010使能读保护后标志不正确怎么解决?

    CW32L010使能读保护后标志不正确
    发表于 11-20 07:44

    软通动力中标卓望公司技术服务框架采购项目

    近日,软通动力成功中标卓望信息技术(北京)有限公司(以下简称“卓望公司”)2025—2027年技术服务框架采购项目,中标份额排名第一。本次中标不仅彰显了软通动力在技术服务领域的领先实力,也标志
    的头像 发表于 09-06 10:28 948次阅读

    龙芯中科助力得力打印机中标中央国家机关集采项目

    近日,中央政府采购网发布“中央国家机关2025年打印机批量集中采购项目-7月”中标公告。得力集团凭借搭载龙芯2P0500的打印机产品DP31DNL,以近3000台的中标量勇夺第一包,超过包2、包3及包4中标量总和,规模创历次集采
    的头像 发表于 07-30 14:23 1439次阅读

    手机充电头RCM标志是什么认证

    RCM(RegulatoryComplianceMark)标志是澳大利亚和新西兰市场对电气产品、电信设备和无线设备进行强制合规管理的统一认证标识。对于手机充电头(充电器)这类产品,RCM标志的意义
    的头像 发表于 07-21 17:33 893次阅读
    手机充电头RCM<b class='flag-5'>标志</b>是什么认证

    USB缓冲区中的内容满了之后,是否有标志进行反馈?

    USB缓冲区中的内容满了之后,是否有标志进行反馈。
    发表于 07-17 07:13

    软通动力中标浙能财务数据中台深化应用项目

    软通动力成功中标“浙江省能源集团财务有限责任公司(以下简称浙能财务)数据中台深化应用项目”。此次中标不仅标志着软通动力在数字金融领域的技术实力再获行业认可,更以数据中台深化应用为切入点,正式开启双方在资金
    的头像 发表于 07-04 18:17 881次阅读

    软通动力中标湖北银行2025年财资管理系统采购项目

    软通动力凭借在财资管理领域的深厚积累与创新实力,成功中标湖北银行2025年财资管理系统采购项目,正式成为湖北银行数字化转型战略合作伙伴。
    的头像 发表于 05-22 16:09 676次阅读

    请问如何处理GPIF DMA标志延迟和“重复计数”值?

    我正在开发一个 UVC 应用程序,它使用 32 总线 GPIF 状态机来管理从 FPGA 向 USB 主机发送数据。 我们目前已将其设置为 FPGA 将向 FX3 写入与精确缓冲区大小相等的字节数
    发表于 05-20 07:15

    芯盾时代中标某芯片公司统一身份管理平台建设

    芯盾时代中标某芯片公司,为其建设统一身份管理平台,完善安全管理标准规范体系,实现用户身份集中统一的全生命周期管理,有效提升公司的整体信息安全水平。
    的头像 发表于 05-13 18:16 820次阅读

    芯盾时代中标易事特集团统一身份认证管理项目

    芯盾时代中标易事特集团统一身份认证管理项目,助力集团在信息化数字化管理领域再迈关键一步。芯盾时代基于零信任安全理念,为客户建设统一化、标准化、自动化的身份管理体系,提升IT
    的头像 发表于 05-09 11:08 1013次阅读

    串口数据错乱?从标志设置入手

    不对,而且还存在帧数据错乱的情况。经排查,是程序没用设置ISIG标志设置引起的。本节以此为切入点进行展开,对串口设置的一些标志进行简单说
    的头像 发表于 02-11 11:35 1376次阅读
    串口数据错乱?从<b class='flag-5'>标志</b><b class='flag-5'>位</b>设置入手

    串口中断需要清除标志吗,串口中断标志会自动清除吗

    在电子通信领域,串口中断作为一种重要的通信机制,广泛应用于各种嵌入式系统和计算机设备中。串口中断标志管理,尤其是是否需要手动清除以及是否会自动清除,是理解和实现串口通信的关键环节。
    的头像 发表于 01-29 14:59 2934次阅读

    软通动力中标亦庄控股司库管理系统建设项目

    近日,软通动力成功中标北京亦庄投资控股有限公司(以下简称:亦庄控股)司库管理系统建设项目,正式成为亦庄控股司库管理系统建设的合作伙伴。双方将在国资发财评规〔2022〕1号文件的指导下,携手探索具有亦庄控股特色的司库体系建设道路,
    的头像 发表于 01-16 10:56 805次阅读

    旷视中标北京市大数据中心感知管理服务平台二期建设项目

    近日,旷视成功中标北京市大数据中心感知管理服务平台(二期)建设项目,此次中标不仅是对旷视技术实力和服务能力的认可,更标志着旷视在智慧城市建设领域又迈出了坚实的一步。
    的头像 发表于 12-31 09:20 1178次阅读

    软通动力中标西电集团财务有限责任公司数据治理项目

    近日,软通动力成功中标西电集团财务有限责任公司(以下简称“西电财务公司”)数据治理管理系统和1104信息系统建设项目,这标志着数据治理方案在西北地区集团财务公司领域的新突破,将进一步夯实客户数据基础,健全财务公司数据治理体系,完
    的头像 发表于 12-18 11:46 1002次阅读