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 <stdio.h>typedef unsigned char uint8_t;
typedef unsigned short int    uint16_t;
typedef signed short int      int16_t;#pragma pack(push, 1) //:將結構體的對齊方式設置為 1 字節,并將當前對齊設置保存到堆棧中。//0x03e8 - 0x03ee
typedef 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 - 0x1781
typedef 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- 0x0cABC_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位為1reg.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為0x0Fprintf("Byte 0: 0x%02X\n", reg.Bytes.bytes[0]);}

Union聯合體+struct結構體(方式2):

這種方式不一個一個列出寄存器名稱,直接通過地址偏移操作:

#include <stdio.h>typedef unsigned char uint8_t;
typedef unsigned short int    uint16_t;
typedef signed short int      int16_t;#pragma pack(push, 1) //:將結構體的對齊方式設置為 1 字節,并將當前對齊設置保存到堆棧中。//0x03e8 - 0x03ee
typedef 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 - 0x1781
typedef 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- 0x0cABC_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 1reg.Bytes[1].bits.b7 = 1;  // Set bit 7 to 1// 讀取并打印結果printf("Byte 0: 0x%02X\n", reg.Bytes[0].byte);  // 輸出 0xA5printf("Byte 1: 0x%02X\n", reg.Bytes[1].byte);  // 輸出 0x81 (因為 b7 和 b0 被設置為1)}

BYTE方式讀取:

#include <stdio.h>typedef unsigned char uint8_t;
typedef unsigned short int    uint16_t;
typedef signed short int      int16_t;
#pragma pack(push, 1) //:將結構體的對齊方式設置為 1 字節,并將當前對齊設置保存到堆棧中。//0x03e8 - 0x03ee
typedef 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 - 0x1781
typedef 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 binaryreg.Bytes[8].byte = 0x6A;  // 0xA5 in hex is 10100101 in binaryunsigned char* ptr = (unsigned char*)&reg.Bytes;//print_struct_values(&reg);//聯合體讀8個,實際物理地址才偏移1,相對于基地址地偏移量,都一個BYTE才偏移1for (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.pswp.cn/web/82794.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82794.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82794.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

三種讀寫傳統xls格式文件開源庫libxls、xlslib、BasicExcel的比較

最近準備讀寫傳統xls格式文件&#xff0c;而不是較新的xlsx&#xff0c;詢問DeepSeek有哪些開源庫&#xff0c;他給出了如下的簡介和建議&#xff0c;還給出了相應鏈接&#xff0c;不過有的鏈接已失效。最后還不忘提醒&#xff0c;現在該用xlsx格式了。 以下是幾個可以處理傳統…

從測試角度看待CI/CD,敏捷開發

什么是敏捷開發&#xff1f; 是在高強度反饋的情況下&#xff0c;短周期&#xff0c;不斷的迭代產品&#xff0c;滿足用戶需求&#xff0c;搶占更多的市場 敏捷開發是什么&#xff1f; 是一種產品快速迭代的情況下&#xff0c;降低出錯的概率&#xff0c;具體會落實到公司的…

figma MCP + cursor如何將設計稿生成前端頁面

一、準備工作 figma MCP需要通過figma key來獲取設計稿權限&#xff0c;key的生成步驟如下 1. 打開figma網頁版/APP&#xff0c;進入賬戶設定 2. 點擊生成token 3. 填寫內容生成token(一定要確認復制了&#xff0c;不然關閉彈窗后就不會顯示了) 二、配置MCP 4. 進入到cursor…

git互聯GitHub 使用教程

一、下載git Git 公司 右鍵 git config --global user.name "name" git config --global user.email "email" ssh-keygen -t rsa -C email &#xff1a;生成的ssh密鑰需要到github 網站中保存ssh 二、GitHub新建repository 三、本地git互聯GitHub 找…

“輕量應用服務器” vs. “云服務器CVM”:小白入門騰訊云,哪款“云機”更適合你?(場景、配置、價格對比解析)

更多云服務器知識&#xff0c;盡在hostol.com 當你第一次踏入騰訊云這個“數字百貨大樓”&#xff0c;面對琳瑯滿目的“云產品”&#xff0c;是不是有點眼花繚亂&#xff0c;特別是看到“輕量應用服務器”和“云服務器CVM”這兩位都號稱能幫你“安家落戶”的“云主機”時&…

MongoDB學習和應用(高效的非關系型數據庫)

一丶 MongoDB簡介 對于社交類軟件的功能&#xff0c;我們需要對它的功能特點進行分析&#xff1a; 數據量會隨著用戶數增大而增大讀多寫少價值較低非好友看不到其動態信息地理位置的查詢… 針對以上特點進行分析各大存儲工具&#xff1a; mysql&#xff1a;關系型數據庫&am…

Qt學習及使用_第1部分_認識Qt---Qt簡介

前言 學以致用,通過QT框架的學習,一邊實踐,一邊探索編程的方方面面. 參考書:<Qt 6 C開發指南>(以下稱"本書") 標識說明:概念用粗體傾斜.重點內容用(加粗黑體)---重點內容(紅字)---重點內容(加粗紅字), 本書原話內容用深藍色標識,比較重要的內容用加粗傾斜下劃線…

