🌱 Giao tiếp External EEPROM với vi điều khiển AVR ATMega16

Hướng dẫn Giao tiếp External EEPROM AT24C512 với AVR ATMega16 | Lập Trình Điện Tử

     Bộ nhớ Non-Volatile là loại bộ nhớ cực kỳ quan trọng trong các ứng dụng nhúng. Các loại bộ nhớ này đã được mình giới thiệu chi tiết trong bài viết về Embedded Memory.

     Trong các ứng dụng nhúng, thông thường khi bộ nhớ nội nhỏ thì chúng ta thường sử dụng thêm bộ nhớ ngoài. Đôi khi, trong một số ứng dụng, bộ nhớ nội thường chỉ được sử dụng để lưu trữ code, vì người lập trình có thể mở rộng ứng dụng thông qua FOTA, vì vậy, một số thông tin khác cần lưu như thông tin cấu hình của người dùng, một số data quan trọng, hay các lỗi gặp phải trong runtime, ... sẽ cần được lưu ở một vùng nhớ nào đó để tránh conflict. Và loại bộ nhớ thường được sử dụng để lưu trữ các thông tin đó chính là External EEPROM.

➤ Tại sao lại chọn External EEPROM?

     Dễ thấy, chúng ta hoàn toàn có thể chọn internal EEPROM, tức bộ nhớ tích hợp sẵn bên trong chip. Nhưng như đã nói ở trên, để dễ quản lý, một số ứng dụng lựa chọn 2 bộ nhớ tách biệt:

  • Bộ nhớ nội để lưu trữ code chương trình
  • Bộ nhớ ngoài để lưu trữ thông tin cấu hình, một số data, các lỗi runtime, ...
    Ví dụ trong bài toán "Giải mã tín hiệu hồng ngoại", mình cần lựa chọn xem lưu trữ data về mã lệnh hồng ngoại giải mã được ở đâu ? Nếu đặt trong EEPROM nội thì đặt ở vùng nào để tránh bị conflict với code chương trình ?

    ➜ Thường thì lựa chọn sẽ là tìm đến page có địa chỉ cao nhất của EEPROM. Nhưng cách này có vẻ vẫn chưa an toàn, vì code hoàn toàn có thể tràn lên đây!

    ➜ Cách lựa chọn để dễ quản lý nhất chính là External Memory!

    ❓Vậy tại sao không phải là External Flash?

    Dễ thấy Flash sẽ thao tác nhanh hơn so với EEPROM và dung lượng cũng sẽ lớn hơn. Tuy nhiên cần nhìn vào data chúng ta sẽ lưu trên đó. Các thông tin cấu hình khi giải mã hồng ngoại ? Các lỗi runtime ? Các data này có 2 đặc điểm phù hợp với EEPROM:

  • Kích thước data nhỏ
  • Số lần ghi xóa nhiều
    Vì vậy, dùng Flash sẽ lãng phí và không đảm bảo vì tuổi thọ của Flash khá thấp (10,000+ chu kỳ), trong khi tuổi thọ của EEPROM là 100,000+ chu kỳ.

➤ Giao tiếp vi điều khiển với External EEPROM

    Các dòng External EEPROM phổ biến thường sử dụng giao thức I2C, với ưu điểm tiết kiệm chân, và có thể mở rộng thêm nhiều thiết bị trên cùng một đường bus. Ở bài viết này mình sẽ giới thiệu về External EEPROM với chip AT24Cxxx (xxx biểu thị kích thước của EEPROM với đơn vị KBit), chẳng hạn AT24C512 có dung lượng 512KBit = 64KB. 

