Những định nghĩa , code mẫu trong bài viết này hoàn toàn có thể dùng được với những trình biên dịch ANSI-C. Đã kiểm tra trên Keil C và Hi-Tech C
Struct và Union được sử dụng rất nhiều trong lập trình C để định nghĩa kiểu dữ liệu người dùng, dễ dàng hơn trong các phép tính tra bảng, định dạng dữ liệu …
Hầu hết các trình biên dịch chuẩn ANSI-C đều có cách khai báo và sử dụng giống nhau. Bài viết này đề cập đến Struct và Union sử dụng cho 8051 và PIC với 2 trình biên dịch là Hi-Tech C và Keil C.
Struct
Một bài toán đơn giản khi tôi muốn truyền một Frame dữ liệu với cấu trúc bao gồm 6 byte:
[CMD:1byte][LEN:1byte][DATA:1byte], vậy muốn định nghĩa cái này một cách đơn giản dễ dùng thì định nghĩa Struct sẽ hiệu quả:
Có thể hiểu ngay cách định nghĩa này, từ khóa struct, đến tên của Struct, sau đó khai báo lần lượt, 1 byte dự trữ cho CMD, với kiểu dữ liệu char, 1 byte dự trữ cho LEN với kiểu dữ liệu char, và 4 byte dự trự cho DATA với kiểu dữ liệu char. Chú ý, phần này chỉ khai báo cho trình biên dịch biết đây là kiểu dữ liệu DataPacket sẽ dùng trong chương trình.
Vậy dùng Struct này thế nào:
1 |
struct DataPacket MyData; |
Khai báo biến MyData có kiểu dữ liệu DataPacket, chú ý là phải có từ khóa struct đằng trước.
Cách sử dụng trong chương trình chính, truy xuất, gán dữ liệu cho MyData
1 |
/* Gán dữ liệu cho MyData */ |
Với kiểu struct này, trình biên dịch sẽ dành ra 6 byte để cấp phát cho MyData theo thứ tự+-------+-------+---------+---------+---------+---------+
| CMD | LEN | DATA[0] | DATA[1] | DATA[2] | DATA[3] |
+-------+-------+---------+---------+---------+---------+
Ngoài ra còn có thể khải báo struct bằng từ khóa typedefVới cách này, từ khóa typedef đặt trước struct, và tên của struct đặt sau block {}, lúc này trình dịch coi DataPacket như một kiểu dữ liệu được định nghĩa giống char, hay intUnion: cũng giống như struct, tuy nhiên, struct khai báo dữ liệu theo chiều dài, nghĩa là khai báo 1 phần từ trong struct sẽ cấp phát đúng bằng số byte mà phần tử đó cần (chẳng hạn ví dụ trên). Trong khi Union khai báo dữ liệu theo chiều dọc, nghĩa là tất cả các phần từ sẽ chỉ định nghĩa cho 1 vùng dữ liệu nào. Hãy xem ví dụ để hình dung thêm.
Yêu cầu ở đây, tôi muốn định nghĩa 2 byte dữ liệu, nhưng tôi muốn truy xuất nó bằng 2 tên.Debug sử dụng Keil C - Code trên hoàn toàn có thể dùng với Hi-Tech C Trình biên dịch cấp phát bộ nhớ cho kiêu Union như sau:+-------+-------+
| BYTE1 | BYTE0 |
+---------------+
| WORD_VAL1 |
+---------------+
| WORD_VAL2 |
+---------------+
Cả WORD_VAL1 và WORD_VAL2 đều trỏ đến cùng 1 địa chỉ RAMGiống như struct, còn một các khác để khai báo unionKết hợp union và struct: Bằng cách kết hợp này, dữ liệu trở nên linh hoạt hơn, ngoài ra, có thể dễ dàng tách hay ghép nhiều Byte lại một cách nhanh chóng. Ví dụ:Sử dụng như sauNgoài ra, kết hợp union và struct còn có thể định nghĩa từng bit cho một thanh ghi (Cả KeilC và Hi-Tech C đều hỗ trợ):Sử dụng:
08 |
y.Nibbles.NibbleLo = 0x05 |
09 |
y.Nibbles.NibbleHi = 0x00 |
Kết quảKết quả Debug trên KeilC, hoàn toàn giống khi Debug dùng MPLAB cho Hi-TechC //=============================================================
0 nhận xét:
Đăng nhận xét