嵌入式中,与外设打交道较多,其实大部分的设置是直接操作寄存器的,而寄存器又被当成一个内存地址来使用。每个寄存器有不同的字段,表示不同的含义。常常使用的方法有移位和位域。我一般常用的移位,这是当年搞AVR单片机时留下的纪念,我也自认为移位方式十分好用。另外的位域,其实我没实际使用过。

本文就虚拟一个寄存器(其实是一个变量而已)及其字段,当然,仅具有演示意义,不代表实际的场合。

使用位操作时,就是通过左移、右移来组装不同字段的数据,在移位时一定要记得使用掩码,否则数据有可能会错乱。见代码的test_1函数示例。

使用位域时,就是设置好各个字段的位域,然后一一赋值,再利用联合体的特性来对寄存器赋值,位域最好用联合体,方便很多。见代码的test_2函数示例。

两种方法各有优点,看个人取舍吧。我是偏向使用移位的方式。

#include <stdio.h>/*
测试结果:
struct test
register_value: 0x0000fead
enable: 1 type: 6 id: a value: fe
union test
register_value: 0x0000fead
enable: 0 type: 6 id: a value: fe*/
/**
虚拟的寄存器,各字段:0: enable
1~3: type
4~7: id
8~15:value
16~31: reserve
*/unsigned int register_value = 0;// 结构体式
typedef struct {unsigned int enable;unsigned int type;unsigned int id;unsigned int value;
}DEV_IO_ARG;int test_1(void)
{DEV_IO_ARG io_arg_tmp;DEV_IO_ARG *io_arg = &io_arg_tmp;// 组装io_arg->enable = 0x1;io_arg->type = 0x6;io_arg->id = 0xa;io_arg->value = 0xfe;register_value = (io_arg->value << 8) | (io_arg->id << 4) | (io_arg->type << 1) | (io_arg->enable << 0);printf("register_value: 0x%08x\n", register_value);// 分解io_arg->enable = (register_value >> 0) & 0x01;io_arg->type = (register_value >> 1) & 0x07;io_arg->id = (register_value >> 4) & 0x0f;io_arg->value = (register_value >> 8) & 0xff;printf("enable: %x type: %x id: %x value: %x\n", io_arg->enable,io_arg->type,io_arg->id,io_arg->value);
}// 联合体式
typedef struct {unsigned int enable: 1;unsigned int type: 3;unsigned int id: 4;unsigned int value: 8;unsigned int reserve: 16;
}DEV_IO_ARG_1;typedef union {unsigned int tmp;DEV_IO_ARG_1 arg;
}DEV_IO_ARG_UNION;void test_2(void)
{DEV_IO_ARG_UNION io_arg_tmp = {0};io_arg_tmp.arg.enable = 1;io_arg_tmp.arg.type = 0x6;io_arg_tmp.arg.id = 0xa;io_arg_tmp.arg.value = 0xfe;register_value = 0;register_value = io_arg_tmp.tmp;printf("register_value: 0x%08x\n", register_value);// 前面enable为1,这里减去1,理论上enable应该为0。io_arg_tmp.tmp = register_value - 1; printf("enable: %x type: %x id: %x value: %x\n", io_arg_tmp.arg.enable,io_arg_tmp.arg.type,io_arg_tmp.arg.id,io_arg_tmp.arg.value);
}int main(void)
{printf("struct test\n");test_1();printf("union test\n");test_2();
}

注:本文内容简单,起因也很简单,公司某部门某些人员可能没搞过嵌入式,没见过位域的用法,但又要搞那一堆代码,不懂了,就问我们部门的人。该同事(和我十分好的那种)和我聊了,于是就有此文。有时想想,想不明白凭什么别人不懂的问题就可以找我们,我们不懂的问题就要自己查。

李迟记于2014年6月7日

