1. 1 Giới thiệu
3.2.2. Hoạt động của TWI:
TWI trên AVR được gọi là byte-oriented (tạm dịch là hướng byte) và interrupt- based (dựa trên ngắt). Bất kỳ một sự kiện nào trong quá trình truyền/nhận TWI cũng có thể gây ra 1 ngắt TWI. TWI trên AVR vì thế hoạt động tương đối độc lập với chip.
Tuy nhiên, cần khai thác ngắt trên AVR một cách hơp lý. Ví dụ, đối với Master, chúng ta không cần sử dụng ngắt vì chip này hoàn toàn chủ động trong việc truyền và nhận. Riêng với Slave, sử dụng ngắt để tránh bỏ lỡ các cuộc gọi là cần thiết.
Tất cả các AVR trên mạng TWI đều có thể là Master hay Slave, cả Master và Slave đều có thể truyền và nhận dữ liệu. Vì thế, có tất cả 4 mode trong hoạt động của TWI trên AVR. Chúng ta sẽ lần lượt khảo sát các mode này như sau: Master Transmitter (chip chủ truyền), Master Receiver (Chip chủ nhận), Slave Reicever (chip tớ nhận) và Slave Transmitter (Chip tớ truyền).
Trước khi khảo sát các chế độ hoạt động của TWI chúng ta qui ước một số ký hiệu thường dùng (đây cũng là các ký hiệu trong datasheet của các chip AVR).
S: START condition – điều kiện bắt đầu
Rs:REPEAT START – bắt đầu lặp lại
R:READ Bit, bit này bằng 1 được gởi kèm với gói địa chỉ
W: WRITE Bit, bit này mang giá trị 0, gởi kèm gói địa chỉ
ACK: Ackowledge, bit xác nhận, chân SDA được kéo xuống 0 ở xung thứ 9
NACK: Not Acknowledge, không xác nhận, SDA mức cao ở bit thứ 9.
Data: 8 bits dữ liệu.
SLA: Slave address, địa chỉ của Slave cần giao tiếp.
a. Master Transmitter mode – Master truyền dữ liệu:
Trong chế độ này, Master truyền 1 hoặc một số byte dữ liệu đến một hoặc các Slave. Để bắt đầu, Master tạo ra một START condition trên đường SDA, nếu đường truyền đang rảnh, Master sẽ tiếp tục phát đi địa chỉ của Slave cần giao tiếp cùng với bit W (ghi) theo định dạng như sau: SLA+W. Nếu Slave đáp lại bằng một ACK trong xung giữ nhịp thứ 9, Master sẽ tiếp tục gởi 1 hoặc liên tiếp các byte dữ liệu trên SDA.
Cứ sau mỗi byte dữ liệu, Master sẽ kiểm tra ACK từ Slave. Nếu Slave gởi một NACK hoặc Master không muốn gởi thêm dữ liệu đến Slave nó sẽ phát đi một STOP condition hoặc một REPEAT START (Rs). Nếu STOP được phát, cuộc gọi kết thúc, nếu Rs được phát, một cuộc gọi mới bắt đầu, sau Rs là địa chỉ của Slave mới…
Đó là về mặt lý thuyết, trên thực tế làm sao để kiểm tra môt START condition có được gởi chưa?
Làm sao biết có nhận được ACK sau khi phát địa chỉ hoặc dữ liệu?
Tất cả được TWI mã hóa thành các code chứa trong thanh ghi TWSR (chỉ 5 bit cao). Chúng ta chỉ thanh ghi này và đối chiếu với bảng code quy định sẵn để biết trạng thái đường truyền và đưa ra quyết định tiếp theo. Hình 2 mô tả một quá trình Master truyền dữ liệu, các khả năng có thể xảy ra và giá trị tương ứng của thanh ghi TWSR. Ý nghĩa các code trong thanh ghi TWSR trong lúc Master truyền dữ liệu có thể tham khảo thêm datasheet của chip.
Hình 3.10. Master truyền dữ liệu.
Từ hình 2, chúng ta nhận thấy khi Master truyền dữ liệu, dãy code 0x08 -> 0x18 -> 0x28 ->… -> 0x28 (-> 0x30) là dãy code thành công nhất. Code 0x08 báo rằng START codition được truyền thành công, code 0x18 báo địa chỉ truyền thành công và đã có Slave xác nhận bằng ACK, code 0x28 tức dữ liệu được Master truyền thành công và Slave đã nhận được, báo ACK lại cho Master, code 0x30 tức dữ liệu đã được truyền nhưng Slave không xác nhận lại, lúc này Master có thể phát đi một STOP codition sau code 0x30. Ngoài ra còn một số
code khác tương ứng với các trường hợp khác như gởi địa chỉ thất bại (code 0x20), Master bị lost (code 0x38)…Đối với mỗi loại ứng dụng, cách “hành xử” sẽ khác nhau đối với các trường hợp thất bại này. Trong bài báo cáo này, em sẽ bỏ qua tất cả các trường hợp thất bại, nếu một trong các code thất bại xảy ra chúng ta sẽ thoát khỏi cuộc gọi và đưa đường truyền về trạng thái nghỉ.
b. Master Receiver mode – Master nhận dữ liệu:
Hình 3.11. Master nhận dữ liệu.
Từ hình 3.11, trong quá trình Master nhận dữ liệu, dãy code 0x08 -> 0x40 -> 0x50 ->… -> 0x58 là dãy code thành công nhất. Code 0x08 báo rằng START codition được truyền thành công, code 0x40 báo địa chỉ + R đã được truyền thành công và đã có Slave xác nhận bằng ACK, code 0x50 báo dữ liệu được Master nhận thành công và Master cũng đã phát một ACK bit sau khi nhận, code
0x58 xảy ra khi Master nhận dữ liệu thành công nhưng nó không phát ACK mà phát NOT ACK, báo cho Slave rằng Master không muốn nhận thêm dữ liệu, tiếp theo Master sẽ phát một STOP condition hoặc một REPEAT START. Các trường hợp khác chúng ta không khảo sát.
b. Slave Receiver mode – Slave nhận dữ liệu:
Hình 3.12. Slave nhận dữ liệu.
Hình 3.12 mô tả một quá trình Slave nhận dữ liệu, các khả năng có thể xảy ra và giá trị code tương ứng của thanh ghi TWSR. Chế độ Slave nhận dữ liệu xảy ra khi Master thực hiện một cuộc gọi phát dữ liệu (SLA+W). Như quan sát trong hình 3.12, Slave chỉ nhận ra cuộc gọi này khi địa chỉ của nó trùng với địa chỉ của Master (Own address mode) hoặc khi Master thực hiện một cuộc gọi chung. Khi đó, bit TWINT của Slave sẽ được set lên 1. Nếu Slave cho phép ngắt
TWI (bit TWIE trong thanh ghi TWCR được set từ lúc đầu) thì một ngắt xảy ra báo có một sự kiện TWI. Nếu code trong thanh ghi TWSR là 0x60 thì một cuộc gọi địa chỉ riêng được yêu cầu và Slave cũng đã đáp ứng lại Master bằng một ACK, Slave sau đó bắt đầu nhận dữ liệu từ đường SDA. Cứ sau một byte dữ liệu Slave phải xác nhận một ACK nếu nó còn muốn tiếp tục nhận. Nếu vì một lý do nào đó mà Slave không thể tiếp tục nhận nó có thể phát một NOT ACK sau một byte dữ liệu. Cuộc gọi kết thúc khi Slave nhận được STOP condition, tương ứng code 0xA0. Cuộc gọi chung cũng diễn ra hoàn toàn tương tự cuộc gọi địa chỉ riêng nhưng code có giá trị khác. Khi viết chương trình cho Slave trong chế độ nhận dữ liệu, chúng ta cần xét cả 2 trường hợp cuộc gọi địa chỉ riêng và cuộc gọi chung.
d. Slave Transmitter mode – Slave truyền dữ liệu:
Đây là chế độ cuối cùng trong 4 chế độ của AVR TWI. Hình 3.13 mô tả một quá trình Slave truyền dữ liệu, các khả năng có thể xảy ra và giá trị code tương ứng của thanh ghi TWSR. Chế độ Slave phát dữ liệu xảy ra khi Master muốn nhận dữ liệu từ Slave, Master thực hiện một cuộc gọi nhận dữ liệu (SLA+R). Như quan sát trong hình 3.13, Slave chỉ nhận ra cuộc gọi này khi địa chỉ của nó trùng với địa chỉ của Master (Own address mode). Khi đó, bit TWINT của Slave sẽ được set lên 1. Nếu Slave đáp lại bằng một ACK ở xung nhịp thứ 9, code trong thanh ghi TWSR sẽ là 0xA8, Slave sau đó bắt đầu phát dữ liệu lên đường SDA. Cứ sau mỗi byte dữ liệu, Master sẽ xác nhận một ACK nếu nó còn muốn tiếp tục nhận, code 0xB8 sẽ xuất hiện trong trường hợp này. Nếu Master không muốn tiếp tục nhận dữ liệu từ Slave, một NOT ACK sẽ được phát và code 0xC0 xuất hiện, Slave kết thúc quá trình phát dữ liệu. Một trường hợp đặc biệt khi bit TWEA (bit ACK) trong thanh ghi TWCR của Slave được reset về 0 trước khi Slave truyền dữ liệu, trường hợp Slave muốn báo rằng nó đã hết dữ liệu để truyền, byte tiếp theo cũng là byte cuối cùng. Sau khi Master nhận byte này, nó có thể xác nhận 1 ACK cho Slave (vì thật ra Master không hề biết Slave đang truyền byte cuối), code trên Slave trong trường hợp này là 0xC8 và
Slave sẽ tự hết thúc quá trình truyền mà không cần chờ Master. Khi lập trình cho Slave trong chế độ phát, cần phải có sự “thỏa hiệp” với Master trước để tránh code 0xC8 vì code này không có nhiều ý nghĩa.
Hình 3.13. Slave truyền dữ liệu.
Kỹ thuật chính dùng cho Master khi truyền hay nhận cuộc gọi là hỏi vòng và chờ (polling and waiting). Ứng với mỗi code nhận về từ thanh ghi TWSR (hay ứng với mỗi trạng thái của cuộc gọi) mà Master set các bit tương ứng trong thanh ghi điều khiển TWCR và sau đó chờ bit TWINT được set (quá trình kết thúc) để tiếp tục đọc và xét code TWSR.
Quá trình chờ và xét này lặp lại cho đến khi Master kết thúc cuộc gọi bằng STOP condition. Tuy nhiên Slave thì khác, Slave không chủ động thực hiện cuộc gọi mà nó phải chờ yêu cầu từ Master để phục vụ. Vì thế, nếu dùng “hỏi vòng” cho Slave thì sẽ tốn thời gian chờ vô ích và đôi khi còn bỏ lỡ các cuộc gọi. Đối với Slave, ngắt là phương pháp bắt cuộc gọi tối ưu nhất. Trong bài học này, việc truyền và nhận của Slave sẽ được thực hiện trong các trình phục vụ ngắt TWI.