Giao tiếp ngoại vi I2C

0
1447

Khái niệm

I²C (viết tắt của từ tiếng Anh “Inter-Integrated Circuit”, phát âm tiếng Anh I-two-C, hoặc cũng có thể viết là IIC) là một loại bus nối tiếp hai chiều với hai dây tín hiệu được phát triển bởi hãng sản xuất linh kiện điện tử Philips (nay là hãng NXP Semiconductors) cho quá trình giao tiếp giữa các IC.[1] Truyền thông với bus I²C là quá trình truyền thông đồng bộ nối tiếp, hỗ trợ nhiều master và slave trên đường truyền. I²C phù hợp với các ngoại vi mà sự ưu tiên về kết nối đơn giản và chi phí sản xuất thấp quan trọng hơn là yêu cầu về tốc độ truyền.

SMBus (System Management Bus), là một “chuẩn con” của I²C, được giới thiệu bởi Intel vào năm 1995, với đặc tính sử dụng nghiêm ngặt hơn. SMBus nổi bật bởi tính ổn định và độ tương thích cao. Do đó, các hệ thống I²C ngày nay đã sử dụng một số chính sách và nguyên tắc của SMBus, và đôi khi hỗ trợ cả I²C và SMBus, thông qua việc sử dụng câu lệnh (command) hoặc thay đổi kết nối các chân linh kiện.

Đặc điểm kĩ thuật

Các tính năng của một bus I²C:

– Chỉ sử dụng hai đường bus: SDA (serial data line, tạm dịch: đường truyền dữ liệu nối tiếp) và SCL (serial clock line, tạm dịch: đường xung nhịp nối tiếp).

–  Hoạt động theo cơ chế master-slave với cả master và slave đều có thể truyền-nhận dữ liệu. Hỗ trợ nhiều master với cơ chế phát hiện va chạm trên đường truyền (collision detection) và phân xử (arbitration) khi có va chạm tín hiệu để ngăn ngừa mất dữ liệu nếu hai hoặc nhiều master truyền tín hiệu cùng lúc.

–  Mỗi thiết bị kết nối vào bus được định một địa chỉ duy nhất bằng phần mềm.

–  Quá trình truyền dữ liệu nối tiếp hai chiều 8-bit có định hướng có thể đạt tốc độ lên đến 100 kbit/giây với Standard-mode (tạm dịch: chế độ tiêu chuẩn), 400 kbit/giây với Fast-mode (tạm dịch: chế độ nhanh), 1 Mbit/giây với Fast-mode Plus (Fm+) hoặc đến 3.4 Mbit/s với High-speed mode.[1] Ultra Fast-mode là chế độ chỉ truyền đơn hướng với tốc độ có thể lên đến 5Mbit/giây.[1]

–  Lọc nhiễu các xung nhọn trên đường bus để đảm bảo tính toàn vẹn dữ liệu.

–  Số lượng IC tối đa có thể kết nối được trên I²C bus chỉ phụ thuộc vào sức chứa tối đa của bus.

Nội dung Project

Sử dụng giao tiếp I2C, ghi và đọc giá trị vào IC EEPROM AT24C32

Sơ đồ kết nối AT24C32, các chân A0,A1,A2 được nối xuống mass, nên địa chỉ I2C của AT24C32 sẽ là 0xA0. Các chân SCL và SDA lần lượt sẽ kết nối với các chân I2C tương ứng của STM32.

Cấu hình trên STM32CubeMX

Bước 1: Mở STM32CubeMX và tạo dự án mới

Bước 2: Gõ tên tìm kiếm loại MCU cần lập trình và click đúp vào tên của nó

Bước 3: Cấu hình chế độ Debug cho chip là Serial Wire

Bước 4: Trong tab Clock Configuration, cấu hình tần số hoạt động cho chip là 216Mhz (max)

Bước 5: Cấu hình sử dụng bộ I2C

Trong cây thư mục ngoại vi Connectivity, chọn I2C1, ở mục Mode  chọn mode là I2C, ở dây chúng ta chỉ cần chọn tốc độ giao tiếp I2C là 100/400Khz, trong ví dụ này chọn 100Khz.

Bước 6: Cấu hình sử dụng UART để debug chương trình

