Đổi số thực float, double sang hex và ngược lại, xem bit dấu, mũ, định trị, thứ tự byte khi gửi qua UART hay Modbus, và chuyển đổi fixed-point Q15, Q31.

Số thực float được lưu thế nào?

Theo chuẩn IEEE 754, một số float 32-bit gồm 3 phần:

  • Dấu (1 bit): 0 là dương, 1 là âm.
  • Mũ (8 bit): lưu số mũ cộng thêm 127 (bias).
  • Định trị (23 bit): phần lẻ sau dấu phẩy, ngầm hiểu có số 1 đứng trước.
giá trị = (−1)^dấu × 1.định_trị × 2^(mũ − 127)

Ví dụ 3.14159 được lưu thành 0x40490FD0. Giá trị thật trong bộ nhớ là 3.14159012, lệch một chút vì 23 bit định trị chỉ cho độ chính xác khoảng 7 chữ số thập phân. Cần chính xác hơn thì dùng double (khoảng 15–16 chữ số).

Gửi số float qua UART, Modbus

Khi truyền float theo từng byte, hai bên phải thống nhất thứ tự byte. STM32, ESP32 lưu little-endian (byte thấp trước). Thiết bị Modbus thường chia float thành 2 thanh ghi 16-bit, và mỗi hãng sắp xếp một kiểu (ABCD, CDAB, BADC, DCBA). Bảng “Thứ tự byte” ở trên liệt kê đủ 4 kiểu để bạn so với dữ liệu đọc được.

Trong C, chuyển float sang mảng byte và ngược lại bằng memcpy, không nên ép kiểu con trỏ *(float*)buf vì có thể lỗi căn lề trên Cortex-M0.

Fixed-point Q15, Q31 là gì?

Trên vi điều khiển không có FPU, phép tính float chạy chậm. Fixed-point lưu số thực dưới dạng số nguyên đã nhân với 2^n. Ví dụ Q15 dùng số nguyên 16-bit có dấu với 15 bit phần lẻ: 0.5 được lưu thành 0.5 × 32768 = 0x4000. Thư viện CMSIS-DSP của ARM có sẵn các hàm lọc, FFT cho kiểu Q15 và Q31.

Bài viết liên quan