Sơ đồ chân IC EEPROM AT24C512
Sơ đồ chân IC EEPROM AT24C512
    Dễ thấy chip AT24C512 có 8 chân, trong đó:

  • 2 chân cấp nguồn VCC và GND cung cấp nguồn 1.8 đến 3.6VDC cho chip
  • 2 chân SCL và SDA dùng để giao tiếp I2C với vi điều khiển
  • 3 chân A0, A1, A2 dùng để chọn địa chỉ cho chip bằng cách kéo lên cao hoặc thấp với mỗi chân. Tức là chúng ta có thể giap tiếp tối đa 2^3 = 8 chip AT24C512 trên một đường bus I2C.
  • Chân WP (Write Protection) dùng để bảo vệ việc ghi vào EEPROM khi được kéo lên mức cao. Khi muốn ghi vào EEPROM, vi điều khiển cần kéo WP = 0.

    ➤ Quy định về địa chỉ của EEPROM

    Địa chỉ của EEPROM AT24C512 được quy định bởi các chân A0, A1, A2 và frame sau:

External EEPROM AT24C512 Address
    Giả sử, 3 chân A0, A1, A2 đều nối GND thì địa chỉ của EEPROM sẽ là 0b1010.000x (với x = 0 để Write và x = 1 để Read), tức 0xA0 là địa chỉ để Write, và 0xA1 là địa chỉ để Read, phần bên dưới sẽ chỉ nói đến 2 địa chỉ này.

    ➤ Ghi dữ liệu vào EEPROM (Thao tác Write)

External EEPROM AT24C512 Write Sequence
Frame truyền khi write một byte EEPROM

    Để thao tác ghi một byte vào EEPROM, Vi điều khiển cần gửi 2 byte địa chỉ cần ghi qua I2C cho EEPROM (vì EEPROM dung lượng 64KB sử dụng 16-bits để đánh địa chỉ), sau đó tiếp tục truyền Data cần ghi vào EEPROM.

    Lưu ý khi write data vào EEPROM sẽ cần mất một khoảng thời gian để hoàn tất, khoảng thời gian này được quy định trong tài liệu datasheet "Self-timed Write Cycle (5 ms Max)", vì vậy, sau khi truyền I2C cho việc Write, chương trình MCU cần delay 5ms hoặc kiểm tra tín hiệu ACK bằng cách liên tục thử gửi tín hiệu cho EEPROM (Polling).

    Việc ghi nhiều byte vào EEPROM cũng diễn ra tương tự, MCU chỉ cần gửi lần lượt từng byte cần ghi qua I2C, sau đó cũng delay 5ms để việc ghi hoàn tất.

External EEPROM AT24C512 Write Page Sequence
Frame truyền I2C khi write nhiều byte EEPROM

    ➥ Tổng hợp lại thì thao tác ghi vào EEPROM sẽ là:

  1. Start I2C và gửi đi Write Command (0xA0)
  2. Gửi lần lượt byte cao và byte thấp của địa chỉ cần ghi qua I2C
  3. Gửi lần lượt các byte Data qua I2C
  4. Đợi hết thời gian Write Cycle (5ms) hoặc liên tục gửi tín hiệu cho EEPROM và kiểm tra ACK.

    ➤ Đọc dữ liệu từ EEPROM (Thao tác Read)

EEPROM AT24C512 Read Byte
Thao tác read một địa chỉ bất kỳ từ EEPROM

    Việc đọc data từ EEPROM sẽ thực hiện từng byte một, để có thể đọc data từ một địa chỉ bất kỳ trên EEPROM, MCU cần:

  • Gửi lệnh Write EEPROM Command (0xA0) sang EEPROM để sau đó thực hiện gửi lần lượt byte cao và byte thấp của địa chỉ cần đọc.
  • Tiếp đó repeat Start I2C và gửi lệnh Read Command (0xA1)
  • Sau đó thực hiện thao tác Read bus I2C với NACK, data nhận được chính là data đọc từ địa chỉ đã gửi trước đó trên EEPROM.

    Nếu muốn đọc nhiều byte liên tiếp, chúng ta có thể lần lượt đọc từng byte với ACK - lúc này không cần gửi lại địa chỉ đọc nữa, byte cuối đọc với NACK là xong.

➤ Test hoạt động của EEPROM AT24C512 giao tiếp Vi điều khiển ATMega16

    >> Download Code và Simulator tại đây!

>>= Follow ngay =<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊

Chúc các bạn học tập tốt 😊

        

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

Đăng nhận xét

Mới hơn Cũ hơn