Site icon TAPIT

Giao thức I2C và giao tiếp với cảm biến nhiệt hồng ngoại MLX90614

Giao thức I2C được sử dụng trong rất nhiều ứng dụng quen thuộc như giao tiếp với module thời gian thực DS1307, DS3231, module I2C-LCD 16×2, IC EEPROM… Vậy giao thức I2C được định nghĩa như thế nào, nó hoạt động ra sao? Bài viết sau đây sẽ giúp các bạn hiểu rõ về giao thức I2C và thực hiện một ví dụ đó là sử dụng vi điều khiển STM32 để đọc nhiệt độ từ cảm biến hồng ngoại MLX90614. 

I. ĐỊNH NGHĨA GIAO THỨC I2C (Inter-Integrated Circuit)
I2C là một giao thức giao tiếp được phát triển bởi Philips Semiconductors để truyền, nhận dữ liệu giữa một hoặc có thể nhiều Master – được xem như là các thiết bị điều khiển trung tâm với một hoặc nhiều Slave – được xem như là các ngoại vi trên cùng một hệ thống thông qua hai đường truyền tín hiệu.

Hình 1: Minh hoạ kết nối sử dụng giao tiếp I2C

[HỌC ONLINE TẠI TAPIT: LẬP TRÌNH VI ĐIỀU KHIỂN STM32, VI XỬ LÝ ARM CORTEX – M]

Các thiết bị kết nối với bus I2C được phân thành hai loại: master và slave. Trong đó, master sở hữu quyền kiểm soát để thực hiện đưa ra yêu cầu đến các slave, còn slave là một thiết bị đáp ứng các yêu cầu từ master. Như hình minh họa ở trên, master thông thường là các vi điều khiển, slave sẽ là các ngoại vi như cảm biến nhiệt độ, LCD driver, EEPROM,…

Tại một thời điểm chỉ có duy nhất một thiết bị master ở trạng thái hoạt động trên bus I2C. master điều khiển bus clock SCL và quyết định hoạt động nào sẽ được thực hiện trên bus dữ liệu SDA. Tất cả các thiết bị đáp ứng các yêu cầu từ thiết bị master này đều là slave. Để phân biệt giữa nhiều thiết bị slave khi được kết nối với cùng một hệ thống bus I2C thì mỗi thiết bị slave sẽ có một địa chỉ vật lý 7-bit cố định.

Khi một thiết bị master muốn truyền hoặc nhận dữ liệu từ một thiết bị slave, master sẽ xác định địa chỉ thiết bị slave cụ thể trên đường SDA và sau đó tiến hành truyền dữ liệu. Tất cả các thiết bị slave khác không gửi tín hiệu phản hồi về, trừ khi địa chỉ của chúng được chỉ định bởi thiết bị master trên đường SDA.

II.PHƯƠNG THỨC HOẠT ĐỘNG – TRƯỜNG HỢP SỬ DỤNG
Trường hợp 1: Thiết bị master muốn gửi dữ liệu cho một thiết bị slave


Hình 2: Khung truyền dữ liệu khi thiết bị master muốn gửi dữ liệu cho thiết bị slave

Trường hợp 2: Thiết bị master muốn đọc dữ liệu từ một thiết bị slave


Hình 3: Khung truyền dữ liệu khi thiết bị master muốn đọc dữ liệu từ thiết bị slave

Phân tích các thành phần trong khung truyền: 
1. Điều kiện bắt đầu và điều kiện kết thúc (STAT, STOP)

Hình 4: Tín hiệu của điều kiện bắt đầu và điều kiện kết thúc

2. Các bit địa chỉ 

3. Bit cấu hình đọc/ghi dữ liệu (R/W)

4. Bit xác nhận (ACK/NACK)

5. Các bit dữ liệu (Data)

6. Lặp lại điều kiện bắt đầu (Repeated Start)

III. MỘT SỐ HÀM HỖ TRỢ LÀM VIỆC VỚI I2C TRONG THƯ VIỆN HAL – STM32

1. HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress,uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

-> Dùng để đọc một lượng dữ liệu ở chế độ blocking (hàm sẽ không return và chờ cho đến khi có 1 sự kiện hoặc khi có dữ liệu đến) từ bộ nhớ có địa chỉ cụ thể.

– Chi tiết các tham số hàm này như sau:

– Giá trị trả về: Status

2. HAL_I2C_Mem_Write(I2C_HandleTypeDef * hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t * pData, uint16_t Size, uint32_t Timeout)

-> Dùng để ghi một lượng dữ liệu ở chế độ blocking từ bộ nhớ có địa chỉ cụ thể

