- Giao thức truyền thông I2C là gì?
- Giao tiếp I2C hoạt động như thế nào?
- Sử dụng Giao tiếp I2C ở đâu?
- I2C trên Nuvoton N76E003 - Yêu cầu phần cứng
- Giao tiếp AT24LC64 với Nuvoton N76E003 - Sơ đồ mạch
- I2C Pins trên Nuvoton N76E003
- Giao tiếp I2C trong N76E003
- Lập trình N76E003 cho giao tiếp I2C
- Nhấp nháy mã và đầu ra
Trong hệ thống rộng lớn của các ứng dụng nhúng, không có vi điều khiển nào có thể tự thực hiện tất cả các hoạt động. Tại một số giai đoạn, nó phải giao tiếp với các thiết bị khác để chia sẻ thông tin, có nhiều loại giao thức truyền thông khác nhau để chia sẻ những thông tin này, nhưng được sử dụng nhiều nhất là USART, IIC, SPI và CAN. Mỗi giao thức truyền thông đều có ưu và nhược điểm riêng. Bây giờ chúng ta hãy tập trung vào phần IIC vì đó là những gì chúng ta sẽ tìm hiểu trong hướng dẫn này. Nếu bạn là người mới ở đây, hãy xem Hướng dẫn Nuvoton nơi chúng tôi đã thảo luận về mọi thiết bị ngoại vi của Vi điều khiển N76E003 từ hướng dẫn bắt đầu rất cơ bản. Nếu bạn muốn tìm hiểu cách sử dụng I2C với các bộ vi điều khiển khác, bạn có thể xem các liên kết bên dưới.
- Cách sử dụng I2C trong Arduino: Giao tiếp giữa hai Bo mạch Arduino
- Giao tiếp I2C với Vi điều khiển PIC PIC16F877
- Giao diện LCD 16X2 với ESP32 sử dụng I2C
- Giao tiếp I2C với MSP430 Launchpad
- Giao diện LCD với NodeMCU mà không cần sử dụng I2C
- Cách xử lý đa giao tiếp (I2C SPI UART) trong một chương trình duy nhất của Arduino
I2C là một giao thức truyền thông quan trọng được phát triển bởi Philips (nay là NXP). Sử dụng giao thức I2C này, MCU có thể được kết nối với nhiều thiết bị và bắt đầu giao tiếp. I2C chỉ hoạt động với hai dây, đó là SDA và SCL. Trong đó SDA là viết tắt của Serial data và SCL là viết tắt của Serial Clock. Tuy nhiên, hai chân này yêu cầu điện trở kéo lên đến mức điện áp VCC và với một điện trở kéo lên thích hợp, bus có thể hỗ trợ 127 thiết bị với một địa chỉ duy nhất.
Giao thức truyền thông I2C là gì?
Thuật ngữ IIC là viết tắt của “ Inter Integrated Circuits ”. Nó thường được ký hiệu là I2C hoặc I bình phương C hoặc thậm chí là giao thức giao diện 2 dây (TWI) ở một số nơi nhưng tất cả đều có nghĩa giống nhau. I2C là một giao thức truyền thông đồng bộ có nghĩa là cả hai thiết bị đang chia sẻ thông tin phải chia sẻ một tín hiệu đồng hồ chung. Nó chỉ có hai dây để chia sẻ thông tin, trong đó một dây được sử dụng cho tín hiệu đồng hồ và dây kia được sử dụng để gửi và nhận dữ liệu.
Giao tiếp I2C hoạt động như thế nào?
Giao tiếp I2C lần đầu tiên được giới thiệu bởi Phillips. Như đã nói trước đó, nó có hai dây, hai dây này sẽ được kết nối qua hai thiết bị. Ở đây một thiết bị được gọi là master và thiết bị còn lại được gọi là slave. Giao tiếp nên và sẽ luôn xảy ra giữa hai, một Master và một Slave. Ưu điểm của giao tiếp I2C là có thể kết nối nhiều hơn một nô lệ với một Master.
Giao tiếp hoàn chỉnh diễn ra thông qua hai dây này là Đồng hồ nối tiếp (SCL) và Dữ liệu nối tiếp (SDA).
Đồng hồ nối tiếp (SCL): Chia sẻ tín hiệu đồng hồ được tạo ra bởi chính với phụ
Dữ liệu nối tiếp (SDA): Gửi dữ liệu đến và đi giữa Master và slave.
Tại bất kỳ thời điểm nào, chỉ có chủ mới có thể bắt đầu giao tiếp. Vì có nhiều hơn một nô lệ trong xe buýt, chủ phải tham chiếu đến mỗi nô lệ bằng một địa chỉ khác nhau. Khi được giải quyết, chỉ những người có địa chỉ cụ thể đó sẽ trả lời lại thông tin trong khi những người khác giữ im lặng. Bằng cách này, chúng ta có thể sử dụng cùng một bus để giao tiếp với nhiều thiết bị.
Sử dụng Giao tiếp I2C ở đâu?
Giao tiếp I2C chỉ được sử dụng cho giao tiếp khoảng cách ngắn. Nó chắc chắn đáng tin cậy ở một mức độ nào đó vì nó có xung đồng hồ được đồng bộ hóa để làm cho nó trở nên thông minh. Giao thức này chủ yếu được sử dụng để giao tiếp với cảm biến hoặc các thiết bị khác phải gửi thông tin đến chủ. Nó rất tiện dụng khi một bộ vi điều khiển phải giao tiếp với nhiều mô-đun phụ khác bằng cách sử dụng tối thiểu chỉ dây. Nếu bạn đang tìm kiếm giao tiếp tầm xa, bạn nên thử RS232 và nếu bạn đang tìm kiếm giao tiếp đáng tin cậy hơn, bạn nên thử giao thức SPI.
I2C trên Nuvoton N76E003 - Yêu cầu phần cứng
Vì yêu cầu của dự án này là học giao tiếp I2C bằng N76E003, chúng tôi sẽ sử dụng một EEPROM sẽ được kết nối với đường dữ liệu I2C. Chúng tôi sẽ lưu trữ một số dữ liệu vào EEPROM và cũng đọc dữ liệu tương tự và hiển thị nó bằng màn hình UART.
Vì giá trị được lưu trữ sẽ được in trong UART, nên bất kỳ loại bộ chuyển đổi USB sang UART nào cũng được yêu cầu. Bạn cũng có thể xem hướng dẫn về UART với Nuvoton nếu bạn chưa quen với giao tiếp UART trên N76E003. Đối với ứng dụng của chúng tôi, chúng tôi sẽ sử dụng bộ chuyển đổi CP2102 UART sang USB. Ngoài những điều trên, chúng tôi cũng yêu cầu các thành phần sau:
- EEPROM 24C02
- 2 điện trở 4,7k
Chưa kể, ngoài những thành phần trên, chúng ta cần một board phát triển dựa trên vi điều khiển N76E003 cũng như Nu-Link Programmer. Ngoài ra, breadboard và dây hookup cũng được yêu cầu để kết nối tất cả các thành phần.
Giao tiếp AT24LC64 với Nuvoton N76E003 - Sơ đồ mạch
Như chúng ta có thể thấy trong sơ đồ bên dưới, EEPROM được kết nối trong đường I2C cùng với hai điện trở kéo lên. Ở phía bên trái, kết nối giao diện lập trình được hiển thị.
Tôi đã sử dụng một breadboard cho IC AT24LC64 và kết nối IC với bảng lập trình nuvoton của tôi bằng dây nhảy. Thiết lập phần cứng của tôi cùng với bộ lập trình nu-ink được hiển thị bên dưới.
I2C Pins trên Nuvoton N76E003
Sơ đồ chân của N76E003 có thể được nhìn thấy trong hình ảnh dưới đây-
Như chúng ta thấy, mỗi chân cắm có thông số kỹ thuật khác nhau và mỗi chân cắm có thể được sử dụng cho nhiều mục đích. Tuy nhiên, chân 1.4 được sử dụng làm chân I2C SDA, nó sẽ làm mất PWM và các chức năng khác. Nhưng đó không phải là vấn đề vì một chức năng khác không cần thiết cho dự án này. Điều tương tự sẽ xảy ra đối với P1.3 là chân SCL của I2C.
Vì các chân I2C hoạt động như một GPIO nên nó cần được cấu hình. Tất cả các chân GPIO có thể được định cấu hình ở chế độ được mô tả dưới đây.
Theo biểu dữ liệu, PxM1.n và PxM2. n là hai thanh ghi được sử dụng để xác định hoạt động điều khiển của cổng I / O. Trong biểu dữ liệu, nó được nêu rõ rằng để sử dụng chức năng I2C, các chế độ I / O cần được sử dụng như Open-out cho các giao tiếp liên quan đến I2C.
Giao tiếp I2C trong N76E003
Thiết bị ngoại vi I2C là một thứ quan trọng đối với bất kỳ bộ vi điều khiển nào hỗ trợ các tính năng I2C. Nhiều loại vi điều khiển khác nhau đi kèm với thiết bị ngoại vi I2C tích hợp sẵn. Tuy nhiên, trong một số trường hợp, I2C có thể được cấu hình theo cách thủ công bằng cách sử dụng điều khiển phần mềm khi hỗ trợ phần cứng liên quan đến I2C không khả dụng (Ví dụ: nhiều bộ vi điều khiển 8051). Tuy nhiên, nuvoton N76E003 đi kèm với hỗ trợ ngoại vi I2C.
M76E003 hỗ trợ bốn loại hoạt động trong các chế độ I2C - Bộ phát chính, Bộ thu chính, Bộ phát Slave và Bộ thu Slave. Nó cũng hỗ trợ tốc độ tiêu chuẩn (100kbps) và nhanh (lên đến 400kbps) cho dòng I2C. I2C hoạt động với một số quy tắc chung trong đường tín hiệu SCL và SDA.
Điều kiện Bắt đầu và Dừng:
Đó là một điều quan trọng trong giao tiếp I2C. Khi dữ liệu được chuyển đến dòng I2C, nó bắt đầu với điều kiện bắt đầu và kết thúc với điều kiện dừng.
Điều kiện bắt đầu là quá trình chuyển đổi từ cao xuống thấp trên SDA khi dòng SCL cao và điều kiện dừng là quá trình chuyển đổi từ thấp đến cao trên SDA khi dòng SCL ở mức cao. Hai điều kiện này được tạo ra bởi master (MCU hoặc bất cứ thứ gì đang điều khiển các thiết bị phụ khác). Đường xe buýt vẫn bận ở trạng thái này khi điều kiện bắt đầu được bắt đầu và vẫn tự do trở lại khi điều kiện dừng được bắt đầu.
Điều kiện Bắt đầu và Dừng được thể hiện một cách xuất sắc trong phối cảnh tín hiệu trong biểu dữ liệu N76E003-
Địa chỉ 7 bit với định dạng dữ liệu:
N76E003 hỗ trợ địa chỉ 7-bit và định dạng dữ liệu. Sau khi điều kiện bắt đầu được bắt đầu, thiết bị chủ cần gửi dữ liệu đến dòng I2C. Dữ liệu đầu tiên là một dữ liệu quan trọng. Nếu dữ liệu này không được tạo hoặc truyền đúng cách, thiết bị được kết nối sẽ không được nhận dạng và không thể thực hiện các liên lạc khác.
Dữ liệu bao gồm một địa chỉ nô lệ dài 7 bit, được ký hiệu là SLA. Địa chỉ dài 7 bit này cần phải là duy nhất cho mỗi thiết bị nếu nhiều thiết bị được kết nối trên bus. Sau địa chỉ 7 bit, bit thứ 8 là bit hướng dữ liệu. Điều đó có nghĩa là, tùy thuộc vào bit thứ 8, master sẽ gửi thông tin đến thiết bị tớ về việc dữ liệu sẽ được ghi vào thiết bị tớ hay dữ liệu sẽ được đọc từ thiết bị tớ. Bit thứ 8 là bit R / W được gọi là trình thông báo Đọc hoặc Ghi. Như chúng ta đã biết thông tin 8-bit có thể có 128 loại, do đó hỗ trợ 128 thiết bị, nhưng I2C hỗ trợ 127 loại thiết bị trên cùng một bus chứ không phải 128. Vì địa chỉ 0x00 là địa chỉ dành riêng nên được gọi là địa chỉ cuộc gọi chung. Nếu thiết bị chính muốn gửi thông tin đến tất cả các thiết bị,nó sẽ giải quyết 0x00 và mỗi thiết bị sẽ phát lại theo cách tương tự như theo cấu hình phần mềm riêng lẻ.
Do đó, việc truyền dữ liệu trông giống như bên dưới-
Công nhận:
Trong hình ảnh địa chỉ dữ liệu ở trên, bit thứ 9 theo sau là bit R / W được gọi là bit xác nhận. Nó là một điều quan trọng bởi vì sử dụng bit này, master hoặc slave phản hồi với bộ truyền dữ liệu bằng cách kéo dòng SDA xuống thấp. Để nhận được bit xác nhận, máy phát cần giải phóng dòng SDA.
Lập trình N76E003 cho giao tiếp I2C
Chương trình hoàn chỉnh được sử dụng trong hướng dẫn này có thể được tìm thấy ở cuối trang này. Giải thích về các phân đoạn quan trọng trong mã như sau:
Đặt Ghim làm Cống mở và Định cấu hình chúng cho I2C:
Hãy bắt đầu với phần chân I2C trước. Như đã mô tả trước đây, các cổng I2C SCL và SDA cần được định cấu hình và đặt làm cấu hình thoát mở. Để làm điều này, chúng tôi đang sử dụng một tập tin tiêu đề I2C.h cùng với một tập tin nguồn I2C.c . Đoạn mã trông như thế này-
làm {P13_OpenDrain_Mode; P14_OpenDrain_Mode; clr_I2CPX;} trong khi (0)
Đoạn mã trên đang đặt P13 và P14 làm chân Open-Drain và clr_I2CPX được sử dụng để chọn P13 và P14 làm chân SCL trên P1.3 và chân SDA trên P1.4.
Đây I2CPX là bit 0 của kiểm soát I2C đăng ký I2CON. Nếu I2C_PX này được đặt là 1, các chân được thay đổi thành P0.2 dưới dạng SCL và P1.6 là SDA. Tuy nhiên, chúng tôi sẽ sử dụng P13 và P14. Các chân thay thế không được sử dụng ở đây.
Thanh ghi điều khiển I2C I2CON:
Thanh ghi điều khiển I2C I2CON được sử dụng để điều khiển các hoạt động của I2C. Bit đầu tiên là bit chọn chân I2C. Đặt nó 0 sẽ cấu hình chân I2C là P13 và P14.
Bit AA là cờ xác nhận Acknowledge, nếu cờ AA được thiết lập, một ACK sẽ được trả về trong xung đồng hồ xác nhận của dòng SCL. Nếu nó bị xóa, một NACK (mức cao trên SDA) sẽ được trả về trong thời gian xung đồng hồ được thừa nhận của đường SCL.
Bit tiếp theo là SI là ngắt trạng thái I2C. Nếu Ngắt trạng thái I2C được bật, người dùng nên kiểm tra thanh ghi I2STAT để xác định bước nào đã được vượt qua và nên thực hiện hành động.
STO là cờ STOP đang được đặt ở chế độ chính. STO sẽ tự động được xóa bằng phần cứng khi điều kiện STOP được phát hiện.
Bit tiếp theo là bit STA. Nếu cờ này được thiết lập, thì I2C tạo điều kiện START nếu bus đang rảnh. Nếu bus bận, I2C sẽ đợi điều kiện STOP và tạo điều kiện START sau đó. Nếu STA được đặt trong khi I2C đã ở chế độ chính và một hoặc nhiều byte đã được truyền hoặc nhận, I2C sẽ tạo điều kiện START lặp lại. STA cần được xóa thủ công bằng phần mềm.
Cái cuối cùng, I2CEN là bit kích hoạt hoặc vô hiệu hóa bus I2C.
EEPROM 24C02:
Bây giờ, đến với 24C02. Gói hỗ trợ bo mạch của N76E003 có mã I2C cho 24LC64 và có thể được sửa đổi dễ dàng. Tuy nhiên, chúng ta sẽ sử dụng một phương pháp đơn giản để hiểu hàm I2C.
Nếu ai đó muốn sử dụng giao tiếp chi tiết với EEPROM 24C02, thì có thể sử dụng chương trình EEPROM trong BSP.
Chúng tôi sẽ chỉ kết nối 24C02 trong I2C nơi N76E003 sẽ là chính và EEPROM sẽ là nô lệ. Vì vậy, chúng tôi sẽ ghi bất kỳ dữ liệu nào vào địa chỉ EEPROM và đọc như nhau.
Sơ đồ chân EEPROM 24C02 được hiển thị bên dưới-
A0, A1 và A2 là ba chân chọn địa chỉ. Các chân WP là chân bảo vệ Ghi và cần được kết nối với VSS để cho phép ghi vào EEPROM.
Chức năng Viết Byte được hiển thị trong hình ảnh dưới đây-
Chu kỳ ghi đầy đủ xảy ra với một bit bắt đầu. Sau đó, byte điều khiển cần được gửi. Trong byte điều khiển, những điều sau đây là bắt buộc-
Sau bit bắt đầu, bao gồm địa chỉ nô lệ. 1010 là địa chỉ tĩnh và A0, A1 và A2 là địa chỉ dựa trên kết nối phần cứng. Nếu ba chân được kết nối với nguồn cung cấp GND hoặc VSS, nó sẽ được đọc là 0. Ngược lại, nếu được kết nối với VCC, nó sẽ được đọc là 1. Trong trường hợp của chúng tôi, tất cả A0, A1 và A2 đều được kết nối với VSS. Vì vậy, tất cả những điều này sẽ là 0.
Chi tiêu trên điều kiện đọc hoặc ghi. Giá trị của địa chỉ có bit Đọc hoặc Ghi sẽ là - 0xA0 cho Ghi và 0xA1 cho đọc. Tiếp theo là bit Acknowledge và sau đó, một địa chỉ 8 bit sẽ được truyền đến nơi dữ liệu cần được lưu trữ và cuối cùng, dữ liệu sẽ được lưu trữ ở vị trí tương ứng. Những điều này được thực hiện theo định dạng từng bước trong chức năng chính.
Chức năng chính và Vòng lặp Trong khi:
void main (void) {char c = 0x00; Ban đầuUART0_Timer3 (115200); TI = 1; // Quan trọng, sử dụng hàm Princeft phải đặt TI = 1; I2C_init (); while (1) {EEPROM_write (1,0x55); c = EEPROM_read (1); printf ("\ n Giá trị được đọc là% x", c & 0xff); } }
Chức năng chính rất đơn giản, nó liên tục ghi các giá trị vào EEPROM ở địa chỉ 1 và đọc dữ liệu. Dữ liệu sau đó sẽ được in bằng cách sử dụng hàm printf. Printf đang in giá trị dưới dạng hex.
Chức năng ghi EEPROM bao gồm những điều sau đây đã được mô tả trong phần EEPROM-
void EEPROM_write (unsigned char address, unsigned char value) {I2C_start (); I2C_write (0xA0); I2C_write (địa chỉ); I2C_write (giá trị); I2C_stop (); }
Hàm khởi động I2C bao gồm những điều sau:
void I2C_start (void) {đã ký int time = timeout; set_STA; clr_SI; while ((SI == 0) && (time> 0)) {time--; } }
Trong chức năng này, trạng thái SI đang được kiểm tra cùng với khoảng thời gian chờ xác định trước (được định nghĩa trong I2C.h trong đó thời gian xác định trước được đặt là 1000). Chức năng bắt đầu bắt đầu với việc thiết lập STA và xóa SI.
void I2C_stop (void) {đã ký int time = timeout; clr_SI; set_STO; while ((STO == 1) && (time> 0)) {time--; } }
Giống như chức năng Bắt đầu, dừng được sử dụng. Các điểm dừng chức năng được bắt đầu bằng cách thiết lập các STO tiếp bằng cách xóa SI. Chức năng bên dưới là chức năng đọc I2C-
unsigned char I2C_read (unsigned char ack_mode) {đã ký int time = timeout; giá trị char không dấu = 0x00; set_AA; clr_SI; while ((SI == 0) && (t> 0)) {time--; } giá trị = I2DAT; if (ack_mode == I2C_NACK) {t = timeout_count; clr_AA; clr_SI; while ((SI == 0) && (t> 0)) {time--; } } giá trị trả về; }
Các ack_mode và I2C_NACK , cả hai được định nghĩa trong file header I2C là 0 và 1 tương ứng.
Tương tự, hàm ghi được tạo ra-
void I2C_write (unsigned char value) {đã ký int time = timeout; I2DAT = giá trị; clr_STA; clr_SI; while ((SI == 0) && (time> 0)) {time--; } }
Nhấp nháy mã và đầu ra
Mã trả về 0 cảnh báo và 0 Lỗi và được đánh dấu bằng phương pháp nhấp nháy mặc định bởi Keil. Nếu bạn là người mới, hãy xem hướng dẫn bắt đầu với nuvoton để hiểu cách tải lên mã. Thông tin biên dịch của mã có thể được tìm thấy bên dưới.
Xây dựng mục tiêu 'I2C_EEPROM' biên dịch I2C_EEPROM.c… biên dịch I2C.c… liên kết… Kích thước chương trình: data = 59,2 xdata = 0 code = 2409 tạo tệp hex từ ". \ Output \ I2C_EEPROM"… ". \ Output \ I2C_EEPROM "- 0 (Các) lỗi, 0 Cảnh báo. Thời gian xây dựng đã trôi qua: 00:00:04 Tóm tắt bản dựng hàng loạt: 1 thành công, 0 không thành công, 0 bị bỏ qua - Thời gian đã trôi qua: 00:00:04
Phần cứng đang được thiết lập trên breadboard và đang hoạt động như mong đợi. Như bạn có thể thấy trong hình dưới đây, chúng tôi có thể ghi một giá trị trên EEPROM và đọc lại từ bộ nhớ và hiển thị nó trên màn hình nối tiếp.
Hãy xem video dưới đây để có một minh chứng đầy đủ về cách thức hoạt động của bảng đối với mã này. Hy vọng bạn thích hướng dẫn và học được điều gì đó hữu ích nếu bạn có bất kỳ câu hỏi nào, hãy để lại chúng trong phần bình luận bên dưới. Bạn cũng có thể sử dụng diễn đàn của chúng tôi để đăng các câu hỏi kỹ thuật khác.