当前位置: 首页 > news >正文

C语言数据结构笔记3:Union联合体+结构体取8位Bool量 - 指南

本文衔接上文要求,新增8位bool量的获取方式。

目录

问题提出:

Union联合体+struct结构体(方式1):

Union联合体+struct结构体(方式2):

BYTE方式读取:


问题提出:

STM32单片机的编程中,无法定义Bool或者bit类型

但有时候,比如modbus通信时,需要把bool量八个八个地组合读取,少于8个的部分填充0

Union联合体+struct结构体(方式1):

这里是考虑到超过8位的使用场景,因此定义了超过3字节的定义方式

这种方式适合那种喜欢一个一个列出所有寄存器位名称的情况。

#define BITS_PER_BYTE 8#define BYTES_FOR_BITS 3  // // 定义3字节的位字段结构typedef union {    uint8_t bytes[BYTES_FOR_BITS];  // 整个字节数组访问    struct {        // 每个字节单独定义位字段        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } byte0;        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } byte1;        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } byte2;    } bits;} LargeBitField;
#include  typedef unsigned char uint8_t;typedef unsigned short int    uint16_t;typedef signed short int      int16_t; #pragma pack(push, 1) //:将结构体的对齐方式设置为 1 字节,并将当前对齐设置保存到堆栈中。 //0x03e8 - 0x03eetypedef struct  ABC_regs1{    uint16_t  A1;    uint16_t  B1;    int16_t   C1;    int16_t   D1;    uint16_t  E1;    int16_t   F1;    int16_t   G1;}ABC_regs_1; //0x177B - 0x1781typedef struct  ABC_regs2{    uint16_t  A2;    uint16_t  B2;    int16_t   C2;    int16_t   D2;    uint16_t  E2;    int16_t   F2;    int16_t   G2;}ABC_regs_2; #define BITS_PER_BYTE 8#define BYTES_FOR_BITS 3  // // 定义15字节的位字段结构typedef union {    uint8_t bytes[BYTES_FOR_BITS];  // 整个字节数组访问    struct {        // 每个字节单独定义位字段        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } byte0;        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } byte1;        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } byte2;    } bits;} LargeBitField;  typedef struct  Letter_regs{    ABC_regs_1 ABC1;  //0x03e8 - 0x03f1 //7成员 14字节 //偏移量 0x00- 0x0c    ABC_regs_2 ABC2;  //0x177B - 0x1781 //7成员 14字节     //BOOL_1     Bool1; //    LargeBitField Bytes;}letter_regs;   int main(void){    letter_regs reg;      // 设置位    reg.Bytes.bits.byte0.b0 = 1;  // 设置byte0的第0位为1    reg.Bytes.bits.byte1.b7 = 1;  // 设置byte1的第7位为1     // 读取位    uint8_t bit0 = reg.Bytes.bits.byte0.b0;    uint8_t bit7 = reg.Bytes.bits.byte1.b7;     printf("Bit 0 of byte0: %d\n", bit0);    printf("Bit 7 of byte1: %d\n", bit7);     // 通过字节数组访问    reg.Bytes.bytes[0] = 0x0F;  // 设置byte0为0x0F    printf("Byte 0: 0x%02X\n", reg.Bytes.bytes[0]);  }

Union联合体+struct结构体(方式2):

这种方式不一个一个列出寄存器名称,直接通过地址偏移操作:

#include  typedef unsigned char uint8_t;typedef unsigned short int    uint16_t;typedef signed short int      int16_t; #pragma pack(push, 1) //:将结构体的对齐方式设置为 1 字节,并将当前对齐设置保存到堆栈中。 //0x03e8 - 0x03eetypedef struct  ABC_regs1{    uint16_t  A1;    uint16_t  B1;    int16_t   C1;    int16_t   D1;    uint16_t  E1;    int16_t   F1;    int16_t   G1;}ABC_regs_1; //0x177B - 0x1781typedef struct  ABC_regs2{    uint16_t  A2;    uint16_t  B2;    int16_t   C2;    int16_t   D2;    uint16_t  E2;    int16_t   F2;    int16_t   G2;}ABC_regs_2; // 定义字节的位字段结构typedef union {    uint8_t byte;  // 整个字节数组访问        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } bits;}BitField;  typedef struct  Letter_regs{    ABC_regs_1 ABC1;  //0x03e8 - 0x03f1 //7成员 14字节 //偏移量 0x00- 0x0c    ABC_regs_2 ABC2;  //0x177B - 0x1781 //7成员 14字节     BitField Bytes[10];}letter_regs;   int main(void){    letter_regs reg;    // 通过直接赋值给联合体的字节    reg.Bytes[0].byte = 0xA5;  // 0xA5 in hex is 10100101 in binary     // 通过位域赋值    reg.Bytes[1].bits.b0 = 1;  // Set bit 0 to 1    reg.Bytes[1].bits.b7 = 1;  // Set bit 7 to 1     // 读取并打印结果    printf("Byte 0: 0x%02X\n", reg.Bytes[0].byte);  // 输出 0xA5    printf("Byte 1: 0x%02X\n", reg.Bytes[1].byte);  // 输出 0x81 (因为 b7 和 b0 被设置为1) }