– Tham số và giá trị trả về giống HAL_I2C_Mem_Read

3. HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size,uint32_t Timeout): Dùng để nhận một lượng data ở mode Master

– Giá trị trả về : Status

– Lưu ý: Vì hàm này dùng để nhận data ở mode Master nên sẽ không có tham số MemAddress và MemAddSize

4. HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size,uint32_t Timeout): Dùng để truyền một lượng data ở mode Master

– Giá trị trả về : Status

IV. THỰC HÀNH GIAO TIẾP I2C, VI ĐIỀU KHIỂN STM32 VÀ MODULE MLX90614

a. Thông số kỹ thuật

Điện áp hoạt động: 2,6 ~ 3,6V

Dải đo: Nhiệt độ môi trường xung quanh -40°C đến +125°C, nhiệt độ vật thể -70°C đến +380° có thể đo được

Sai số: Chênh lệch 0,5°C ở nhiệt độ phòng, 0.2°C đối với nhiệt độ đối tượng

Độ phân giải đo: 0,02°C

b. Cách đặt vị trí, khoảng cách của vật cần đo đến cảm biến

Vị trí: Đặt vật cần đo tại điểm Point heat source, tại điểm này cảm biến có độ nhạy cao nhất (100%) thì nhiệt độ của đối tượng cần đo sẽ chính xác nhất. Khoảng cách để đo giá trị chính xác nhất: Point heat source = 7 đến 10 cm.

c. Các đọc giá trị nhiệt độ từ cảm biến MLX90614
Các bạn cần đọc tài liệu datasheet của cảm biến này.
MLX có 2 bộ nhớ quan trọng: EEPROM và RAM.
Địa chỉ truy cập RAM:         000x xxxx*
Địa chỉ truy cập EEPROM: 001x xxxx*

Nhiệt độ của đối tượng (temperature of object) được lưu trong bộ nhớ RAM, giá trị trả về sẽ được đưa vào 2 thanh ghi TOBJ1 hoặc TOBJ2. Địa chỉ: TOBJ1: 0x07, TOBJ2: 0x08

Sau khi đọc giá trị nhiệt độ của đối tượng ở TOBJ1 hoặc TOBJ2, ta thực hiện chuyển nhiệt độ đổi qua độ K qua công thức:

Với To: nhiệt độ của đối tượng (K).

Toreg: địa chỉ thanh ghi chứa nhiệt độ chuyển sang hệ thập phân.

d. Thực hành sử dụng vi điều khiển STM32 giao tiếp với cảm biến MLX90614 

Bước 1: Mở phần mềm STM32CubeIDE, chọn vi điều khiển. Ở đây mình sẽ thực hành trên dòng STM32F303. Các bạn vẫn có thể sử dụng KeilC để thực hành và sử dụng vi điều khiển STM32 khác.

Bước 2: Cấu hình Serial Wires

Bước 3: Cấu hình ngoại vi I2C. Ở đây mình sẽ chọn bộ I2C1 để thực hành.

Bước 4: Sinh code và chuyển qua giao diện C/C++ (main.c)

Bước 5: Ở vòng lặp while(1) chúng ta thực hiện đọc giá trị nhiệt độ từ cảm biến và quy đổi về độ C

Bước 6: Thực hiện biên dịch và chuyển qua giao diện Debug để kiểm tra các giá trị

Hình ảnh thực hành của nhóm:

Hi vọng với bài viết này các bạn có thể hiểu rõ hơn về giao thức I2C cũng như sử dụng các API có liên quan trong thư viện HAL. Các bạn có thể thực hành với một số ngoại vi I2C khác như LCD-I2C, EEPROM hoặc giao tiếp giữa 2 vi điều khiển với nhau để hiểu hơn về giao thức này

Chúc các bạn thành công!

Nhóm thực tập:
Phương Duy, Thảo Ly, Thị Nghị, Đức Hưng

Tìm hiểu thêm:
[HỌC ONLINE TẠI TAPIT: LẬP TRÌNH VI ĐIỀU KHIỂN STM32, VI XỬ LÝ ARM CORTEX – M]
Tổng hợp hướng dẫn Internet of Things với NodeMCU ESP8266 và ESP32
Tổng hợp các bài hướng dẫn Lập trình vi điều khiển STM32
Fanpage Cộng đồng Kỹ thuật TAPIT: TAPIT – Learning, Research and Sharing Community

Tài liệu tham khảo:
– Understanding the I 2C Bus – Texas Instruments – Jonathan Valdez, Jared Becker
– MLX90614 datasheet.