Skip to main content

Command Palette

Search for a command to run...

Struct and Union

Published
•3 min read•View as Markdown

Chắc chắn rồi! Dưới đây là bảng so sánh chi tiết giữa struct và union trong lập trình nhúng (embedded C), rất quan trọng khi làm việc với các bản đồ thanh ghi, giao tiếp ngoại vi, truy cập bit và tối ưu bộ nhớ.


🧠 1. Định nghĩa

Đặc điểmstructunion
Khái niệmTập hợp các biến (gọi là thành viên) được gom lại dưới một tên chung. Các thành viên có bộ nhớ riêng.Tập hợp các biến nhưng dùng chung vùng nhớ, tức là chỉ một thành viên có giá trị tại một thời điểm.
Cú phápstruct MyStruct { int a; char b; };union MyUnion { int a; char b; };

🗂 2. Cách sử dụng bộ nhớ

🔸 struct

  • Mỗi trường (field) được lưu ở một vị trí bộ nhớ riêng biệt.

  • Tổng kích thước = tổng các kích thước thành viên (có thể thêm padding).

  • Ví dụ:

struct MyStruct {
    int a;     // 4 bytes
    char b;    // 1 byte (+3 byte padding để giữ alignment)
    float c;   // 4 bytes
};
// Tổng kích thước: 12 bytes (hoặc 8/16 tùy kiến trúc và alignment)

🔹 union

  • Tất cả thành viên dùng chung 1 vùng nhớ, kích thước của union là kích thước của thành viên lớn nhất.

  • Ghi vào một trường sẽ ghi đè giá trị trường khác.

union MyUnion {
    int a;     // 4 bytes
    char b;    // 1 byte
    float c;   // 4 bytes
};
// Tổng kích thước: 4 bytes

🧰 3. Ứng dụng trong lập trình nhúng

Lĩnh vựcstructunion
Mapping thanh ghi (register)✅ Dùng để biểu diễn layout chi tiết của thanh ghi (gồm nhiều bit/field)✅ Dùng khi cần truy cập nhiều kiểu dữ liệu hoặc nhiều cách biểu diễn cùng 1 vùng nhớ
Truy cập bit cụ thể (bit-field)✅ Phối hợp với bit-field để định nghĩa từng bit trong thanh ghi✅ Phối hợp với struct để vừa truy cập toàn thanh ghi, vừa truy cập từng bit
Giao tiếp truyền dữ liệu (I2C/SPI/UART)✅ Dùng để đóng gói khung dữ liệu (packet)✅ Dùng khi cần ánh xạ cùng 1 vùng dữ liệu vào nhiều dạng khác nhau
Tối ưu RAM/Flash❌ Không hiệu quả vì mỗi field chiếm chỗ riêng✅ Rất hữu ích khi làm việc với RAM hạn chế
Protocol decoding (CAN, Modbus, BLE...)✅ Định nghĩa khung dữ liệu chi tiết✅ Truy cập dạng raw byte hoặc dạng struct tùy lúc

🧪 4. Ví dụ thực tế

union kết hợp struct để map thanh ghi:

typedef union {
    uint32_t ALL;  // Truy cập toàn bộ thanh ghi 32-bit
    struct {
        uint32_t EN  : 1;  // Bit 0
        uint32_t MODE: 2;  // Bit 1–2
        uint32_t     : 5;  // Padding
        uint32_t DATA: 24; // Bit 8–31
    } BITS;
} REG_CTRL_t;

// Dùng:
REG_CTRL_t reg;
reg.ALL = 0xAABBCCDD;
printf("%d", reg.BITS.MODE);  // Lấy MODE từ bit-field

🧾 5. Tổng kết so sánh

Thuộc tínhstructunion
Các thành viên độc lập✅❌
Chia sẻ vùng nhớ❌✅
Truy cập đồng thời nhiều trường✅⚠️ Không an toàn
Tối ưu bộ nhớ❌✅
Dễ hiểu, trực quan✅⚠️ Dễ gây lỗi nếu dùng sai
Dùng để map dữ liệu kiểu khác nhau❌✅