BYTE方式读取:

#include  typedef unsigned char uint8_t;typedef unsigned short int    uint16_t;typedef signed short int      int16_t;#pragma pack(push, 1) //:将结构体的对齐方式设置为 1 字节,并将当前对齐设置保存到堆栈中。 //0x03e8 - 0x03eetypedef struct  ABC_regs1{    uint16_t  A1;    uint16_t  B1;    int16_t   C1;    int16_t   D1;    uint16_t  E1;    int16_t   F1;    int16_t   G1;}ABC_regs_1; //0x177B - 0x1781typedef struct  ABC_regs2{    uint16_t  A2;    uint16_t  B2;    int16_t   C2;    int16_t   D2;    uint16_t  E2;    int16_t   F2;    int16_t   G2;}ABC_regs_2; // 定义字节的位字段结构typedef union {    uint8_t byte;  // 整个字节数组访问        struct {            uint8_t b0 : 1;            uint8_t b1 : 1;            uint8_t b2 : 1;            uint8_t b3 : 1;            uint8_t b4 : 1;            uint8_t b5 : 1;            uint8_t b6 : 1;            uint8_t b7 : 1;        } bits;}BitField; typedef struct  Letter_regs{    ABC_regs_1 ABC1;  //0x03e8 - 0x03f1 //7成员 14字节    ABC_regs_2 ABC2;  //0x177B - 0x1781 //7成员 14字节     BitField Bytes[10]; //0x0400 - 0x0450 //80 成员 }letter_regs; int main(void){    letter_regs reg;    // 通过直接赋值给联合体的字节    reg.Bytes[0].byte = 0xAA;  // 0xA5 in hex is 10100101 in binary     reg.Bytes[8].byte = 0x6A;  // 0xA5 in hex is 10100101 in binary    unsigned char* ptr = (unsigned char*)®.Bytes;     //print_struct_values(®);      //联合体读8个,实际物理地址才偏移1,相对于基地址地偏移量,都一个BYTE才偏移1     for (int j = 0; j < 10; j++) //读10个BYTE 整个联合体    {        unsigned char offset = j; // 计算偏移量        uint8_t value = *(const uint8_t*)(ptr + offset);         printf("Byte %d: 0x%02X\n",j,value);    }}

http://www.jsqmd.com/news/10356/

相关文章:

  • 多机器人协同首现基础模型技术突破
  • PHP 图像处理实战 GD/Imagick 从入门到精通,构建高性能图像服务
  • 2025氧化镁厂家、活性氧化镁厂家、肥料级氧化镁厂家最新推荐榜:实力生产与优质供应之选
  • 2025学校家具定制厂家/书包柜厂家推荐榜:专业设计与安全品质首选
  • 2025农机带厂家最新推荐榜:质量可靠与耐用性能兼备之选
  • 2025深圳电源适配器厂家最新推荐榜:高效耐用与安全认证深度解析
  • 2025试验机厂家最新推荐榜:精准测量与高效检测口碑之选
  • 2025喷砂厂家 / 热喷锌厂家 / 热喷铝厂家 / 油漆涂装厂家 / 热喷耐磨材料厂家 / 防腐工程厂家最新推荐榜:高效作业与优质工艺口碑之选
  • 2025上海经济纠纷律师/民事纠纷律所最新推荐榜:专业辩护与胜诉保障口碑之选
  • Semantic Kernel + AutoGen = 开源 Microsoft Agent Framework
  • 读技术之外:社会联结中的人工智能04数据
  • Potplayer Official Download LINK
  • 二廿计划(25.10.09 - 25.10.29)
  • 生成式AI与计算教育融合研究
  • 博科SAN switch 所有端口的led闪橙色
  • Spec Kit 终结AI瞎写代码
  • 2025年R系列斜齿轮减速机厂家最新推荐:R系列斜齿轮减速机/F系列平行轴齿轮减速机/K系列螺旋斜齿轮减速机/S系列蜗轮减速机实力厂家精准传动解决方案
  • 2025化工泵厂家权威推荐榜:磁力泵/多级泵/高温泵/混流泵/浆液泵/螺杆泵/陶瓷泵/脱硫泵/旋涡泵/液下泵/轴流泵/自吸泵厂家,高效节能与耐用品质实力之选
  • C语言 strtol() 函数用法
  • 课程作业
  • 国庆七日赛训总结
  • task2.c
  • SpringCloud实用篇02-(Nacos配置管理,Feign远程调用,Gateway服务网关) - a
  • 总资料汇总关联化站点形式的尝试(未完成)
  • 8051指令集
  • reLeetCode 热题 100- 76 最小覆盖串 - MKT
  • SpringCloud-01(认识微服务,服务拆分和远程调用,Eureak注册中心,Ribbon负载均衡,Nacos注册中心) - a
  • 算法第一次作业
  • C++_高阶
  • 使用Quarkus构建首个Keycloak MCP服务器实战指南