单片机,struct ,union定义标志,节约RAM
单片机的RAM是非常少的,像新唐,STC,合泰等一些国产的51单片机,RAM 512 byte,1k,2k,非常常见,
有时候我们的串口接收一串数据,或AD连续采集,这些数据是不能放到 flash 里的,没办法,只能想法节约一些变量空间了.
标志位很多时候只有两种状态,就像bool型一样,真/假,这样的话,我们可以用下面的方式定义,
typedef union uFLG{
char Flg ; //定义整形数据 联合体成员
struct FLAG{ //位域定义
u8 Flg1 : ;
u8 Flg2 : ;
u8 Flg3 : ;
u8 Flg4 : ;
u8 Flg5 : ;
u8 Flg6 : ;
u8 Flg7 : ;
u8 Flg8 : ;
}tFlg;
}uFlg;
uFlg uF1; //定义联合体变量
定义一个联合体产FLG类型,包含一个char变量和一个结构体,
在RAM中,联合体(union)只占用一个字节,
也就是说char Flg和struct FLAG在单片机的内存中,共用一个字节,改变了FLAG的值,Flg的值也被改变了,这在某些情况下会变得很方便,
Flg1~Flg8都只占用一个bit位,所以它们的值只能是0或1,这用来做标志位是足够了,如果改变了它们的值,相应的,char Flg的值也被改变了,
比如改变了Flg3的值,那么char Flg的第3位也被改了,这是对应的,因为他们共享同一个字节的RMA.
也可以这样定义:
typedef union uFLG{
char Flg ; //定义整形数据 联合体成员
struct FLAG{ //位域定义
u8 Flg1 : ;
u8 Flg2 : ;
u8 Flg3 : ;
}tFlg;
}uFlg;
uFlg ; //定于联合体变量
这个时候,Flg1占8个bit中的1个bit,也就是和char Flg中8个bit(一个字节)的第1个bit共享RAM空间,
对应Flg2占8个bit中的2个bit,也就是和char Flg中8个bit(一个字节)的第2个和第3个bit共享RAM空间,
同样的, 对应Flg3占8个bit中的5个bit,也就是和char Flg中8个bit(一个字节)的第4,5,6,7,8bit共享RAM空间,
改变Flg1,Flg2,Flg3,的值,char Flg的值也会做出相应的改变.
Flg1,Flg2,Flg3这是位域变量名,你可以随意起名,只要不违反编译器的相应规则就可以了.
怎么使用那?
1.先定义一个uFlg(我们在上文自己定义的联合体)变量
uFlg uF1,;
2.给变量赋值
如果我们定义了一个char 变量,应该是这样的:
char p;
p=;
同理:
uF1.tFlg.Flg1 =;
这样,我们就给Flg1赋值了,因为他只占用一个bit,所以只能是1或0,
如果想把Flg1,Flg2,Flg3都赋值为0;
uF1.tFlg.Flg1 =;
uF1.tFlg.Flg2 =;
uF1.tFlg.Flg3 =;
和
uF1.Flg =;
结果是一样的,因为他们共享同一个字节的RAM空间,这样可以一次性清除所有的标志位.
这样写会有些麻烦,必竟名字太长了.可以用#define
#define time_2s uF1.tFlg.Flg1
这样我们直接用time_2s就可以了,不用再写uF1.tFlg.Flg1这么长了.
单片机,struct ,union定义标志,节约RAM的更多相关文章
- 关于C与C++的struct,union,enum用法差异
对着代码说话: #include <stdio.h> #include <stdlib.h> struct test { int abc; }; enum _enum {A,B ...
- enum,struct,union类型使用和长度
VC,C++ Builder和lcc三个编译器 间枚举类型enum长度的情况. 各种C编译器默认的字节对齐数不一致,要写通用的代码,经常就是使用 #pragma pack(1) ... #pragma ...
- 单片机内程序运行的时候ram空间是如何分配的?
转自:http://blog.sina.com.cn/s/blog_a575eb9401014tam.html 单片机内程序运行的时候ram空间是如何分配的?我现对一个程序进行减少片内ram的使用的优 ...
- 51单片机数组的定义方法(code与data的作用)
转自:http://blog.sina.com.cn/s/blog_94994f7b01010s1h.html 数组前不加“code”或“data”,则默认将数组存放在程序存储器中:code 指定数据 ...
- keil 编译器V6 定义函数在ram中运行-和在指定地址定义常量
之前一直是用v5编译,编译速度慢,换成V6编译速度差不多快50% ,而且arm后期只维护v5编译器不在更新v5编译器.切换到V6编译器大势所趋,把之前v5且换到v6需要如下更改: 1. CMSIS包需 ...
- C/C++中struct/union/class内存对齐
struct/union/class内存对齐原则有四个: 1).数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储 ...
- 单片机C语言中标志位的经典应用
/* 本例程是C语言的位域操作示例 这里为什么位域结构体与联合体一起使用? -->因为这样定义后,即可以单独使用标志位 也可同时使用整个字节数据 主要应用:单片机C语言 好处:用标志位可以节省R ...
- C语言的struct/union字节对齐
C语言的一大优势就是对内存空间的控制,当然,一般情况下对于开发人员来说都是透明的.看一个始终困扰初学者的问题:字节对齐! 先看四个重要的基本概念:1.数据类型自身的对齐值:对于char型数据,其自身对 ...
- 【转】单片机中volatile定义的作用详解
传送门:http://www.eeworld.com.cn/mcu/2011/0411/article_3928.html 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译 ...
随机推荐
- Ubuntu双系统安装过程中遇到的问题
1.在第六步选择时区的时候,会报错,这时候可以选择断开网络(取消右上角的网络选项)! 2.用easybcd添加启动项以后,无法进入,F12进入BIOS,选择Ubuntu进入,因为以前的BIOS BOO ...
- python 函数&条件,循环
条件if <条件判断1>: <执行1>elif <条件判断2>: <执行2>elif <条件判断3>: <执行3>else: & ...
- ignore_user_abort函数制定计划任务
PHP中的ignore_user_abort函数是当用户关掉终端后脚本不停止仍然在执行,可以用它来实现计划任务与持续进程,下面会通过实例讨论ignore_user_abort()函数的作用与用法. ...
- Linux 命令行浏览器
真是没有做不到只有想不到! Linux下竟然有命令行式的浏览器:W3m SPC向下翻页 b向上翻页 J 向下滚动一行 K 向上滚动一行 > 右移一屏 < 左移一屏 TAB 转到下个超链接 ...
- 小知识积累-C++使用tinyxml解析Xml内存泄漏问题
项目中需要用到C++解析XML,网上搜到tinyxml这么个开源库,就用了下试试,创建对象后内部自带Clear方法,但在循环测试的时候(刚用C++做项目不久,不会什么特别的内存泄漏测试工具,于是就写个 ...
- IDEA定位开发文件在左边工程中的文件路径
IDEA新公司入职使用第七天,基本快捷键和BUG调试已经搞透了!从最开始的配置到现在的适应确实是一个不小的进步,前几天每天加班太忙没有时间更新博客,明天就是五一假期,现在将刚掌握的一点IDEA技术写出 ...
- 使用js接收ajax解析的json再拼成一个自己想要的json
//ajax解析的json{ "status": 1, "content": { "pathsInfo": [ { "id&quo ...
- 图片左右滚动控件(带倒影)——重写Gallery
转http://blog.csdn.net/ryantang03/article/details/8053643 今天在网上找了些资料,做了一个图片左右滚动的Demo,类似幻灯片播放,同时,图片带倒影 ...
- injection for Xcode10使用方法
对于一个使用Xcode的使用者来说,麻烦的地方在于使用代码布置界面时候的调试,5s改一下代码,用10s查看修改效果,如果电脑配置稍低,时间更长,这是病,得治,哈哈.下面就来说一下injection的使 ...
- 纯 js 让浏览器不缓存 ajax 请求
开发「bufpay.com 个人即时到账收款平台」支付页面需要用到 ajax 轮询订单的支付状态. 现在浏览器对 ajax 的缓存策略遵循 http response header 里面的缓存设置,为 ...