Python語法基礎篇(包含類型轉換、拷貝、可變對象/不可變對象,函數,拆包,異常,模塊,閉包,裝飾器)

Python語法基礎篇&#xff08;二&#xff09; 類型轉換拷貝可變對象與不可變對象可變對象不可變對象 函數拆包異常模塊閉包裝飾器 &#x1f439;&#x1f439;&#x1f439;&#x1f439;&#x1f439;一只正在努力學習計算機技術的小倉鼠&#xff0c;尾部有課程鏈接哦~&#x…

錄制mp4

目錄 單線程保存mp4 多線程保存mp4 rtsp ffmpeg錄制mp4 單線程保存mp4 import cv2 import imageiocv2.namedWindow(photo, 0) # 0窗口大小可以任意拖動&#xff0c;1自適應 cv2.resizeWindow(photo, 1280, 720) url "rtsp://admin:aa123456192.168.1.64/h264/ch1/main…

ISBN書號查詢接口如何用PHP實現調用?

一、什么是ISBN書號查詢接口 ISBN數據查詢接口是一項圖書信息查詢服務。它基于全球通用的ISBN編碼系統&#xff0c;幫助用戶快速獲取圖書的詳細信息&#xff0c;包括書名、作者、出版社、出版時間、價格、封面等關鍵字段。 該接口廣泛應用于電商平臺、圖書館管理系統、二手書…

Redis底層數據結構之深入理解跳表(2)

上一篇文章中我們詳細講述了跳表的增添、查找和修改的操作&#xff0c;這篇文章我們來講解一下跳表在多線程并發時的安全問題。在Redis中&#xff0c;除了網絡IO部分和大文件的后臺復制涉及到多線程外&#xff0c;其余任務執行時全部都是單線程&#xff0c;這也就意味著在Redis…

Go語言依賴管理與版本控制-《Go語言實戰指南》

在現代軟件開發中&#xff0c;項目的第三方依賴和版本控制扮演著至關重要的角色。Go 語言自 Go 1.11 引入 Modules&#xff08;模塊化管理&#xff09;以來&#xff0c;已經實現了內建的依賴管理機制&#xff0c;徹底擺脫了傳統 GOPATH 模式的限制。 本章將深入探討如何使用 Go…

Appium+python自動化(十一)- 元素定位- 下

1、 List定位 List顧名思義就是一個列表&#xff0c;在python里面也有list這一個說法&#xff0c;如果你不是很理解什么是list&#xff0c;這里暫且理解為一個數組或者說一個集合。首先一個list是一個集合&#xff0c;那么他的個數也就成了不確定性&#xff0c;所以這里需要用復…

stress 服務器壓力測試的工具學習

一、stress 工具介紹 tress 是一種工具&#xff0c;可以對符合 POSIX 標準的操作系統施加可配置數量的 CPU、內存、I/O 或磁盤壓力&#xff0c;并報告其檢測到的任何錯誤。 stress 不是一個基準測試。它是由系統管理員用來評估其系統擴展性的工具&#xff0c;由內核程序員用來…

不止抓請求:5種開發場景中的抓包組合策略(含 Charles 等工具)

很多開發者用抓包&#xff0c;只在“接口調不通”的時候。 但在復雜項目中&#xff0c;抓包早已不僅是調錯工具&#xff0c;更是開發節奏提速器、協作問題解耦器、架構瓶頸探測器。 關鍵在于——不同場景下&#xff0c;你要用對方法、配對工具。 以下是我根據日常開發實戰&a…

藍橋杯3498 01串的熵

問題描述 對于一個長度為 23333333的 01 串, 如果其信息熵為 11625907.5798&#xff0c; 且 0 出現次數比 1 少, 那么這個 01 串中 0 出現了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚舉 0 出現的次數//因…

計算機系統大作業——程序人生

計算機系統 大作業 題 目 程序人生-Hello’s P2P 專 業 物聯網工程 學   號 2022112820 班 級 2237301 學 生 孟宇航 指 導 教 師 吳 銳 計算機科學與技術學院 2024年…

〈軟件安裝管家軟件目錄〉?Windows系統版

①裝機常用 ?壓縮解壓WinRAR7-ZIPBandZip360壓縮?文件工具EverythingOneCommander XYplorer ReNamer ?卸載軟件CCleanerIObitUninstallerUninstall toolGeekAutodesk卸載Adobe卸載Ashampoo?驅動軟件驅動人生&#xff08;離線版&#xff09;驅動精靈&#xff08;離線版&…

CentOS Stream 8 Unit network.service not found

一、問題現象 在 CentOS Stream 8 操作系統中&#xff0c;配置完靜態IP 信息&#xff0c;想重啟網絡服務。 執行如下命令&#xff1a; systemctl restart network 提示信息如下&#xff1a; Failed to restart network.service: Unit network.service not found. 二、問題…

極空間z4pro配置gitea mysql,內網穿透

極空間z4pro配置gitea mysql等記錄&#xff0c;內網穿透 1、mysql、gitea鏡像下載&#xff0c;極空間不成功&#xff0c;先用自己電腦科學后下載鏡像,拉取代碼&#xff1a; docker pull --platform linux/amd64 gitea/gitea:1.23 docker pull --platform linux/amd64 mysql:5.…