Để theo dõi các giá trị đọc và ghi giữa VĐK STM32 với IC EEPROM, chúng ta sẽ xuất các kết quả đọc và ghi ra cổng UART để tiện theo dõi trên máy tính. Ở mục Mode của USART1, chúng ta chọn là Asynchronous (giao tiếp bất đồng bộ). Các tham số cơ bản như tốc độ baund, độ dài data truyền đi chúng ta chọn như hình dưới.

Bước 7: Trong tab Project Manager, đặt tên cho Project, chọn đường dẫn lưu thư mục, chọn trình biên dịch là Keilc (MDK-ARM) và chọn phiên bản sử dụng

Bước 8: Trong mục Code Generator tích chọn Generate peripheral initialization.. Sau đó tiến hành GENERATE CODE.

Trong hàm main, định nghĩa địa chỉ I2C của AT24C32 là 0xA0;

Để giao tiếp với AT24C32, chúng ta cần xây dựng 2 hàm đọc và ghi vào IC, hình dưới là nội dung hàm đọc dữ liệu từ AT24C32. Tham số của hàm là địa chỉ thanh ghi cần đọc dữ liệu.

Trong hàm at24c32_read_reg, địa chỉ cần đọc dữ liệu sẽ được chia thành 2 byte, biến value được dùng để lưu giá trị đọc được từ AT24C, hàm HAL_I2C_Master_Transmit(&hi2c1,add_i2c_at24c32,arr_temp,2,10); sẽ thực hiện giao tiếp AT24C qua bộ I2C1 của STM32, địa chỉ so khớp là add_i2c_at24c32,  thanh ghi cần đọc dữ liệu là arr_temp, chỉ số 2 biểu thị dữ liệu ghi vào là 2byte, và chỉ số 10 là thời gian timeout, nếu hết 10ms hoạt động đọc không thành công đoạn lệnh HAL_I2C_Master_Transmit sẽ tự thoát.

Sau khi ghi địa chỉ thanh ghi cần đọc cho AT24C32, hàm HAL_I2C_Master_Receive(&hi2c1,add_i2c_at24c32,value,1,10); được gọi ra để đọc giá trị trả về, giá trị trả về sẽ được lưu vào biến value.

Giá trị đọc được sau đó sẽ xuất ra cổng UART qua các hàm:

//xuat ket qua doc ra UART1

HAL_UART_Transmit(&huart1,”\rread reg”,sizeof(“\rread reg”)-1,10);

HAL_UART_Transmit(&huart1,(uint8_t*)buff_value,sprintf(buff_value, “%d”, reg),10);

HAL_UART_Transmit(&huart1,”=”,1,10);

HAL_UART_Transmit(&huart1,(uint8_t*)buff_value,sprintf(buff_value, “%d”, value[0]),10);              

Để ghi giá trị vào các thanh ghi của AT24C32, chúng ta xây dựng hàm ghi dữ liệu:

Tham số của hàm bao gồm địa chỉ thanh ghi cần ghi và dữ liệu muốn ghi. Cũng giống như hàm đọc, hàm ghi cũng thực hiện ghi địa chỉ thanh ghi cần truy cập, địa chỉ ghi vào được tách thành 2 byte. Dữ liệu cần ghi sẽ được lưu trong biến value. Hàm HAL_I2C_Master_Transmit(&hi2c1,add_i2c_at24c32,arr_temp,3,10); sẽ thực hiện ghi dữ liệu vào ngoại vi I2C có địa chỉ là add_i2c_at24c32, thanh ghi và giá trị cần ghi là mảng arr_temp, số byte được ghi là 3 byte và chỉ số 10 là thời gian timeout được tính bắng mili giây.

Trong hàm main, chúng ta sẽ thực hiện ghi vào 20 thanh ghi của AT24C32 và đọc ngược dữ liệu ra của 20 thanh ghi đó.

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

Biên dịch: Mai Văn Ba

Để cập nhật tin tức công nghệ mới nhất và các sản phẩm của công ty AIoT JSC, vui lòng truy cập link: http://aiots.vn hoặc linhkienaiot.com

0 0 Phiếu bầu
Article Rating
Subscribe
Notify of
guest
0 Comments
Phản hồi nội tuyến
Xem tất cả các bình luận