Khi truyền/ nhận dữ liệu nối tiếp bất đồng bộ ta phải thực hiện các công việc sau: 1. Cài đặc tốc độ baud
3. Số bit truyền nhận dữ liệu 4. Có kiểm tra chẵn lẻ hay không
5. Xác định vi điều khiền nhận/ truyền hoặc vừa nhận vừa truyền dữ liệu. 6. Xác định xem có ngắt hay không
7.3.1 Quá trình nhận dữ liệu
1. Kiểm tra cờ RX trong thanh ghi UCSRA (mục đích là để nhận biết VĐK đã nhận được dữ liệu hay chưa):
Nếu = 0 thì dữ liệu trong thanh ghi UDR (read) là trống (đã được đọc hay chưa nhận được dữ liệu kế tiếp), vì thế VĐK sẽ chờ cho đến khi bit này = 1.
Nếu = 1 thì dữ liệu trong thanh ghi UDR (read) đã có dữ liệu (có nghĩa là VĐK đã hoàn tất thủ tục nhận dữ liệu), lúc này ta có thể đọc dữ liệu từ thanh ghi UDR, sau khi đọc xong, bit này sẽ tự động = 0.
2. Kiểm tra quá trình nhận dữ liệu có lỗi hay không, có 3 vấn đề cần kiểm tra đó là:
Parity Error (PE bit – 2 trong thanh ghi UCSRA).
Data OverRun (DOR bit – 3 trong thanh ghi UCSRA).
Frame Error (FE bit – 4 trong thanh ghi UCSRA).
3. Sau đó, VĐK sẽ nhận dữ liệu từ thanh ghi UDR (read). Kết thúc quá trình nhận dữ liệu.
7.3.2 Quá trình truyền dữ liệu:
1. Kiểm tra bit UDRE xem thanh ghi UDR (write) đã sẵn sàng nhận dữ liệu hay chưa.
Nếu UDRE = 1 thì thanh ghi UDR (write) đang trống (đã truyền dữ liệu) và sẵn sàng nhận dữ liệu để truyền đi.
Nếu UDRE = 0 thì thanh ghi UDR (write) đang bận truyền dữ liệu và không nhận dữ liệu mới.
7.3.3 Các thời điểm xảy ra ngắt trong hoạt động USART
Khi hoạt động nhận hoàn thành bit cho phép ngắt RXCIE
Khi hoạt động truyền hoàn thành, bit cho phép ngắt TXCIE
Khi thanh ghi dữ liệu UDR trống, bit cho phép ngắt UDRIE
7.4 BÀI TẬP VÍ DỤ
1. Bit nào, trong thanh ghi nào qui định việc cài đặt hoạt động đồng bộ và bất đồng bộ. 2. Hãy cho biết thời điểm xảy ra hoạt động ngắt.
3. Bit nào cho biết trạng thái truyền/ nhận dữ liệu đã hoàn thành.
4. Tốc độ baud có ảnh hưởng tới quá trình đồng bộ, bất đồng bộ hay ảnh hưởng cả hai. 5. Thanh ghi nào nhận dữ liệu và thanh ghi nào truyền dữ liệu
6. Khi cài đặc giao tiếp nối tiếp không đồng bộ giữa 2 thiết bị phải cùng các thông số nào?
7. Khi truyền dữ liệu đồng bộ với IC 74HC74 thì ta phải chọn bit UCPOL bằng bao nhiêu, tại sao?
Giao tiếp giữa 2 vi điều khiển theo nghi thức giao tiếp nối tiếp CHƯƠNG TRÌNH TRUYỀN DỮ LIỆU
/*****************************************************
This program was produced by the CodeWizardAVR V2.05.0 Professional Date : 11/25/2011
Author : LÂM QUANG CHUYÊN
Chip type : ATmega16 Program type : Application AVR Core Clock frequency: 1.000000 MHz
*****************************************************/ #include <mega16.h> #ifndef RXB8 #define RXB8 1 #endif #ifndef TXB8 #define TXB8 0 #endif #ifndef UPE #define UPE 2
#endif #ifndef DOR #define DOR 3 #endif #ifndef FE #define FE 4 #endif #ifndef UDRE #define UDRE 5 #endif #ifndef RXC #define RXC 7 #endif
#define FRAMING_ERROR (1<<FE) #define PARITY_ERROR (1<<UPE) #define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE) #define RX_COMPLETE (1<<RXC)
// Write a character to the USART Transmitter
#ifndef _DEBUG_TERMINAL_IO_
#define _ALTERNATE_PUTCHAR_
#pragma used+
void putchar(char c) {
while ((UCSRA & DATA_REGISTER_EMPTY)==0);
UDR=c; }
#pragma used-
#endif
#include <stdio.h>
// Declare your global variables here
void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; MCUCR=0x00; MCUCSR=0x00;
TIMSK=0x00;
// USART initialization
// Communication Parameters: 8 Data, 2 Stop, No Parity // USART Receiver: Off
// USART Transmitter: On // USART Mode: Asynchronous // USART Baud Rate: 19200
UCSRA=0x00; UCSRB=0x08; UCSRC=0x8E; UBRRH=0x00; UBRRL=0x02; ACSR=0x80; SFIOR=0x00; ADCSRA=0x00; SPCR=0x00; TWCR=0x00; while (1) {
// Place your code here
while(PINB.7); putchar(PINA); }
}
CHƯƠNG TRÌNH TRUYỀN DỮ LIỆU
/*****************************************************
This program was produced by the CodeWizardAVR V2.05.0 Professional Date : 11/25/2011
Author : NeVaDa
Chip type : ATmega16 Program type : Application AVR Core Clock frequency: 1.000000 MHz
*****************************************************/ #include <mega16.h> #ifndef RXB8 #define RXB8 1 #endif #ifndef TXB8 #define TXB8 0 #endif #ifndef UPE #define UPE 2 #endif
#ifndef DOR #define DOR 3 #endif #ifndef FE #define FE 4 #endif #ifndef UDRE #define UDRE 5 #endif #ifndef RXC #define RXC 7 #endif
#define FRAMING_ERROR (1<<FE) #define PARITY_ERROR (1<<UPE) #define DATA_OVERRUN (1<<DOR)
#define DATA_REGISTER_EMPTY (1<<UDRE) #define RX_COMPLETE (1<<RXC)
// Get a character from the USART Receiver
#ifndef _DEBUG_TERMINAL_IO_ #define _ALTERNATE_GETCHAR_ #pragma used+
char getchar(void) {
char status,data;
while (1) {
while (((status=UCSRA) & RX_COMPLETE)==0); data=UDR;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) return data; } } #pragma used- #endif
// Standard Input/Output functions
#include <stdio.h>
// Declare your global variables here void main(void)
{
// Declare your local variables here
PORTA=0x00; DDRA=0xff; PORTB=0x00; DDRB=0x00;
PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; MCUCR=0x00; MCUCSR=0x00; TIMSK=0x00; // USART initialization
// Communication Parameters: 8 Data, 2 Stop, No Parity // USART Receiver: On
// USART Transmitter: Off // USART Mode: Asynchronous // USART Baud Rate: 19200
UCSRA=0x00; UCSRB=0x10; UCSRC=0x8E; UBRRH=0x00; UBRRL=0x02; ACSR=0x80; SFIOR=0x00; ADCSRA=0x00; SPCR=0x00; TWCR=0x00; while (1) {
// Place your code here
PORTA = getchar(); }
7.5 CÂU HỎI ÔN TẬP HẾT CHƯƠNG
1. Hãy cài đặc tốc độ baud là 9600, 8bit, no parity, 2 stop bit, fosc = 1Mhz.
2. Hãy cài đặc tốc độ baud là 19200, 5bit, parity chẵn, 1 stop bit, fosc = 3.6864 Mhz. 3. Tốc độ baud 250k, 9 bit, parity lẻ, 1 stop bit, fosc = 4 Mhz.
4. Hãy cho biết chức năng của từng thanh ghi liên quan trong hoạt động USART. 5. Viết chương trình truyền dữ liệu từ PORTB của VĐK1 sang PORTA của VĐK2, với nghi thức truyền như sau: tốc độ baud 4800, 8 bit, 2 stop bit, parity chẵn, fosc = 1 Mhz. 6. Hãy cho so sánh giữa 2 bit TXC và UDRE.
7. Hãy cho biết tốc độ truyền chậm nhất và nhanh nhất của VĐK.
8. Vẽ dạng sóng ngõ ra trên 2 chân RxD và TxD trong chế độ đồng bộ, khi truyền dữ liệu có nội dung sau: 101100011
9. Viết chương trình truyền và nhận dữ liệu từ 2 VĐK như sau:
Hình 7.10 Bài tập ví dụ giao tiếp nối tiếp
Khi nhấn nút SW1 thì VĐK1 sẽ truyền dữ liệu từ PORTB sang PORTC của VDK2. Khi nhấn nút SW2 thì VĐK2 sẽ truyền dữ liệu từ PORTB sang PORTC của VDK1.
Chương 8
GIAO TIẾP THIẾT BỊ NGOẠI VI THEO NGHI
THỨC SPI
8.1 GIỚI THIỆU 8.1.1 Giới thiệu chung
Hoạt động SPI dùng để trao đổi dữ liệu đồng bộ theo dạng nối tiếp giữa AVR với thiết bị ngoại vi hoặc giữa các AVR với nhau. Một số đặc tính của việc truyền nối tiếp như sau:
Truyền đồng bộ song công 4 dây (SCK, MOSI, MISO, SS)
Hoạt động theo dạng Master và Slaver
Truyền dữ liệu bit thấp (LSB) trước, hoặc bit cao (MSB) trước
7 tốc độ truyền dữ liệu khác nhau
Phát sinh ngắt khi quá trình truyền dữ liệu hoàn tất
Tăng gấp đôi tốc độ truyền dữ liệu
Master và Slaver có thể hoán đổi chức năng với nhau
Hình 8.1 Sơ đồ giao tiếp giữa Master và Sl ave 8.1.2 Chức năng các chân trong hoạt động SPI
8.1.2.1 Chân SCK
Chân này tạo xung clock để tạo xung nhịp truyền dữ liệu giữa Master và Slaver, xung nhịp được tạo ra bởi Master.
MOSI MISO SCK SS1 SS2 SS3 SS3 MOSI MISO SCK SS2 MOSI MISO SCK SS1 MOSI MISO SCK MASTER SLAVER 3 SLAVER 2 SLAVER 1
8.1.2.2 Chân SS (Slaver select)
Khi sử dụng SPI ở vị trí Slave thì chân SS phải được khai báo là ngõ vào, khi chân SS ở mức thấp thì thiết bị ở trạng thái hoạt động (sẵn sàng nhận dữ liệu), khi chân SS ở mức cao thì tất cả các thiết bị ngưng hoạt động, khi chân SS ở mức thấp thì các chân SPI sẽ bị reset ngay lập tức.
Khi sử dụng SPI ở vị trí là Master thì người sử dụng có thể điều khiển hướng của chân SS, khi chân này được khai báo là ngõ ra và sẽ điều khiển chân SS của Slave.
Khi chân này được khai báo là ngõ vào nó phải được kéo lên mức cao để đảm bảo hoạt động cho Master, nếu chân này bị kéo xuống mức thấp bởi tác nhân bên ngoài trong khi chân SS được khai báo là ngõ vào thì nó sẽ hiểu là đã bị Master khác đã chiếm đường truyền trên bus, để tránh điều này hệ thống SPI phải thực hiện một số thủ tục sau:
1. Bit MSTR trong thanh ghi SPCR phải được xóa và nó trở thành Slave lúc này chân MOSI và SCK phải là ngõ vào.
2. Cờ trong thanh ghi SPIR trong thanh ghi SPSR được bật lên 1, và nếu hoạt động ngắt được cho phép
8.1.2.3 Chân MOSI (Master Input / Slave Output) nếu là Master thì đây là đường Input còn nếu là chip Slave thì MISO lại là Output. MISO của Master và các Slaves Input còn nếu là chip Slave thì MISO lại là Output. MISO của Master và các Slaves được nối trực tiếp với nhau.
8.1.2.4 Chân MISO (MOSI – Master Output / Slave Input)nếu là Master thì đây là đường Output còn nếu là chip Slave thì MOSI là Input. MOSI của Master và các Slaves đường Output còn nếu là chip Slave thì MOSI là Input. MOSI của Master và các Slaves được nối trực tiếp với nhau.
8.2 CÁC THANH GHI LIÊN QUAN: SPCR, SPSR, SPDR 8.2.1 Thanh ghi SPCR 8.2.1 Thanh ghi SPCR
Bit 7 6 5 4 3 2 1 0 SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0 Read/ Write RW RW RW RW RW RW RW RW Giá trị ban đầu 0 0 0 0 0 0 0 0
Hình 8.2 Thanh ghi SPCR
Bit 7 – SPIE (SPI Interrupt Enable): Cho phép ngắt nếu bit SPIF trong thanh ghi SPSR = 1, và bit I cho phép ngắt toàn cục trong thanh ghi SREG =1.
Bit 5 – DORD (Data Order): Xác định thứ tự truyền dữ liệu, nếu DORD = 1, thì dữ liệu sẽ được truyền byte thấp trước, khi DORD = 0 thì ngược lại.
Bit 4 – MSTR (Master/Slaver Select): khi MSTR = 1 thì VĐK hoạt động như là Master, khi MSTR = 0 thi VĐK là Slave. Ngoài ra khi VĐK là Master thì khi chân SS là ngõ vào và được kéo xuống thấp thì bit MSTR sẽ bằng 0 (trở thành Slave) và bit SPIR trong thanh ghi SPSR lên 1. Nếu muốn VĐK là Master thì phải ghi bit MSTR lên 1.
Bit 3.2 – CPOL, CPHA (Clock parity, Clock phase) dùng để xác định các chế độ làm việc của SPI.
Bit 1.0 – SPR1.0 (Clock Rate Select 1 và 0) dùng để chọn tốc độ truyền dữ liệu. SPI2X SPR1 SPR0 Tần số SCK 0 0 0 fosc/4 0 0 1 fosc/16 0 1 0 fosc/64 0 1 1 fosc/128 1 0 0 fosc/2 1 0 1 fosc/8 1 1 0 fosc/32 1 1 1 fosc/64
Bảng 8.1 Mối quan hệ giữa chân sck và tần số dao động
8.2.2 Thanh ghi SPSR
Bit 7 6 5 4 3 2 1 0
SPIF WCOL - - - SPI2X SPSR Read/ Write R R R R R R R RW
Giá trị ban
đầu 0 0 0 0 0 0 0 0
Hình 8.3 Thanh ghi SPSR
Bit 7 – SPIF (SPI Interrupt Flag): Cờ ngắt trong hoạt động SPI, khi hoàn tất việc trao đổi dữ liệu thì bit SPIF sẽ bằng 1, thông báo hoạt động ngắt bắt đầu. Ngoài ra bit SPIF cũng lên 1 khi chân SS trong mode Master được kéo xuống thấp.
Bit 6 – WCOL (Write COLlision Flag): Bit WCOL =1 khi thanh ghi dữ liệu SPI (SPDR) đang nhận dữ liệu.
8.2.3 Thanh ghi SPDR Bit 7 6 5 4 3 2 1 0 Bit 7 6 5 4 3 2 1 0 MSB LSB SPDR Read/ Write RW RW RW RW RW RW RW RW Giá trị ban đầu x x x x x x x x Không xác định Hình 8.4 Thanh ghi SPDR
Đây là thanh ghi truyền nhận dữ liệu, viết dữ liệu vào thanh ghi này dùng truyền dữ liệu, đọc dữ liệu khi ở chế độ nhận.
8.3 CÁC CHẾ ĐỘ LÀM VIỆC CỦA SPI
Thời điểm lấy
mẫu Thời điểm đỗi dữ liệu Giá trị ban đầu Chế độ SPI CPOL = 0, CPHA = 0 Cạnh lên Cạnh xuống Mức thấp 0 CPOL = 0, CPHA = 1 Cạnh xuống Cạnh lên Mức thấp 1 CPOL = 1, CPHA = 0 Cạnh xuống Cạnh lên Mức cao 2 CPOL = 1, CPHA = 1 Cạnh lên Cạnh xuống Mức cao 3
Bảng 8.2 Các thời điểm lấy mẫu nhận dữ liệu
Hình 8.6 Thời điểm lấy mẫu khi bit CPHA = 1 8.4 BÀI TẬP VÍ DỤ
Viết chương trình giao tiếp giữa 1 Master và 2 Slaver, theo yêu cầu sau:
Khi nhấn nút 1 thì Master sẽ gởi dữ liệu từ PORTA đến Slaver 1, nút 2 thì Master gởi dữ liệu từ PORTA đến Slaver 2.
Phân tích: Các bước thực hiện Chọn Master và Slaver
Chọn tốc độ truyền dữ liệu Xác định ngắt/ không ngắt
Xác định kiểu truyền dữ liệu (LSB trước hay MSB trước) Chọn mode hoạt động 0,1,2,3
Chương trình cho Master:
/*****************************************************
This program was produced by the CodeWizardAVR V2.05.0 Advanced
Date : 28/01/2012
Company : TRƯỜNG CAO ĐẲNG CÔNG THƯƠNG TP.HCM Chip type : ATmega16
Program type : Application AVR Core Clock frequency: 1,000000 MHz
*****************************************************/
// SPI functions
#include <spi.h>
// Declare your global variables here
void main(void) { // Port A initialization PORTA=0xff; DDRA=0x00; // Port B initialization PORTB=0x07; DDRB=0xB0; // Port C initialization PORTC=0x00; DDRC=0x00; // Port D initialization PORTD=0x00; DDRD=0x00;
// Analog Comparator initialization // Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80; SFIOR=0x00;
// SPI initialization // SPI Type: Master
// SPI Clock Rate: 250,000 kHz // SPI Clock Phase: Cycle Start // SPI Clock Polarity: Low
// SPI Data Order: LSB First
SPCR=0x70; SPSR=0x00; // TWI initialization // TWI disabled TWCR=0x00; while (1) {
// Place your code here
while(PINB.2); spi(PINA); }
Chương trình cho Slave
/***************************************************** This program was produced by the CodeWizardAVR V2.05.0 Date : 28/01/2012
Company : TRƯỜNG CAO ĐẲNG CÔNG THƯƠNG TP.HCM Chip type : ATmega16
AVR Core Clock frequency: 1,000000 MHz
*****************************************************/
#include <mega16.h>
// SPI functions
#include <spi.h> void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0x40; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0xFF;
// Analog Comparator initialization
ACSR=0x80; SFIOR=0x00;
// SPI initialization // SPI Type: Slave
// SPI Clock Phase: Cycle Start // SPI Clock Polarity: Low
// SPI Data Order: LSB First
SPCR=0x60; SPSR=0x00; while (1) {
// Place your code here
PORTD = SPDR; SPSR.7 = 1; }
8.5 CÂU HỎI ÔN TẬP HẾT CHƯƠNG
Câu 1: Chân SS là ngõ vào hay ngõ ra đối với Master và Slaver Câu 2: Chân SS của Slaver phải luôn ở mức cao hay mức thấp
Câu 3: Hãy cài đặc vi điều khiển ở chế độ Master, tần số xung SCK = 62,500Khz, mức logic của chân SCK ban đầu bằng 1, thời điểm lấy mẫu cạnh lên của xung clock, truyền LSB trước, biết tần số thạch anh là 4Mhz.
Chương 9
GIAO TIẾP THIẾT BỊ THEO NGHI THỨC I2C
9.1. GIỚI THIỆU:
Là hoạt động truyền dữ liệu dạng nối tiếp có định địa chỉ, hỗ trợ cả Master và Slave, hoạt động I2C sử dụng 2 chân giao tiếp SDA và SCL, hoạt động I2C có thể truy cập tới từng ô nhớ của thiết bị.
Hình 9.1 Hình vẽ giao tiếp theo nghi thức I2C 9.1.1 Đặc tính
Đơn giản, dễ giao tiếp và sử dụng chỉ với 2 dây
Tốc độ truyền 400Khz
Hổ trợ cho cả 2 hoạt động Master và Slave có thể hoán đổi vị trí cho nhau.
Có thể hoạt động như bộ truyền/ nhận dữ liệu
Có thể phân chia đến 128 địa chỉ khác nhau cho Slave
Hổ trợ nhiều Master kiểm soát đường truyền
2 chân giao tiếp SDA (PC1,23) và SCL (PC0,22) 9.1.2 Thuật ngữ:
SDA: Serial Data dữ liệu đường nối tiếp
9.2 NGUYÊN LÝ HOẠT ĐỘNG GIAO TIẾP I2C
Hoạt động I2C bắt đầu bằng 1 start bit và kết thúc bằng 1 Stop bit, gói dữ liệu là 8 bit và xen giữa là bit ACK,
Định dạng gói địa chỉ
Hình 9.2 Định dạng truyền dữ liệu theo nghi thức I2C
Để bắt đầu bằng 1 start bit chân SDA sẽ từ mức cao xuống mức thấp, trong khi Stop bit chân SDA sẽ từ mức thấp chuyển lên mức cao trong cả 2 trường hợp này chân SCL đều ở mức cao,
Hình 9.3 Định dạng Stop bit và Start bit
Việc chuyển đổi dữ liệu giữa các bit được thực hiện tại mức thấp của chân SCL,
Hình 9.4 Chuyển đổi dữ liệu tại mức thấp của chân SCL