寄存器位域、位操作等示例相关推荐

  1. STM32F103ZET6 点灯的三种操作方式(库函数、寄存器、位操作)

    LED硬件连接: 点灯的基本步骤: 库函数版本 重要函数: main.c部分: #include "stm32f10x.h" #include "LED.h" ...

  2. 入门51单片机(STC8952RC)定时器、有关中断原理简述、寄存器设置与程序示例(包括流水灯和计时器)

    目录 1.单片机之定时器 1.1 STC89C52RC定时器模式1工作流程 1.1.1 计数部分 1.1.2 时钟部分 1.1.3 中断部分 1.2 定时器T0.T1相关寄存器 1.2.1 TCOM寄 ...

  3. C语言对寄存器的位操作

    C语言位操作 1.位操作符 (1)位与& 逻辑与&& 1&1=1 1&0=0 0&0=0 0&1=0 (2)位或 | 逻辑或 || 1 | 1= ...

  4. STM32单片机修改寄存器的位操作方法(全网最全)

    使用 C语言对寄存器赋值时,我们常常要求只修改该寄存器的某几位的值,且其它的寄存器位不变,这个时候我们就需要用到 C 语言的位操作方法了. 1. 把变量的某位清零 此处我们以变量 a代表寄存器,并假设 ...

  5. 单片机寄存器的位操作

    1.连续多位需要操作 假如需要将B16的D8~D10位改为0001,但是更改D8~D10位时又不能改变其它位状态:所以需要先将D8~D10位 清0,再改为0001 PORTB->PCR[16] ...

  6. 把变量赋值给寄存器_用C语言对DSP的寄存器进行操作?

    欢迎FPGA工程师加入官方微信技术群 在嵌入式软件的开发过程中,我们常用的语言主要是:汇编语言和C语言.相比较于汇编语言,C语言对我们来说,更贴近我们的一些语言习惯.在DSP的开发过程中,我们主要还是 ...

  7. LiteOS内核源码分析:位操作模块

    摘要:本文带领大家一起剖析了LiteOS位操作模块的源代码,代码非常简单,参考官方示例程序代码,实际编译运行一下,加深理解. 本文分享自华为云社区<LiteOS内核源码分析系列五 LiteOS内 ...

  8. ARMv8 Cortex-a 编程向导手册学习_2.ARMv8-A 寄存器

    /* TODO 本系列文章是对 ARMv8 Cortex-a 系列编程向导手册拙劣的翻译和注解,若有出入,以官方文档为准 */ Chapter 4 ARMv8 寄存器 AArch64 执行状态提供了 ...

  9. ccs中c语言定义布尔常量,CCS中寄存器定义方法

    <TMS 320 F28x源码解读>第1章DSP F28x 使用入门,通过位域结构体的方法为F28x 提供了一个完整的头文件体系,并且针对F28x 的外围设备给出了20 个外设示例,这是D ...

最新文章

  1. java jquery的定义方法_jQuery--基本语法
  2. oracle数据类型查询,Oracle 空间查询, 数据类型为 sdo_geometry
  3. 20189211 《网络攻防》第五周作业
  4. mysql数据库内置函数大全_MySQL数据库——内置函数
  5. ES-Hadoop学习之ES和HDFS数据交换
  6. 2020年我对大前端的认知,前端开发有哪些变化
  7. ssm项目之Bookstrap创建页面并分页查询
  8. java编程手册_java编程手册下载
  9. 如何Python写一个安卓APP
  10. cron在线生成表达式
  11. origin指数拟合
  12. ubuntu 64位下载 处理器为Intel
  13. 拔丝芋头的Java学习日记--Day6
  14. 从钉钉后台对接考勤打卡信息(仅供参考)
  15. 物联卡套餐该如何选择
  16. 怎样轻松搞定图片转ico?
  17. uniapp(H5) + signalr 制作的简单的卡牌游戏
  18. WebP 文件及其编码解码工具(WebPconv)
  19. 快速幂+矩阵快速幂(总结+例题)
  20. 2020安徽省大学生程序设计大赛题解——K 农夫打狼

热门文章

  1. 宁德时代:拟70亿投建储能电池项目
  2. 谷歌Pixel 6系列正式发布:搭载自研Tensor SoC 规格超骁龙888
  3. 超60万人抢购!魅族这波营销火了
  4. “韩国泡菜源于中国”说引韩国教授抗议,要求修改词条,百度百科回应...
  5. 苹果iPad Pro将转向OLED屏幕 首款明年下半年推出
  6. 腾讯音乐Q3财报多点开花,属于数字音乐时代的新浪潮已至
  7. 特斯拉召回部分进口Model S、Model X电动汽车
  8. 阿里巴巴发布第四财季财报 菜鸟驿站包裹量增长100%
  9. 骁龙865+65W闪充!realme 真我X50 Pro 5G正式全球发布
  10. 网易有道词典2019年度十大热词:Vlog、PUA等上榜