You are on page 1of 88

CHƯƠNG 8

CỔNG NỐI TIẾP

Giáo Trình Vi xử lý Chương 8 Lưu Phú 1


 Tóm tắt:
8.1 Giới thiệu chung
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.1 Nguyên lý hoạt động
8.2.2 Các thanh ghi sử dụng trong mode UART
8.2.3 Khởi động mode UART
8.2.4 Phát data
8.2.5 Thu data
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.1 Giới thiệu
8.3.2 Các thanh ghi sử dụng trong mode SPI
8.3.3 Chức năng chân /SS
8.3.4 Mode data
8.3.5 Lập trình truyền SPI
8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
8.4.2 Các thanh ghi sử dụng TWI
8.4.3 Lập trình các mode TWI 2
Giáo Trình Vi xử lý Chương 8 Lưu Phú
8.1 Giới thiệu chung
• Các giao thức truyền data nối tiếp hiện nay thường theo các định dạng thông dụng như sau:
1. Truyền bất đồng bộ-UART(Universal Asynchronous Receiver Transmitter)
2. Truyền đồng bộ- USRT(Universal Synchronous Receiver Transmitter)
3. Truyền SPI(Serial Peripheral Interface)
4. Truyền I2C(Inter-Integrated Circuit)
• MCU324P có cấu hình phần cứng onchip các port giao tiếp nối tiếp:
- USART0,USART1: 2 port có định dạng giao thức UART,USRT,SPI master(MSPIM)
- SPI: 1 port có định dạng mode Master/Slave
- TWI(Two Wired serial Interface): 1 port tương thích I2C mode Master/Slave phát/thu

Giáo Trình Vi xử lý Chương 8 Lưu Phú 3


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.1 Nguyên lý hoạt động
• Định dạng một khung(frame)truyền UART

Hình 8.1

- Đầu tiên luôn luôn là 1 start bit=0


- Kế tiếp là các bit data có thể từ 5-9 bit,LSB truyền trước
- Kết thúc luôn luôn là stop bit=1,có thể 1 hoặc 2 stop bit
• Tốc độ truyền tính bằng baudrate(BR)hay bitrate(bps:bit/s)
Thông dụng BR=bitrate=1/Tb,Tb=độ rộng 1 bit
Ví dụ các BR thông dụng(bps)=1200,2400,9600,19.2K,38.4K,57.6K,115.2K…

Giáo Trình Vi xử lý Chương 8 Lưu Phú 4


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.1 Nguyên lý hoạt động
• MCU324P có cấu hình 2 cổng USART0 và USART1 hoạt động tương tự nhau,ký hiệu chung
là USARTn,với n=0,1,có khả năng làm việc ở các mode UART,UART đa xử lý
(multiprocessor communication),USRT,mode SPI master(MSPIM)
• USART0: RXD0≡PD0,TXD0≡PD1
• USART1: RXD1≡PD2,TXD1≡PD3
• Hoạt động sơ đồ khối USART xem chi tiết trong giáo trình và datasheet
• Chỉ khảo sát mode UART,các mode đa xử lý,USRT,MSPIM với cổng USART xem chi tiết
trong giáo trình và datasheet
• Cấu hình USART mode UART:
- Lập trình được BR
- Cài đặt khung truyền từ 5-9 bit,1-2 stop bit,parity chẵn/lẻ
- Theo dõi và điều khiển trạng thái truyền data
- Truyền song công(full duplex) : hai chân phát TXDn và thu RXDn riêng,hai bộ đệm
phát/thu độc lập có cùng ký hiệu UDRn
- Cho phép ngắt phát/thu nối tiếp độc lập
Giáo Trình Vi xử lý Chương 8 Lưu Phú 5
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.1 Nguyên lý hoạt động
• Tóm tắt các thanh ghi sử dụng trong mode UART
Bảng 8.1: Các thanh ghi sử dụng UART
Địa chỉ MEM Ký hiệu Truy xuất bit Chức năng

0xC0 UCSR0A Có Cờ báo trạng thái UART


0xC1 USCR0B Có Điều khiển trạng thái UART
USART0
0xC2 UCSR0C Có Cài đặt định dạng truyền UART
0xC4 UBRR0L Không Cài đặt baudrate byte thấp
0xC5 UBRR0H Không Cài đặt baudrate byte cao
0xC6 UDR0 Không Đệm data phát/thu nối tiếp
0xC8 UCSR1A Có Cờ báo trạng thái UART
0xC9 USCR1B Có Điều khiển trạng thái UART
0xCA UCSR1C Có Cài đặt định dạng truyền UART
USART1
0xCC UBRR1L Không Cài đặt baudrate byte thấp
0xCD UBRR1H Không Cài đặt baudrate byte cao
0xCE UDR1 Không Đệm data phát/thu nối tiếp

 Lưu ý: Các thanh ghi mode UART đều nằm trong vùng I/O mở rộng nên khi truy xuất phải
sử dụng các lệnh LDS,STS.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 6
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
1. UBRRnH/UBRRnL- USART Baurate Registers

Hình 8.2

 Bit 15-12: dự trữ chưa sử dụng,khi ghi phải xóa các bit này=0
 Bit 11-8: 4 bit thấp của UBRRnH cài đặt BR
 Bit 7-0: 8 bit của UBRRnL cài đặt BR
 Khi ghi vào UBRRn phải tuân theo nguyên tắc ghi UBRRnH trước và UBRRnL sau
 Bộ chia đặt trước BR sẽ cập nhật ngay sau khi ghi UBRRnL

Giáo Trình Vi xử lý Chương 8 Lưu Phú 7


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
1. UBRRnH/UBRRnL- USART Baudrate Registers
 Công thức tính BR: Ví dụ 8.1: Tính giá trị nạp UBRRn để tạo
BR=9600,với U2Xn=0,Fosc=8Mhz.Tính sai số?
𝐹𝑜𝑠𝑐 × 2𝑈2𝑋𝑛
𝐵𝑅 = (8.1𝑎) Giải:
16(𝑋 + 1) Theo(8.1b):
8000 × 1
𝑋= − 1 = 51.083
𝐹𝑜𝑠𝑐 × 2𝑈2𝑋𝑛 16 × 9.6
𝑋= − 1 (8.1𝑏) Nạp UBRRn=51(số nguyên)
16 × 𝐵𝑅 Giá trị BR tính theo(8.1a):
8000
𝐵𝑅 𝑡í𝑛ℎ = = 9615
𝐵𝑅 𝑡í𝑛ℎ 16 × 52
𝐸𝑟𝑟𝑜𝑟 % = − 1 × 100 (8.1𝑐) Sai số theo(8.1c):
𝐵𝑅 𝑐ℎ𝑢ẩ𝑛 9615
X=UBRRn 𝐸𝑟𝑟𝑜𝑟 % = − 1 × 100 = 0.16%
9600
U2Xn =0/1(thuộc reg. UCSRnA)  Thực tế sai số cho phép <2%

Giáo Trình Vi xử lý Chương 8 Lưu Phú 8


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
1. UBRRnH/UBRRnL- USART Baudrate Registers
Bảng 8.2: Tóm tắt một số giá trị BR,giá trị nạp UBRRn,sai số,theo U2Xn và Fosc
Fosc=1Mhz Fosc=8Mhz Fosc=7.3728Mhz

BR(kbps) U2Xn=0 U2Xn=1 U2Xn=0 U2Xn=1 U2Xn=0 U2Xn=1


Error Error Error Error Error Error
UBRRn UBRRn UBRRn UBRRn UBRRn UBRRn
(%) (%) (%) (%) (%) (%)
1.2 51 0.2 103 0.2 416 -0.1 832 0 383 0 767 0
2.4 25 0.2 51 0.2 207 0.2 416 -0.1 191 0 383 0
9.6 6 -7 12 0.2 51 0.2 103 0.2 47 0 95 0
19.2 2 8.5 6 -7 25 0.2 51 0.2 23 0 47 0
38.4 - - 2 8.5 12 0.2 25 0.2 11 0 23 0
57.6 - - 1 8.5 8 -3.5 16 2.1 7 0 15 0
115.2 - - - - 3 8.5 8 -3.5 3 0 7 0

Giáo Trình Vi xử lý Chương 8 Lưu Phú 9


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
2. UDRn - USART I/O Data Register n

Hình 8.3

 Thanh ghi đệm phát/thu nối tiếp 8 bit có cùng ký hiệu UDRn và địa chỉ,nhưng hoạt động
độc lập.
 Trường hợp khung truyền 5-7 bit,bộ phát sẽ loại bỏ các bit cao không sử dụng,bộ thu sẽ
xóa các bit này=0
 Data ghi vào UDRn sẽ được chuyển đến thanh ghi dịch phát(TXB) để phát nối tiếp ra chân
TXDn.Cờ báo UDREn=1(phần cứng đặt)khi bộ đệm phát UDRn trống sẵn sàng nhận data
phát.
 Đọc data từ UDRn trả về từ thanh ghi dịch thu(RXB) nối tiếp từ chân RXDn.Cờ báo
RXCn=1(phần cứng đặt)khi bộ đệm thu UDRn đầy hay thu đủ ký tự khung truyền.
 Lưu ý: Bộ đệm thu là FIFO 2 cấp,sẽ đổi trạng thái khi bị truy xuất →không sử dụng các
lệnh đọc có ghi hiệu chỉnh như SBI,CBI hay SBIS,SBIC sẽ làm thay đổi trạng thái các FIFO!
Giáo Trình Vi xử lý Chương 8 Lưu Phú 10
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
3. UCSRnA - USART Control and Status Register A

Hình 8.4

 Bit 7 – RXCn: USART Receive Complete(Cờ báo thu xong)


- Phần cứng đặt RXCn=1 khi UDRn thu đầy và chưa được đọc
- Khi đọc UDRn xong,phần cứng xóa UDRn và RXCn=0
- Khi cấm thu (RXENn=0)bộ đệm thu bị cách ly và RXCn=0
- RXCn=1 tạo ngắt thu nối tiếp nếu cho phép ngắt này hoạt động
 Bit 6 – TXCn: USART Transmit Complete(Cờ báo phát xong)
- Phần cứng đặt TXCn=1 khi thanh ghi dịch phát nối tiếp(TXB) đã phát xong data và UDRn
phát trống.
- Cờ TXCn =1 tạo ngắt phát nối tiếp nếu cho phép ngắt này hoạt động,sẽ được xóa bằng
phần cứng khi MCU chuyển đến vector ngắt tương ứng,hoặc phải xóa bằng phần mềm
bằng cách ghi 1 vào vị trí cờGiáo
này.
Trình Vi xử lý Chương 8 Lưu Phú 11
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
3. UCSRnA - USART Control and Status Register A
 Bit 5 – UDREn: USART Data Register Empty(Cờ báo bộ đệm phát trống)
- Phần cứng đặt cờ UDREn=1 khi UDRn phát trống sẵn sàng nhận data mới để phát
- Khi ghi data vào UDRn phát,phần cứng sẽ xóa cờ UDREn
- Cờ UDREn=1 tạo ngắt bộ đệm phát trống nếu cho phép ngắt này hoạt động
- Khi mới reset khởi động cờ UDREn=1 báo UDRn phát trống
 Bit 4 – FEn: Frame Error(Lỗi khung truyền)
- FEn=1 khi ký tự kế tiếp thu được bị lỗi,cụ thể là stop bit đầu tiên=0
- Bit này vẫn giữ nguyên giá trị cho đến khi đọc UDRn
- FEn=0 khi thu được stop bit=1
- Khi ghi vào UCSRnA phải xóa FEn=0
 Bit 3 – DORn: Data Over Run(Báo tràn data)
- DORn=1 khi UDRn thu đầy,có data đang chờ trong thanh ghi dịch thu(RXB) và nhận
được xung Start mới.
- Bit này vẫn giữ nguyên giá trị cho đến khi đọc UDRn
- Khi ghi vào UCSRnA phải xóa DORn=0
Giáo Trình Vi xử lý Chương 8 Lưu Phú 12
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
3. UCSRnA - USART Control and Status Register A
 Bit 2 – UPEn: USART Parity Error(Lỗi kiểm tra chẵn/lẻ parity)
- UPEn=1 nếu ký tự thu kế tiếp bị lỗi parity khi thu với điều kiện đã đặt bit cho phép kiểm
tra parity UPMn1=1
- Bit này vẫn giữ nguyên giá trị cho đến khi đọc UDRn
- Khi ghi vào UCSRnA phải xóa UPEn=0
 Bit 1 – U2Xn: Double the USART Transmission Speed(x2 tốc độ truyền)
- Đặt U2Xn=1 bằng phần mềm nhân 2 BR
- Chỉ hoạt động mode UART,USRT
- Mode MSPIM xóa U2Xn=0(U2Xn không ảnh hưởng)
 Bit 0 – MPCMn: Multi Processor Communication Mode
- Đặt MPCMn=1 bằng phần mềm cho phép truyền thông đa xử lý(xem thêm trong giáo trình
và data sheet)

Giáo Trình Vi xử lý Chương 8 Lưu Phú 13


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
4. UCSRnB - USART Control and Status Register B

Hình 8.5

 Bit 7 – RXCIEn: RX Complete Interrupt Enable


- Đặt RXCIEn=1 và I=1(I thuộc SREG) cho phép ngắt thu nối tiếp khi cờ RXCn=1
 Bit 6 – TXCIEn: TX Complete Interrupt Enable
- Đặt TXCIEn=1 và I=1(I thuộc SREG) cho phép ngắt phát nối tiếp khi cờ TXCn=1
 Bit 5 – UDRIEn: USART Data Register Empty Interrupt Enable
- Đặt UDRIEn=1 và I=1(I thuộc SREG) cho phép ngắt UDRn phát trống khi cờ UDREn=1
 Bit 4 – RXENn: Receiver Enable
- Đặt RXENn=1 cho phép thu nối tiếp
 Bit 3 – TXENn: Transmitter Enable
- Đặt TXENn=1 cho phép phát nối tiếp
Giáo Trình Vi xử lý Chương 8 Lưu Phú 14
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
4. UCSRnB - USART Control and Status Register B
 Bit 2 – UCSZn2: Character Size
- UCSZn2 kết hợp với các bit UCSZn1:0 thuộc reg. UCSRnC đặt số bit truyền trong khung
(xem reg. UCSRnC)
 Bit 1 – RXBn8: Receive Data Bit 8
- Bit thu thứ 9 (bit D8) trong truyền data 9 bit
 Phải đọc RXB8n trước khi đọc UDRn
 Bit 0 - TXBn8: Transmit Data Bit 8
- Bit phát thứ 9 (bit D8) trong truyền data 9 bit
 Phải ghi TXB8n trước khi ghi UDRn

Giáo Trình Vi xử lý Chương 8 Lưu Phú 15


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
5. UCSRnC - USART Control and Status Register C

Hình 8.6

 Bit 7:6 – UMSELn1:0 : USART Mode Select


- Chọn mode làm việc USART
Bảng 8.3: Cài đặt các mode làm việc USARTn
UMSELn1 UMSELn0 Mode
0 0 UART
0 1 USRT
1 0 Dự trữ
1 1 MSPIM

Giáo Trình Vi xử lý Chương 8 Lưu Phú 16


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART
5. UCSRnC - USART Control and Status Register C
 Bit 5:4 – UPMn1:0 : Parity Mode
- Cho phép và đặt việc phát và kiểm tra parity
- Bit parity đặt giữa MSB và stop bit đầu tiên
- Bộ phát tự động phát và gửi parity của khung truyền data
- Bộ thu sẽ tự tính giá trị parity và so sánh với parity thu từ khung truyền
- Nếu sai parity cờ UPEn=1(reg. UCSRnA)
Bảng 8.4: Cài đặt các mode parity
UPMn1 UPMn0 Mode Parity
0 0 Cấm(không k/tra parity)
0 1 Dự trữ
1 0 Cho phép,parity chẵn
1 1 Cho phép,parity lẻ

Giáo Trình Vi xử lý Chương 8 Lưu Phú 17


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.2 Các thanh ghi sử dụng trong mode UART Bảng 8.5: Cài đặt số bit trong khung truyền
5. UCSRnC - USART Control and Status Register C UCSZn2 UCSZn1 UCSZn0 Số bit
 Bit 3 – USBSn : Stop Bit Select 0 0 0 5
USBSn Stop bit 0 0 1 6
0 1 0 1 0 7
1 2 0 1 1 8
 Bit 2:1 – UCSZn1:0 : Character Size 1 0 0 Dự trữ
- Kết hợp với bit UCSZn2(reg. UCSRnB) 1 0 1 Dự trữ
đặt số bit trong khung truyền 1 1 0 Dự trữ
 Bit 0 – UCPOLn: Clock Polarity 1 1 1 9
- Chỉ sử dụng mode USRT,mode UART xóa UCPOLn=0
- Đặt cạnh thay đổi/lấy mẫu data out/in của xung XCKn
UCPOLn Data thay đổi(TXD) Lấy mẫu data(RXD)
0 ↑ XCKn ↓ XCKn
1 ↓ XCKn ↑ XCKn
Giáo Trình Vi xử lý Chương 8 Lưu Phú 18
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.3 Khởi động mode UART LDI R16,HIGH(X)
1. Thiết lập BR 𝐹𝑜𝑠𝑐 × 2𝑈2𝑋𝑛 STS UBRRnH,R16
𝑋= − 1 (8.1𝑏) LDI
- Tính X theo(8.1b): 16 × 𝐵𝑅 R16,LOW(X)
- Nạp UBRRn=X(nguyên) U2Xn thuộc reg, UCSRnA STS UBRRnL,R16
- Trường hợp cần x2 BR đặt bit U2Xn=1:
Ví dụ: LDI R16,(1<<U2Xn)
STS UCSRnA,R16
2. Cho phép phát/thu ,định dạng khung(frame)truyền qua bit UCSZn2
Ví dụ cho phép phát và thu,khung truyền 8 bit data: RXENn=1,TXENn=1,UCSZn2=0
LDI R16,(1<<RXENn)|(1<<TXENn)
STS UCSRnB,R16
3. Chọn mode và khung truyền gồm số bit data,số stop bit,parity
Ví dụ mode UART,8 bit data,1 stop bit,không parity: UMSELn1:0=00,UPMn1:0=00,
USBSn=0,UCSZn1:0=11
LDI R16,(1<<UCSZn0)|(1<<UCSZn1);hay (3<<UCSZn0)
STS UCSRnC,R16
 n=0 USART0,n=1 USART1
Giáo Trình Vi xử lý Chương 8 Lưu Phú 19
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.3 Khởi động mode UART
Ví dụ 8.2: Viết đoạn chương trình khởi động USART0 mode UART phát/thu,BR=9600,
U2X0=1, 8 bit data, 1 stop bit,không parity.Cho Fosc=8Mhz.
Giải:
LDI R16,0 ;BR=9600,UBRR0=103,U2X0=1
STS UBRR0H,R16
LDI R16,103
STS UBRR0L,R16
LDI R16,(1<<U2X0) ;x2 BR
STS UCSR0A,R16
LDI R16,(1<<RXEN0)|(1<<TXEN0);cho phép phát/thu,8 bit data
STS UCSR0B,R16
LDI R16,(3<<UCSZ00);UART 8 bit,1 stop bit,không parity
STS UCSR0C,R16

Giáo Trình Vi xử lý Chương 8 Lưu Phú 20


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.4 Phát data
1. Phát data 5-8 bit
- Kiểm tra cờ UDREn=1 báo UDRn phát trống,ghi data ra UDRn
- Trường hợp khung truyền data < 8 bit,bộ phát loại bỏ các bit cao
 Cờ UDREn=0(phần cứng xóa) khi ghi data ra UDRn
Ví dụ 8.3: Viết một CTC phát data 8 bit sau khi khởi động USART0 theo ví dụ 8.2 ở trên.
Giải:
;Input R17 cất data cần phát
TRANS_CHR:
LDS R16,UCSR0A ;đọc cờ UDRE0
SBRS R16,UDRE0 ;UDRE0=1 sẵn sàng phát
RJMP TRANS_CHR ;chờ cờ UDRE0=1
STS UDR0,R17 ;phát data cất trong R17
RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 21


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.4 Phát data
2. Phát data 9 bit
- Tương tự như phát data 5-8 bit nhưng phải ghi bit thứ 9 vào TXB8n(reg. UCSRnB) trước
khi ghi vào UDRn
Ví dụ 8.4: Viết một CTC phát data 9 bit sau khi khởi động USART0 thích hợp,với bit data
thứ 9=cờ T.
Giải:
;Input R17 cất 8 bit data cần phát,T=bit data thứ 9
TRANS_CHR9:
LDS R16,UCSR0A ;đọc cờ UDRE0
SBRS R16,UDRE0 ;UDRE0=1 sẵn sàng phát
RJMP TRANS_CHR9 ;chờ cờ UDRE0=1
LDS R16,UCSR0B ;đọc UCSR0B
BLD R16,TXB80 ;nạp bit thứ 9 từ T vào vị trí bit TXB80
STS UCSR0B,R16 ;nạp bit thứ 9 vào bit TXB80
STS UDR0,R17 ;phát 8 bit data cất trong R17
RET
Giáo Trình Vi xử lý Chương 8 Lưu Phú 22
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.4 Phát data
3. Cờ báo UDREn và TXCn
- Cờ báo UDREn=1 đặt bằng phần cứng chỉ báo bộ đệm phát UDRn trống sẵn sàng nhận
data phát.Cờ UDREn được xóa=0 bằng phần cứng khi ghi data ra UDRn
- Cờ báo UDREn=1 chính là tín hiệu báo ngắt bộ đệm phát trống nếu đặt UDRIEn=1
(reg. UCSRnB) và I=1(reg. SREG)
- Cờ báo TXCn=1 đặt bằng phần cứng chỉ báo thanh ghi dịch phát nối tiếp(TXB)đã dịch hết
data ra ngoài chân TXDn và bộ đệm phát UDRn trống.
- Cờ báo TXCn=1 chính là tín hiệu báo ngắt phát nối tiếp xong nếu đặt TXCIEn=1
(reg.UCSRnB) và I=1(reg. SREG)
- Cờ TXCn được xóa=0 bằng phần cứng khi MCU chuyển điều khiển đến vector ngắt nếu có
khai báo ngắt phát nối tiếp,hoặc phải xóa bằng phần mềm bằng cách ghi 1 vào bit cờ này.
 Cờ TXCn sử dụng thích hợp trong mode truyền bán song công như RS485,kiểm tra cờ
TXCn bảo đảm data được truyền hết ra chân TXDn và bộ đệm phát UDRn trống!
Giáo Trình Vi xử lý Chương 8 Lưu Phú 23
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.4 Phát data
4. Phát parity
- Cài đặt UPMn1:0 thuộc reg. UCSRnC
- UPMn1:0=10 : phát parity chẵn
𝑃even = 𝑑𝑚−1 ⊕ 𝑑𝑚−2 ⊕ ⋯ ⨁𝑑1 ⨁𝑑0 ⨁0 (8.2)
Bit Peven=1 nếu tổng số bit 1 của data bit là số lẻ và ngược lại
- UPMn1:0=11: phát parity lẻ
𝑃odd = 𝑑𝑚−1 ⊕ 𝑑𝑚−2 ⊕ ⋯ ⨁𝑑1 ⨁𝑑0 ⨁1 (8.3)
Bit Podd=1 nếu tổng số bit 1 của data bit là số chẵn và ngược lại
5. Cho phép/cấm phát
- Cài đặt bit TXENn thuộc reg, UCSRnB
- TXENn=1 cho phép phát nối tiếp
- TXENn=0 cấm phát nối tiếp.UART chỉ dừng phát khi thanh ghi dịch phát(TXB) và bộ
đệm phát UDRn trống.

Giáo Trình Vi xử lý Chương 8 Lưu Phú 24


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.4 Phát data
Ví dụ 8.5: Viết một chương trình liên tục phát data $AA ra USART0,mode UART 8 bit,
BR=9600, 1 stop bit,không parity,cho Fosc=8Mhz.
Giải:
.ORG 0 LDI R16,(3<<UCSZ00); UART 8 bit,1 stop bit,
RJMP MAIN STS UCSR0C,R16 ; không parity
.ORG 0X40 START: LDI R17,$AA ;nạp data phát vào R17
MAIN: LDI R16,HIGH(RAMEND) RCALL TRANS_CHR ;gọi ctc phát data nối tiếp
OUT SPH,R16 RJMP START
LDI R16,LOW(RAMEND) ;-----------------------------------------------------------------------
OUT SPL,R16 ;CTC TRANS_CHR phát data ra UART0
LDI R16,0 ;BR=9600,UBRR0=103,U2X0=1 ;Input R17 cất data cần phát
STS UBRR0H,R16 ;-----------------------------------------------------------------------
LDI R16,103 TRANS_CHR: LDS R16,UCSR0A ;đọc cờ UDRE0
STS UBRR0L,R16 SBRS R16,UDRE0 ;UDRE0=1 sẵn sàng phát
LDI R16,(1<<U2X0) ;x2 BR RJMP TRANS_CHR ;chờ cờ UDRE0=1
STS UCSR0A,R16 STS UDR0,R17 ;phát data cất trong R17
LDI R16,(1<<TXEN0);cho phép phát,8 bit data RET
STS UCSR0B,R16

Giáo Trình Vi xử lý Chương 8 Lưu Phú 25


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.4 Phát data
Ví dụ 8.6: Viết một chương trình liên tục phát chuỗi ký tự cất trong Flash ROM kết thúc bằng
mã Null=$00 ra USART1,mode UART 8 bit,BR=19200,1 stop bit,parity lẻ,cho Fosc=8Mhz.
Giải:
.ORG 0 START: LDI ZH,HIGH(MSG<<1);Z trỏ bảng tra MSG
RJMP MAIN LDI ZL,LOW(MSG<<1) ;trong Flash ROM
.ORG 0X40 NEXT: LPM R17,Z+ ;lấy ký tự MSG,Z+1
MAIN: LDI R16,HIGH(RAMEND) RCALL TRANS_CHR; gọi ctc phát data nối tiếp
OUT SPH,R16 CPI R17,0 ;ký tự Null ?
LDI R16,LOW(RAMEND) BRNE NEXT ;khác,phát tiếp
OUT SPL,R16 RJMP START ;lặp vòng lại từ đầu
LDI R16,0 ;BR=19200,UBRR1=51,U2X1=1 ;-----------------------------------------------------------------------
STS UBRR1H,R16 ;CTC TRANS_CHR phát data ra UART1
LDI R16,51 ;Input R17 cất data cần phát
STS UBRR1L,R16 ;-----------------------------------------------------------------------
LDI R16,(1<<U2X1) ;x2 BR TRANS_CHR: LDS R16,UCSR1A ;đọc cờ UDRE1
STS UCSR1A,R16 SBRS R16,UDRE1 ;UDRE1=1 sẵn sàng phát
LDI R16,(1<<TXEN1);cho phép phát,8 bit data
RJMP TRANS_CHR ;chờ cờ UDRE1=1
STS UCSR1B,R16
STS UDR1,R17 ;phát data cất trong R17
LDI R16,(3<<UCSZ10)|(3<<UPM10)
;UART 8 bit,1 stop bit, parity lẻ RET
STS UCSR1C,R16 MSG: .DB "Phat UART1! ",$00

Giáo Trình Vi xử lý Chương 8 Lưu Phú 26


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
• Bộ thu được thiết lập BR,định dạng khung truyền gồm số data bit,stop bit,parity giống như
bộ phát.
• Cài đặt bit RXENn=1/0: cho phép/cấm thu(reg. UCSRnB)
1. Thu data 5-8 bit
- Chờ cờ RXCn=1 báo bộ đệm thu đầy,đọc data từ UDRn
- Nếu data <8 bit ,các bit cao=0
 Khi đọc data từ UDRn,phần cứng xóa cờ UDRn=0
Ví dụ 8.7: Viết một CTC thu data từ USART0,giả sử đã cài đặt mode UART thích hợp.
Giải:
;Output R17 chứa data thu
REC_CHR: LDS R16,UCSR0A ;đọc cờ RXC0
SBRS R16,RXC0 ;cờ RXC0=1 đọc data
RJMP REC_CHR ;chờ cờ RXC0=1
LDS R17,UDR0 ;đọc data cất vào R17
RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 27


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
2. Thu data 9 bit
- Tương tự như thu data 5-8 bit
- Bit thu thứ 9 được cất vào RXB8n thuộc reg. UCSRnB
- Phải đọc bit thứ 9 trước khi đọc data từ UDRn
Ví dụ 8.8: Viết một CTC thu data 9 bit từ USART0,giả sử đã cài đặt mode UART thích hợp.
Giải:
;Output R17 chứa 8 bit data thu,T chứa bit thứ 9
REC_CHR9: LDS R16,UCSR0A ;đọc cờ RXC0
SBRS R16,RXC0 ;cờ RXC0=1 đọc data
RJMP REC_CHR9 ;chờ cờ RXC0=1
LDS R17,UCSR0B ;đọc UCSR0B
BST R17,RXB80 ;cất TXB80 vào T
LDS R17,UDR0 ;đọc data cất vào R17
RET
Giáo Trình Vi xử lý Chương 8 Lưu Phú 28
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
3. Cờ báo RXCn
- Cờ RXCn=1 khi bộ đệm thu đầy,nghĩa là thu đủ số bit theo định dạng khung truyền và
chưa được đọc.
- Cờ RXCn=0 xóa bằng phần cứng khi đọc bộ đệm thu UDRn,bộ đệm thu UDRn trống,hoặc
cấm thu(REXNn=0)
- Cờ RXCn=1 cũng báo ngắt thu nối tiếp xong,nếu khai báo RXCIEn=1(reg.UCSRnB) và
I=1(reg. SREG)
 Lưu ý: cờ RXCn=0 chỉ khi đọc UDRn!
4. Kiểm tra lỗi
- Lỗi khung truyền : bit FEn=1(reg.UCSRnA)
- Lỗi tràn data thu: bit DORn=1(reg.UCSRnA)
- Lỗi parity: bit UPEn=1(reg.UCSRnA)
- Các bit này được xóa=0 khi đọc bộ đệm thu UDRn
 Lưu ý: Phải đọc các bit này trước khi đọc bộ đệm thu UDRn
Giáo Trình Vi xử lý Chương 8 Lưu Phú 29
8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
Ví dụ 8.9: Viết một CTC thu data 8 bit từ USART0,giả sử đã khởi động USART0 thích hợp.
Nếu không báo lỗi,trả về R17 chứa byte data thu và cờ C=0,nếu có lỗi R17=$FF và cờ C=1.
Giải:
REC_CHR_E: LDS R16,UCSR0A ;đọc UCSR0A
SBRS R16,RXC0 ;cờ RXC0=1,thu data
RJMP REC_CHR_E ;chờ cờ RXC0=1
ANDI R16,(1<<FE0)|(1<<DOR0)|(1<<UPE0);kiểm tra báo lỗi
BRNE REC_ERR ;khác 0,báo lỗi
LDS R17,UDR0 ;không lỗi, thu data
CLC ;xóa C=0
RJMP EXIT_REC ;thoát
REC_ERR: LDI R17,$FF ;có lỗi R17=$FF
SEC ;đặt C=1
EXIT_REC: RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 30


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
Ví dụ 8.10: Viết một chương trình thu chuỗi ký tự kết thúc bằng mã CR=$0D từ USART1,
mode UART,BR=19.2K,8 bit data,1 stop bit,parity lẻ.Chuỗi ký tự và mã CR được cất vào
SRAM địa chỉ đầu 0x200,và hiển thị ký tự thu ra PortB,trường hợp thu lỗi,xuất ra PC0=1.Lặp
vòng thu lại từ đầu khi thu ký tự CR hoặc thu lỗi.Cho Fosc=8Mhz.
Giải: .EQU S_BUF=$200 LDI R16,0 ;BR=19200,UBRR1=51,U2X1=1
.EQU CR=$0D STS UBRR1H,R16
.ORG 0 LDI R16,51
RJMP MAIN STS UBRR1L,R16
LDI R16,(1<<U2X1) ;x2 BR
.ORG 0X40
STS UCSR1A,R16
MAIN: LDI R16,HIGH(RAMEND)
OUT SPH,R16 LDI R16,(1<<RXEN1);cho phép thu,8 bit data
LDI R16,LOW(RAMEND) STS UCSR1B,R16
OUT SPL,R16 ; UART 8 bit ,1 stop bit, parity lẻ
LDI R16,$FF ;PortB output LDI R16,(3<<UCSZ10)|(3<<UPM10);
OUT DDRB,R16 STS UCSR1C,R16
SBI DDRC,0 ;PC0 output
CBI PORTC,0 ;xóa PC0=0

Giáo Trình Vi xử lý Chương 8 Lưu Phú 31


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
START: LDI XH,HIGH(S_BUF) ;X trỏ đ/c đầu SRAM REC_CHR_E: LDS R16,UCSR1A ;đọc UCSR1A
LDI XL,LOW(S_BUF) SBRS R16,RXC1 ;cờ RXC1=1,thu data
TIEP: RCALL REC_CHR_E ;gọi ctc thu có báo lỗI RJMP REC_CHR_E ;chờ cờ RXC1=1
OUT PORTB,R17 ;xuất ký tự ra PortB ANDI R16,(1<<FE1)|(1<<DOR1)|(1<<UPE1);
BRCS ERR ;C=1 báo lỗi ;kiểm tra báo lỗi
CBI PORTC,0 ;C=0,PC0=0 BRNE REC_ERR ;khác 0,báo lỗi
ST X+,R17 ;cất data ,tăng X LDS R17,UDR1 ;không lỗi, thu data
CPI R17,CR ;mã CR thoát CLC ;xóa C=0
BRNE TIEP ;khác 0,tiếp RJMP EXIT_REC ;thoát
RJMP START ;thoát REC_ERR: LDI R17,$FF ;có lỗi R17=$FF
ERR: SBI PORTC,0 ;PC0=1 SEC ;đặt C=1
EXIT: RJMP START ;dừng thu EXIT_REC: RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 32


8.2 Truyền nối tiếp bất đồng bộ(UART)
8.2.5 Thu data
Ví dụ 8.11: Viết một chương trình lặp vòng liên tục phát/thu ký tự từ USART0.Chuỗi ký tự
phát kết thúc bằng mã CR=$0D cất trong Flash ROM,chuỗi ký tự thu cũng kết thúc bằng mã
CR cất vào SRAM địa chỉ đầu $200,thực hiện phát/thu đồng thời và hiển thị ký tự thu ra PortB
cho đến khi cả 2 kết thúc.Mode UART 8 bit,1 stop bit ,không parity,BR=9600,Fosc=8Mhz.
Giải:
.EQU CR=$0D LDI R16,103
.EQU S_BUF=$200 STS UBRR0L,R16
.EQU TX_FLG=0 ;cờ báo kết thúc phát LDI R16,(1<<U2X0) ;x2 BR
.EQU RX_FLG=1 ;cờ báo kết thúc thu STS UCSR0A,R16
.ORG 0 LDI R16,(1<<TXEN0)|(1<<RXEN0);cho phép
RJMP MAIN STS UCSR0B,R16 ; phát/thu,8 bit data
.ORG 0X40 LDI R16,(3<<UCSZ00); UART 8 bit,1 stop bit,
MAIN: LDI R16,HIGH(RAMEND) STS UCSR0C,R16 ; không parity
OUT SPH,R16 START: LDI ZH,HIGH(MSG<<1);Z trỏ bảng tra MSG
LDI R16,LOW(RAMEND) LDI ZL,LOW(MSG<<1) ; trong Flash ROM
OUT SPL,R16
LDI XH,HIGH(S_BUF);X trỏ đ/c đầu SRAM
LDI R16,$FF
OUT PORTB,R16 ;PortB output LDI XL,LOW(S_BUF) ;
LDI R16,0 ;BR=9600,UBRR0=103,U2X0=1 LDI R19,0 ;R19 chứa các cờ báo k/thúc thu/phát
STS UBRR0H,R16
Giáo Trình Vi xử lý Chương 8 Lưu Phú 33
8.2 Truyền nối tiếp bất đồng bộ(UART)
;-----------------------------------------------------------------------
8.2.5 Thu data ;CTC TRANS_CHR phát data ra UART0
PHAT: SBRC R19,TX_FLG ;TX_FLG=0 phát tiếp ;Input R17 cất data cần phát
RJMP THU ;chuyển đến thu ;-----------------------------------------------------------------------
LPM R17,Z+ ;lấy ký tự từ MSG,Z+1 TRANS_CHR: LDS R16,UCSR0A ;đọc cờ UDRE0
RCALL TRANS_CHR; gọi ctc phát data nối tiếp SBRS R16,UDRE0 ;UDRE0=1 sẵn sàng phát
CPI R17,CR ;ký tự CR ? RJMP TRANS_CHR ;chờ cờ UDRE0=1
BRNE THU ;khác,phát tiếp STS UDR0,R17 ;phát data cất trong R17
SBR R19,(1<<TX_FLG);TX_FLG=1 dừng phát RET
THU: SBRC R19,RX_FLG ;RX_FLG=0 thu tiếp ;---------------------------------------------------------------------
RJMP CH_END ;k/tra kết thúc ;REC_CHR thu data 8 bit từ USART0
RCALL REC_CHR ;ctc thu ký tự
;Output R17 chứa data thu
OUT PORTB,R17 ;hiển thị ký tự ra PortB
;------------------------------------------------------------------------
ST X+,R17 ;cất vào SRAM,tăng X
REC_CHR: LDS R16,UCSR0A ;đọc cờ RXC0
CPI R17,CR ;ký tự thu=CR?
BRNE PHAT ;khác,thu tiếp SBRS R16,RXC0 ;cờ RXC0=1 đọc data
SBR R19,(1<<RX_FLG);RX_FLG=1 dừng thu RJMP REC_CHR ;chờ cờ RXC0=1
CH_END: CPI R19,(1<<TX_FLG)|(1<<RX_FLG) LDS R17,UDR0 ;đọc data cất vào R17
;kiểm tra các cờ báo kết thúc phát/thu RET
BRNE PHAT ;chưa,phát/thu tiếp ;------------------------------------------------
RJMP START ;kết thúc cà 2,lặp vòng lại từ đầu MSG: .DB "Xin chào! ",$0D

Giáo Trình Vi xử lý Chương 8 Lưu Phú 34


8.3 Truyền SPI(Serial Peripheral Bus)
8.3.1 Giới thiệu
• SPI là một chuẩn truyền thông nối tiếp đồng bộ do hãng Motorola đề xuất vào năm 1980.
• SPI là một chuẩn truyền song công (full duplex) nghĩa là tại cùng một thời điểm quá trình
phát và thu có thể xảy ra đồng thời.
• Mô hình giao tiếp SPI gồm có 1 Master và
1 hoặc nhiều Slave ,có 4 đường giao tiếp:
Tín hiệu Master Slave
MOSI Data out Data in Hình 8.7
MISO Data in Data out
SCK out in
/SS out in
• Master xuất tín hiệu /SS=0 bắt đầu truyền,/SS cũng là tín hiệu chọn chip Slave
• Master xuất xung nhịp SCK để đồng bộ data với Slave
• Master xuất data ra ngõ MOSI,Slave nhận data từ Master từ ngõ MOSI
• Đồng thời Slave xuất data ra ngõ MISO,Master nhận data từ Slave từ ngõ MISO
• Sau khi truyền xong byte data ,Master dừng phát xung nhịp SCK
• Mater xuất /SS=1 kết thúc truyền,thanh ghi dịch đệm data trong Master và Slave chứa data
thu được tương ứng.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 35
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.1 Giới thiệu
• Cấu hình MCU324P có 1 cổng SPI hoạt động được như Master/Slave,lập trình được tốc độ
truyền SCK. Bảng 8.6: Cấu hình cổng SPI MCU324P
Tín hiệu Chân MCU324P Mô tả I/O Master I/O Slave
MOSI PB5 Output Master,Input Slave Output Input
MISO PB6 Input Master,Output Slave Input Output
SCK PB7 Xung CK đồng bộ Output Input
/SS PB4 Cho phép truyền SPI,chọn Slave Output Input
 Để chọn Master hay Slave→khai báo cấu hình I/O các chân PB4..PB7 theo bảng trên
• Phần hoạt động sơ đồ khối SPI MCU324P xem thêm giáo trình và data sheet.
Bảng 8.7: Tóm tắt các thanh ghi sử dụng trong mode SPI
Địa chỉ MEM Địa chỉ I/O Ký hiệu Truy xuất bit Chức năng
0x4C 0x2C SPCR0 Có Điều khiển SPI
0x4D 0x4D SPSR0 Có Trạng thái SPI
0x4E 0x4E SPDR0 Không data phát/thu SPI

Giáo Trình Vi xử lý Chương 8 Lưu Phú 36


8.3 Truyền SPI(Serial Peripheral Bus)
8.3.2 Các thanh ghi sử dụng trong mode SPI
1. SPCR0 – SPI Control Register
Bit 7 6 5 4 3 2 1 0
0x2C (0x4C) SPIE0 SPE0 DORD0 MSTR0 CPOL0 CPHA0 SPR10 SPR00
Hình 8.8
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value 0 0 0 0 0 0 0 0

 Bit 7 – SPIE0: SPI Interrupt Enable


- Đặt SPIE0=1và I=1(reg.SREG) cho phép ngắt SPI
 Bit 6 – SPE0: SPI Enable
- Đặt SPE0=1 cho phép cổng SPI làm việc
 Bit 5 – DORD0: Data Order
- DORD0=0: MSB truyền trước
- DORD0=1: LSB truyền trước
 Bit 4 – MSTR0: Master/Slave Select
- MSTR0=1: chọn mode Master
- MSTR0=0: chọn mode Slave
Giáo Trình Vi xử lý Chương 8 Lưu Phú 37
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.2 Các thanh ghi sử dụng trong mode SPI
1. SPCR0 – SPI Control Register
 Bit 3 – CPOL0: Clock Polarity  Bit 1:0–SPR10:SPR00:Clock Rate Select1:0
- Chọn tốc độ truyền đối với Master, không ảnh
- CPOL0=1: SCK=1 nghỉ
hưởng đối với Slave (SPIX20 thuộc SPSR0)
- CPOL0=0: SCK=0 nghỉ
Bảng 8.8: Cài đặt FSCK SPI
CPOL0 Cạnh trước Cạnh sau
SPI2X0 SPIR10 SPIR00 FSCK
0 ↑ ↓
0 0 0 Fosc/4
1 ↓ ↑
0 0 1 Fosc/16
 Bit2 – CPHA0: Clock Phase
0 1 0 Fosc/64
CPHA0 Cạnh trước Cạnh sau
0 1 1 Fosc/128
0 Lấy mẫu data Thay đổi data
1 0 0 Fosc/2
1 Thay đổi data Lấy mẫu data
1 0 1 Fosc/8
Ví dụ lấy mẫu data ở cạnh lên là cạnh trước: 1 1 0 Fosc/32
CPOL0=0,CPHA0=0 1 1 1 Fosc/64

Giáo Trình Vi xử lý Chương 8 Lưu Phú 38


8.3 Truyền SPI(Serial Peripheral Bus)
8.3.2 Các thanh ghi sử dụng trong mode SPI
2. SPSR0 – SPI Status Register
Bit 7 6 5 4 3 2 1 0
0x2D (0x4D) SPIF0 WCOL0 – – – – – SPI2X0
Hình 8.9
Read/Write R R R R R R R R/W

Initial Value 0 0 0 0 0 0 0 0

 Bit 7 – SPIF0: SPI Interrupt Flag


- Cờ SPIF0=1 đặt bằng phần cứng chỉ báo SPI truyền xong data
- Cờ SPIF0=1 khi SPI là Master,/SS là input và /SS được kéo xuống 0 bởi Master khác
- Cờ SPIF0=1 cũng là tín hiệu báo ngắt SPI,nếu cho phép ngắt này
- SPIF0=0 xóa bằng phần cứng khi MCU chuyển đến trình phục vụ ngắt tương ứng,nếu cho
phép ngắt SPI.
- SPIF0=0 xóa bằng phần mềm bằng cách đọc reg.SPSR0 lần đầu tiên khi SPIF0=1 và truy
xuất reg. SPDR0.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 39
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.2 Các thanh ghi sử dụng trong mode SPI
2. SPSR0 – SPI Status Register
 Bit 6 – WCOL0: Write Collision Flag
- Cờ WCOL0=1 đặt bằng phần cứng khi ghi vào SPDR0 trong lúc SPI đang truyền data
- WCOL0=0 xóa bằng phần mềm bằng cách đọc reg.SPSR0 lần đầu tiên khi WCOL0=1 và
truy xuất reg. SPDR0.
 Bit 0 – SPI2X0: Double SPI Speed Bit
- Đặt SPI2X0=1 nhân 2 tốc độ truyền Fsck trong mode Master
 Khi SPI làm việc ở mode Slave Fsck<Fosc/4 để đảm bảo đồng bộ truyền data
3. SPDR0 – SPI Data Register
Bit 7 6 5 4 3 2 1 0
Hình 8.10 0x2E (0x4E) MSB LSB
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
Initial Value X X X X X X X X

- Ghi/đọc data trong truyền SPI


- Ghi vào SPDR0→phát data
- Đọc từ SPDR0→thu data từ bộ đệm thu 40
Giáo Trình Vi xử lý Chương 8 Lưu Phú
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.3 Chức năng chân /SS
1. Mode Slave
- Khai báo /SS=input,MISO=output,các chân MOSI và SCK input
- /SS=0 được lái từ Master cho phép kết nối và truyền SPI với Slave
- /SS=1 ngắt kết nối giữa Master và Slave,SPI dừng hoạt động ngay lập tức và vào trạng
thái reset,các ngõ SPI đều là input và mức 1(ngõ MISO=hi-Z).Khi đó vẫn có thể truy xuất
reg.SPDR0.
- Master điều khiển chân /SS với Slave đảm bảo đồng bộ bộ đếm bit của Slave với xung
SCK phát từ Master.
2. Mode Master
- Khai báo /SS=input hoặc output,phần cứng không điều khiển chân này,MISO=input và
các chân MOSI,SCK=output.
- Nếu /SS=output,Master sử dụng chân này điều khiển kết nối với Slave bằng phần mềm,
bằng cách xóa /SS=0 thiết lập kết nối với Slave,đặt /SS=1 dừng kết nối với Slave.
- Nếu /SS=input,phải đặt /SS=1 để đảm bảo mode Master.Trường hợp /SS=0 bị tác động
bởi thiết bị ngoài, làm Master chuyển thành Slave, phần cứng sẽ thực hiện:
1. Bit MSTR0 bị xóa=0 ,các ngõ MOSI và SCK trở thành input,
2. Cờ SPIF0=1 41
Giáo Trình Vi xử lý Chương 8 Lưu Phú
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.4 Mode data
• Có 4 mode truyền data tùy theo cài đặt 2 bit
CPOL0 và CPHA0(reg.SPCR0) CPHA0=0→
Bảng 8.9: Cài đặt mode data SPI
Mode
Diều kiện Cạnh trước Cạnh sau
SPI
0 CPOL0=0,CPHA0=0 Lấy mẫu ↑ Thay đổi ↓
1 CPOL0=0,CPHA0=1 Thay đổi ↑ Lấy mẫu ↓
2 CPOL0=1,CPHA0=0 Lấy mẫu ↓ Thay đổi ↑
3 CPOL0=1,CPHA0=1 Thay đổi ↓ Lấy mẫu ↑

CPHA0=1→

Hình 8.11

Giáo Trình Vi xử lý Chương 8 Lưu Phú 42


8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI
1. Mode Master
1. Khởi động cổng SPI mode Master bao gồm:
 Khai báo các chân MOSI (PB5), SCK (PB7), /SS (PB4) output, MISO (PB6) input
 Cho phép SPI: SPE0=1, bit MSTR0=1; xác định bit truyền trước: bit DORD0; cạnh xung lấy
mẫu data: CPOL0 và CPHA0; tốc độ xung CK: SPR10 và SPR00(reg.SPCR0),SPI2X0(
reg.SPSR0).
2. Xóa /SS=0 bắt đầu truyền:
 Trong trường hợp giao tiếp 1 Slave, chân /SS kết nối trực tiếp chân /SS hay /CS của Slave
 Trong trường hợp nhiều Slave, có thể thêm các chân /SSi hoặc kết hợp thêm mạch giải mã
địa chỉ chọn Slave như đã trình bày ở chương 6.
3. Ghi data cần phát vào thanh ghi SPDR0.
4. Đọc thanh ghi SPSR0, chờ cờ SPIF0=1 báo đã truyền xong.
5. Đọc thanh ghi SPDR0 thu data từ Slave (tác vụ bước 4 và 5 tương ứng xóa cờ SPIF0).
6. Lập lại từ bước 3 nếu muốn tiếp tục truyền data.
7. Đặt /SS=1 kết thúc truyền. 43
Giáo Trình Vi xử lý Chương 8 Lưu Phú
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI
1. Mode Master
Ví dụ 8.12: Khởi động MCU324P mode SPI Master,tốc độ truyền SPI = 500KHz, MSB truyền
trước, lấy mẫu cạnh lên ở cạnh trước.Cho Fosc=8Mhz.
Giải:
- Khai báo các chân MOSI (PB5), SCK (PB7), /SS (PB4) output, MISO (PB6) input
- Cho phép SPI: bit SPE0=1
- MSB truyền trước: DORD0=0
- Mode Master: MSTR0=1
- Lấy mẫu cạnh lên ở cạnh trước CPOL:CPHA=00
- Tốc độ truyền 500Khz=8Mhz/16: SPI2X0:SPR10:SPR00=001
.EQU SS=4 SBI PORTB,SS ;dừng truyền SPI
.EQU MOSI=5 LDI R16,(1<<SPE0)|(1<<MSTR0)|(1<<SPR00)
.EQU MISO=6 ;SPI Master,MSB trước,lấy mẫu cạnh lên cạnh trước,
.EQU SCK=7 ;fck=500Khz,cho phép SPI
LDI R16,(1<<SS)|((1<<MOSI)|(1<<SCK) OUT SPCR0,R16
; SS,MOSI,SCK output,MISO input
OUT DDRB,R16
Giáo Trình Vi xử lý Chương 8 Lưu Phú 44
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI
1. Mode Master
Ví dụ 8.13: Viết một CTC phát data cất trong R17 ra SPI và đọc data thu từ SPI về cất trong
R18.Giả sử đã khởi động SPI như ví dụ 8.12
Giải:
SPI_TRANS:
OUT SPDR0,R17 ;ghi data ra SPI
WAIT_SPI: IN R16,SPSR0 ;đọc cờ SPIF0
SBRS R16,SPIF0 ;cờ SPIF0=1 truyền SPI xong
RJMP WAIT_SPI ;chờ cờ SPIF0=1
IN R18,SPDR0 ;đọc data từ SPI
RET
 Trong chương trình chính phải xóa chân /SS=0 trước khi gọi chương trình con trên, và đặt
/SS=1 khi muốn kết thúc truyền SPI.

Giáo Trình Vi xử lý Chương 8 Lưu Phú 45


8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI
2. Mode Slave
• Trong mode Slave, cổng SPI hoàn toàn phụ thuộc vào tín hiệu /SS.
- /SS =1: Slave ngưng làm việc, chân MISO=hi-Z, chỉ có thể cập nhật data thanh ghi
SPDR0.
- /SS=0: xung CK từ Master sẽ dịch data phát từ Slave ra chân MISO và data thu từ Master
vào chân MOSI. Cấu hình fCK, cạnh lấy mẫu, bit truyền trước khai báo theo Master.
1. Khởi động mode Slave gồm:
 Khai báo chân MISO (PB6) output, các chân /SS(PB4), MOSI(PB5), SCK(PB7)input
 Đặt bit SPE0=1 cho phép SPI,MSTR0=0 mode Slave,DORD0,CPOL0,CPHA0 theo cấu hình
Master,SPR10:00=xx fCK do Master quyết định(thuộc reg. SPCR0)
2. Ghi data cần phát vào thanh ghi SPDR0
3. Đọc thanh ghi SPCR0,chờ cờ SPIF0=1 báo đã truyền xong
4. Đọc thanh ghi SPDR0 thu data từ Master(tác vụ bước 3 và 4 tương ứng xóa cờ SPIF0)
5. Lập lại từ bước 2 cho đến khi thu data từ Master báo kết thúc hay chân /SS=1
Giáo Trình Vi xử lý Chương 8 Lưu Phú 46
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI
Ví dụ 8.14: Viết một chương trình giao tiếp giữa 2 MCU324P qua cổng SPI thực hiện như sau:
 Mỗi lần nhấn SW, MCU Master sẽ truyền 1 ký tự trong chuỗi ký tự kết thúc bằng mã NULL
cất trong Flash ROM sang MCU Slave, đồng thời hiển thị ký tự thu về từ Slave ra PortA.
 MCU Slave thu ký tự từ Master hiển thị ra PortA, đồng thời truyền ký tự trong chuỗi ký tự
kết thúc bằng mã NULL cất trong Flash ROM (chiều dài bằng với chuỗi ký tự của Master)
sang Master.
 Lặp vòng lại từ đầu.
 Cho tốc độ truyền SPI = 500KHz, MSB truyền trước, lấy mẫu cạnh lên ở cạnh trước
Giải:
 MCU Master:
 Khai báo Master, tốc độ truyền SCK = 500KHz, lấy mẫu
cạnh lên ở cạnh trước,MSB truyềntrước,cho phép SPI làm việc
 Khai báo các ngõ ra: SS, SCK, MOSI, ngõ vào MISO.
 Bắt đầu truyền SPI xóa SS=0, dừng truyền SPI đặt SS = 1.
 Mỗi lần SW nhấn, lấy ký tự từ chuỗi ký tự đặt trong
Flash ROM gọi CTC SPI_TRANS phát/thu data và
kết thúc khi phát xong ký tự NULL, hiển thị ký tự thu được ra PortA. Hình 8.12
Giáo Trình Vi xử lý Chương 8 Lưu Phú 47
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI
 MCU Slave:
 Khai báo Slave,cho phép SPI làm việc,lấy mẫu cạnh lên ở cạnh trước,MSB truyền trước.
 Khai báo ngõ ra :MISO,các ngõ còn lại của SPI là ngõ vào.
 Để đồng bộ bên Master, chờ chân SS=0 mới thực hiện việc truyền SPI.
 Lấy ký tự từ chuỗi ký tự đặt trong Flash ROM gọi CTC SPI_TRANS phát/thu data và kết
thúc khi thu được ký tự NULL,hiển thị ký tự thu được ra PortA.
 Để dễ theo dõi, ta có thể sử dụng PortA lái bar LED.
 Sử dụng CTC SPI_TRANS ghi/đọc data chung cho cả Master và Slave.
 Ghi data vào SPDR0.
 Chờ cờ SPIF0=1.
 Đọc data từ SPDR0.
Sử dụng chương trình con SW_RD đọc trạng thái SW có chống rung (xem lại chương 6).
Giáo Trình Vi xử lý Chương 8 Lưu Phú 48
8.3 Truyền SPI(Serial Peripheral Bus)  Chương trình cho Master
8.3.5 Lập trình truyền SPI
.EQU OUTPORT=PORTA ;PORTA hiển thị LDI R16,0X00
.EQU OUTPORT_DR=DDRA OUT OUTPORT,R16 ;xóa hiển thị
.EQU CONT=PORTC ;PortC điều khiển LDI R16,(1<<SS)|(1<<SCK)|(1<<MOSI)
.EQU CONT_DR=DDRC ;khai báo các output SPI
.EQU CONT_IN=PINC OUT DDRB,R16
.EQU SW=0 ;ký hiệu chân SW SBI PORTB,SS ;dừng truyền SPI
.EQU SS=4 ;ký hiệu chân /SS LDI R16,(1<<SPE0)|(1<<MSTR0)|(1<<SPR00);
.EQU MOSI=5 ;ký hiệu chân MOSI ;SPI Master,SCK=Fosc/16,cho phép SPI,lấy mẫu cạnh lên ở
.EQU MISO=6 ;ký hiệu chân MISO ;cạnh trước,MSB truyền trước
.EQU SCK=7 ;ký hiệu chân SCK OUT SPCR0,R16
.EQU NULL=$00 ;mã kết thúc chuỗi ký tự ;---------------------------------------------------------
.ORG 0 START: SBI PORTB,SS ;dừng truyền SPI
RJMP MAIN LDI ZH,HIGH(MSG_OUT<<1);Z trỏ đ/c đầu
.ORG 0X40 LDI ZL,LOW(MSG_OUT<<1);bảng tra MSG
MAIN: LDI R16,HIGH(RAMEND) SPI_NXT: RCALL SW_RD ;chờ SW nhấn
OUT SPH,R16 LPM R17,Z+ ;lấy ký tự từ chuỗi ký tự
LDI R16,LOW(RAMEND) CBI PORTB,SS ;cho phép truyền SPI
OUT SPL,R16 RCALL SPI_TRANS ;truyền SPI
CBI CONT_DR,SW ;khai báo SW input OUT OUTPORT,R18 ;hiển thị ký tự thu từ SPI
SBI CONT,SW ;điện trở kéo lên ngõ SW CPI R17,NULL ;ký tự phát=NULL
LDI R16,0XFF BRNE SPI_NXT ;khác tiếp tục truyền SPI
OUT OUTPORT_DR,R16;Port hiển thị output RJMP START ;lặp vòng lại từ đầu
Giáo Trình Vi xử lý Chương 8 Lưu Phú 49
8.3 Truyền SPI(Serial Peripheral Bus)  Chương trình cho Master
8.3.5 Lập trình truyền SPI ;----------------------------------------------------------
;SW_RD đọc trạng thái nút nhấn có chống rung
;----------------------------------------------------------- ;Chỉ thoát khi có SW nhấn
;SPI_TRANS truyền data SPI giữa Master và Slave ;Sử dụng R16
;Input: R17 chứa data ghi ra Slave ;-----------------------------------------------------------
;Output: R18 chứa data đọc từ Slave SW_RD: LDI R16,50 ;ktra SW nhấn 50 lần liên tục
;Sử dụng R16 WAIT0: SBIC CONT_IN,SW
;---------------------------------------------------------- RJMP SW_RD
SPI_TRANS: DEC R16
OUT SPDR0,R17 ;ghi data ra SPI BRNE WAIT0
WAIT_SPI: BACK1: LDI R16,50 ;k/tra sw nhả 50 lần liên tục
IN R16,SPSR0 ;đọc cờ SPIF0 WAIT1: SBIS CONT_IN,SW
SBRS R16,SPIF0 ;cờ SPIF0=1 truyền SPI xong RJMP BACK1
RJMP WAIT_SPI ;chờ cờ SPIF0=1 DEC R16
IN R18,SPDR0 ;đọc data từ SPI BRNE WAIT1
RET RET
;-----------------------------------------------------------
.ORG 0X200
MSG_OUT:
.DB "ABCDEFGHIJKLMNO",$00
;-------------------------------------------------------
Giáo Trình Vi xử lý Chương 8 Lưu Phú 50
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI Chương trình cho Slave
.EQU OUTPORT=PORTA;PORTA hiển thị START: LDI ZH,HIGH(MSG_OUT<<1);Z trỏ đ/c đầu
.EQU OUTPORT_DR=DDRA LDI ZL,LOW(MSG_OUT<<1); bảng MSG
.EQU SS=4 ;ký hiệu chân /SS SPI_NXT: LPM R17,Z+ ;lấy ký tự từ chuỗi ký tự
.EQU MISO=6 ;ký hiệu chân MISO SPI_SS: SBIC PINB,SS ;chờ cho phép truyền SPI
.EQU NULL=$00 ;mã kết thúc chuỗi ký tự RJMP SPI_SS
.ORG 0 RCALL SPI_TRANS ;truyền SPI
RJMP MAIN OUT OUTPORT,R18;hiển thị ký tự thu từ SPI
.ORG 0X40 CPI R18,NULL ;ký tự=NULL
MAIN: LDI R16,HIGH(RAMEND) BRNE SPI_NXT ;khác tiếp tục truyền SPI
OUT SPH,R16 RJMP START ;lặp vòng lại từ đầu
LDI R16,LOW(RAMEND)
OUT SPL,R16
LDI R16,0XFF
OUT OUTPORT_DR,R16;Port hiển thị output
LDI R16,0X00
OUT OUTPORT,R16 ;xóa hiển thị
LDI R16,(1<<MISO) ;chân MISO output SPI
OUT DDRB,R16
LDI R16,(1<<SPE0) ;SPI Slave,cho phép SPI
;lấy mẫu cạnh lên ở cạnh trước,MSB truyền trước
OUT SPCR0,R16
Giáo Trình Vi xử lý Chương 8 Lưu Phú 51
8.3 Truyền SPI(Serial Peripheral Bus)
8.3.5 Lập trình truyền SPI Phần mô tả hoạt động IC AT24AA1024
;----------------------------------------------------------- và ví dụ giao tiếp SPI với IC này xem chi tiết
;SPI_TRANS truyền data SPI giữa Master và Slave trong giáo trình chương 8
;Input: R17 chứa data ghi ra Slave
;Output: R18 chứa data đọc từ Slave
;Sử dụng R16
;----------------------------------------------------------
SPI_TRANS:
OUT SPDR0,R17 ;ghi data ra SPI
WAIT_SPI:
IN R16,SPSR0 ;đọc cờ SPIF0
SBRS R16,SPIF0 ;cờ SPIF0=1 truyền SPI xong
RJMP WAIT_SPI ;chờ cờ SPIF0=1
IN R18,SPDR0 ;đọc data từ SPI
RET
;-----------------------------------------------------------
.ORG 0X200
MSG_OUT: .DB "abcdefghijklmno",$00
;------------------------------------------------------------

Giáo Trình Vi xử lý Chương 8 Lưu Phú 52


8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
• I2C(Inter Integrated Circuit)là chuẩn giao tiếp nối tiếp các thiết bị của hãng Phillips phát
triển từ 1990,sau đó được sử dụng rộng rãi cho các chip cảm biến,RTC,bộ nhớ…
• Cấu hình cơ bản I2C chỉ gồm 2 dây:
- SCL(Serial clock): xung nhịp đồng bộ data giữa 2 chip
- SDA(Serial data): truyền data giữa 2 chip
Hình 8.13
• Với AVR,I2C còn có tên gọi là
TWI(Two Wire serial Interface)
• Các thiết bị giao tiếp I2C thường có
các ngõ SCL,SDA cực thu (máng)hở
→R1,R2=4.7K kéo lên nguồn,có thể
kết nối wired AND các ngõ SCL,SDA
• AVR có thể kết nối 128 TB I2C với
bus I2C,mỗi TB=node,mỗi node có thể
là Master hoặc Slave,Master phát CK.
→Có 4 mode làm việc: Master phát/thu,Slave phát/thu.Tại 1 thời điểm chỉ có 1 mode làm việc
• Bus data chỉ có 1 đường SDA→I2C truyền bán song công
Giáo Trình Vi xử lý Chương 8 Lưu Phú 53
8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
1. Định dạng truyền I2C
 Tín hiệu START/STOP
- Bắt đầu truyền bằng tín hiệu START
- Kết thúc truyền bằng tín hiệu STOP
- Xung CK trên SCL phát từ Master đồng
bộ truyền data.Data phải ổn định khi SCL=1.
Data chỉ thay đổi khi SCL=0 Hình 8.14
- Tín hiệu START xuất hiện khi đặt SCL=1,
SDA từ 1→0 và giữ mức 0=độ rộng bit data truyền
- Tín hiệu STOP xuất hiện khi đặt SCL=1,
SDA từ 0→1 và giữ mức 1=độ rộng bit data truyền
- Trong thời gian giữa START và STOP bus I2C bận.
- Nếu Master đang kiểm soát bus muốn khởi động
truyền data mới,chỉ cần xuất tín hiệu START lần nữa
Gọi là REPEATED START(Hình 8.16)
Hình 8.15
Giáo Trình Vi xử lý Chương 8 Lưu Phú 54
8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
1. Định dạng truyền I2C
 Truyền data,ACK,NACK
- Truyền data 8 bit,MSB trước
- Master phát xung CK
- Khi bộ phát phát xong 8 bit
data ,sẽ trả bus data SDA=1
- Ở xung CK thứ 9,bộ thu đáp ứng
Hình 8.17
bằng cách xuất tín hiệu ACK/NACK trên bus SDA:
o Nếu là ACK,SDA=0 báo bộ thu
đã thu xong sẵn sàng nhận data tiếp
o Nếu là NACK,SDA=1 báo bộ thu
bận hoặc tạm dừng truyền data
(Hình 8.17)

Hình 8.16
Giáo Trình Vi xử lý Chương 8 Lưu Phú 55
8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
2. Truyền địa chỉ
- Master xuất START(S)+đ/chỉ Slav.+R/W
- Byte data gồm 7 bit cao là đ/chỉ Slave
(MSB trước),loại trừ các đ/chỉ 1111xxx và
Hình 8.18
0000000(gọi chung:general call-xem chi tiết phần reg. TWAR)
- Bit 0 R/W: R/W=1 thu(đọc) data,R/W=0: phát(ghi)data
- Ở xung CK thứ 9 Slave trả về ACK báo đã đáp ứng
3. Truyền địa chỉ+data
- Master xuất S+ đ/chỉ
Slav.+R/W
- Slave đáp ứng ACK
- Nếu là W,Master xuất
tiếp data,Slave đáp ứng
ACK.Nếu là R,Slave xuất data,Master đáp ứng ACK Hình 8.19
- Master xuất STOP kết thúc truyền
Giáo Trình Vi xử lý Chương 8 Lưu Phú 56
8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
4. Hệ thống bus nhiều Master-Sư phân xử(Arbitration)
- I2C cho phép nhiều Master cùng kết nối chung bus,nhưng chỉ có 1 Master chiếm quyền
kiểm soát bus.Hệ thống không phân biệt mức ưu tiên Master
- Việc tranh chấp xảy ra chỉ tại thời điểm 2 hay nhiều Master cùng phát xung START(cho
các tần số xung CK các Master bằng nhau để dễ xử lý)→Sự phân xử
- Sự phân xử thường thực hiện ở thời điểm truyền data.Bộ phát Master kiểm tra logic của nó
phát ra với logic trên bus,nếu khác nhau nó sẽ bị mất quyền kiểm soát bus và chuyển thành
Slave.Quyền kiểm soát bus thuộc về Master kiểm tra logic đúng!
- Xem chi tiết trong giáo trình và data sheet
5. Ghi data ra I2C
- Master phát tín hiệu START
- Master phát địa chỉ Slave cần truy xuất : SLA addr.(7 bit cao) +W(bit0)
- Master phát tiếp địa chỉ vị trí(ô nhớ,thanh ghi)đầu tiên cần ghi
- Master phát data ứng với địa chỉ đầu tiên
- Master trả SDA=1,chờ nhận ACK=0(xung CK thứ 9)
- Master tiếp tục phát data và nhận ACK trong trường hợp ghi nhiều byte(Slave tự động
tăng địa chỉ ô nhớ,thanh ghi thêm 1 mỗi lần nhận data)
- Master phát tín hiệu STOP kết thúc ghi data
Giáo Trình Vi xử lý Chương 8 Lưu Phú 57
8.4 Truyền TWI(Two Wired Interface)
8.4.1 Giới thiệu chung về I2C
6. Đọc data từ I2C
- Master phát tín hiệu START
- Master phát địa chỉ Slave cần truy xuất : SLA addr.(7 bit cao) +W(bit0)
- Master phát tiếp địa chỉ vị trí(ô nhớ,thanh ghi)đầu tiên cần đọc
- Master phát tín hiệu START(REPEATED START)
- Master phát địa chỉ Slave cần đọc: SLA addr.(7 bit cao) +R(bit0)
- Master đọc data ứng với địa chỉ vị trí đầu tiên phát từ Slave
- Master trả ACK=0(xung CK thứ 9)báo đọc xong
- Master tiếp tục đọc data và trả ACK trong trường hợp đọc nhiều byte(Slave tự động tăng
địa chỉ ô nhớ,thanh ghi thêm 1 mỗi lần phát data)
- Master phát tín hiệu STOP kết thúc ghi data
• MCU324P có cấu hình cổng TWI(Two Wire serial Interface)hoàn toàn tương thích với mode
truyền I2C. Địa chỉ MEM Ký hiệu Truy xuất bit Chức năng
- SCL≡PC0,SDA≡PC1 0xB8 TWBR Không Đặt tốc độ bit(bit rate) TWI
• Xem hoạt động sơ đồ khối trong giáo trình 0xB9 TWSR Có Trạng thái TWI
0xBA TWAR Có Đặt địa chỉ TWI
và data sheet 0xBB TWDR Không data TWI
Bảng 8.10: Tóm tắt các thanh ghi sử dụng TWI 0xBC TWCR Có Điều khiển TWI

Giáo Trình Vi xử lý Chương 8 Lưu Phú 58


8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
Hình 8.20

1. TWBR – TWI Bit Rate Register


 Bit 7:0 chọn hệ số chia cho bộ tạo bit rate phát xung CK theo công thức:
𝐹𝑜𝑠𝑐
𝐹𝑆𝐶𝐿 = 𝑇𝑊𝑃𝑆
(8.4)
16 + 2(𝑇𝑊𝐵𝑅) × 4
- TWBR: giá trị reg. TWBR
- TWPS: giá trị các bit đặt trước trong reg. TWI Status (xem Bảng 8.11)
Ví dụ 8.15: Tính giá trị nạp TWBR để tạo FSCL=100Khz,giả sử đặt TWPS=0,cho Fosc=8Mhz.
Giải:
Từ (8.4),suy ra:
𝐹𝑜𝑠𝑐 8000
𝑇𝑊𝐵𝑅 = −8= − 8 = 32
2 × 𝐹𝑆𝐶𝐿 2 × 100
Giáo Trình Vi xử lý Chương 8 Lưu Phú 59
8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
Hình 8.21

2. TWCR – TWI Control Register


 Bit 7 – TWINT: TWI Interrupt Flag
- TWINT=1 đặt bằng phần cứng báo kết thúc một tác vụ truyền TWI,cũng chính là tín hiệu
báo ngắt TWI nếu khai báo cho phép ngắt này
- TWINT =0 xóa bằng phần mềm bằng cách ghi 1 vào bit này
 Lưu ý: - TWINT không được xóa bằng phần cứng khi MCU chuyển đến trình phục vụ ngắt
TWI,nếu cho phép ngắt này!Bởi vì xóa TWINT=0 có nghĩa là bắt đầu hoạt động TWI.
- Việc truy xuất các reg. TWAR,TWSR,TWDR phải chấm dứt trước khi xóa TWINT!
 Bit 6 – TWEA: TWI Enable ACK bit
- Bit TWEA kiểm soát việc phát ACK.Nếu TWEA=1,tín hiệu ACK được xuất ra bus TWI,
nếu một trong các điều kiện sau thòa mãn:
1. Nhận đúng địa chỉ Slave(đối với Slave)
Giáo Trình Vi xử lý Chương 8 Lưu Phú 60
8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
2. Nhận lệnh gọi chung(general call),khi bit TWGCE=1(reg. TWAR)(đối với Slave)
3. Nhận được 1 byte data trong mode Master/Slave thu
- Khi ghi TWEA=0,thiết bị Slave tạm thời ngắt khỏi bus TWI.Nếu đặt lại TWEA=1,việc
nhận đúng địa chỉ có thể kết nối thiết bị Slave với bus TWI trở lại.
 Bit 5 – TWSTA: TWI Start condition bit
- Ghi TWSTA=1 trong mode Master sẽ phát tín hiệu START
- Phần cứng kiểm tra bus và phát tín hiệu START nếu bus data rỗi
- Nếu bus data bận,TWI chờ đến khi phát hiện tín hiệu STOP sẽ phát tín hiệu START mới
yêu cầu sử dụng bus.
- Phải xóa TWSTA=0 bằng phần mềm sau khi phát tín hiệu START
 Bit 4 – TWSTO:TWI Stop condition bit
- Ghi TWSTO=1 trong mode Master sẽ phát tín hiệu STOP
- Khi tín hiệu STOP được phát,phần cứng sẽ xóa TWSTO=0
- Trong mode Slave,ghi TWSTO=1 sử dụng để phục hồi lại từ điều kiện lỗi.TWI không
phát tín hiệu STOP,nhưng nó sẽ trả về mode Slave xác định được không có địa chỉ,và ngắt
khỏi các đường SCL,SDA chuyển sang hi-Z.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 61
8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
 Bit 3 – TWWC: TWI Write Collision Flag
- Phần cứng đặt TWWC=1 khi ghi vào reg. TWDR trong khi TWINT=0
- TWWC=0 xóa bằng phần cứng khi ghi vào TWDR trong khi TWINT=1
 Bit 2 – TWEN:TWI Enable bit
- Đặt TWEN=1 cho phép cổng TWI làm việc.TWI sẽ điều khiển các chân I/O PC0,PC1
thành SCL,SDA tương ứng,cho phép giới hạn tốc độ đáp ứng(slew rate) và lọc gai nhiễu.
- Xóa TWEN=0 sẽ ngắt ngay lập tức cổng TWI,bất kể nó đang làm việc ở trạng thái nào.
 Lưu ý: - Khi đặt TWEN=1 cho phép TWI làm việc,phần cứng tự động chuyển các I/O
PC0,PC1 sang SCL,SDA tương ứng,không cần phải khai báo nào khác!
 Bit 0 – TWIE: TWI Interrupt Enable
- Đặt TWIE=1,cùng với I=1(reg. SREG)cho phép ngắt TWI làm việc.Ngắt TWI xảy ra khi
TWINT=1

Giáo Trình Vi xử lý Chương 8 Lưu Phú 62


8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
3. TWSR – TWI Status Register

Hình 8.22

 Bit 7:3 – TWS7:TWS3: TWI Status


- 5 bit này phản ánh trạng thái logic TWI và bus TWI(xem chi tiết trong phần các mode
truyền SPI)
 Lưu ý: - Khi đọc nội dung TWRS bao gồm cả 2 bit đặt trước hệ số chia TWPS1:0,phải
xóa 2 bit này để trả về giá trị đọc trạng thái TWI đúng!
 Bit 1:0 – TWPS: TWI Prescaler Bits
- Các bit này đặt hệ số chia cho bộ chia đặt trước(Prescaler) tạo bit rate(công thức 8.4)
Bảng 8.11: Cài đặt hệ số
chia cho bộ chia đặt
trước tạo FSCL
TWPS=TWPS1:0

Giáo Trình Vi xử lý Chương 8 Lưu Phú 63


8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
4. TWDR – TWI Data Register

Hình 8.23

- Chứa byte data kế tiếp trong mode phát,chứa byte data cuối cùng trong mode thu
- Chỉ truy xuất TWDR khi TWINT=1
5. TWAR – TWI Address Register

Hình 8.24

 Bit 7:1 – TWA: TWI (Slave) Address Register


- 7 bit địa chỉ của Slave,đặt cho Slave,Master không cần
- Trường hợp bus có nhiều Master,địa chỉ đặt cho Master khi nó chuyển thành Slave theo sự
phân xử.
 Bit 0 – TWGCE: TWI General Call Recognition Enable bit
- Đặt TWGCE=1 cho phép cuộc gọi chung(General call)(đối với Slave)
Giáo Trình Vi xử lý Chương 8 Lưu Phú 64
8.4 Truyền TWI(Two Wired Interface)
8.4.2 Các thanh ghi sử dụng TWI
- Master phát địa chỉ 0000000+W(0) trên bus
- Toàn bộ các Slave trên bus đều đáp ứng và trả về ACK
- Áp dụng cuộc gọi chung trong trường hợp Master muốn phát thông điệp chung cho tất cả
các Slave.Trường hợp đọc không có nghĩa trong cuộc gọi chung!

Giáo Trình Vi xử lý Chương 8 Lưu Phú 65


8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
• Có 4 mode truyền TWI: Master phát,Master thu,Slave phát,Slave thu
• Cờ TWINT=0 báo TWI bận đang truyền,cờ TWINT=1 báo TWI rỗi,đã truyền xong
• Sau mỗi bước truyền TWI,reg. TWSR đều cập nhật mã báo trạng thái truyền TWI.Các mã
trạng thái đọc từ TWSR mô tả sau đây đã xóa 2 bit TWPS1:0=00(xem chi tiết mã trạng thái
trong data sheet)
1. Mode Master phát
B1. Khởi động Master:
 Đặt tốc độ truyền fCK=fSCL qua thanh ghi TWBR.
 Đặt TWEN=1 (thuộc thanh ghi TWCR) cho phép TWI làm việc.
Ví dụ 8.16: Viết CTC khởi động mode Master phát tốc độ CK =100Khz.
Giải:
TWI_INIT: LDI R17,8 ;tốc độ truyền SCL=100Khz,theo vd 8.15 với TWPS=1
STS TWBR,R17
LDI R17,1 ;TWPS=01, hệ số đặt trước=4
STS TWSR,R17 ;
LDI R17,(1<<TWEN);cho phép TWI
STS TWCR,R17
RET Giáo Trình Vi xử lý Chương 8 Lưu Phú 66
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
1. Mode Master phát
B2. Phát xung START(REPEATED START):
 Nạp TWCR các bit TWINT=1, TWSTA=1, TWEN=1: TWINT=1 xóa cờ TWINT chuẩn
bị truyền TWI, TWSTA=1 phát xung START, TWEN=1 cho phép TWI.
 Chờ TWINT=1, xóa xung START bằng cách xóa TWSTA=0. Để thuận tiện ta có thể kết
hợp việc xóa bit TWSTA trong bước chờ phát địa chỉ Slave.
 Trạng thái: - TWSR=0x08 báo xung START đã phát.
- TWSR=0x10 báo xung REPEATED START đã phát.
Ví dụ 8.17: Viết CTC master phát xung START sau khi khởi động.
Giải:
TWI_START: LDI R17,(1<<TWEN)|(1<<TWSTA)|(1<<TWINT);cho phép TWI,START,xóa TWINT
STS TWCR,R17
WAIT_STA: LDS R17,TWCR ;đọc cờ TWINT
SBRS R17,TWINT ;chờ cờ TWINT=1 báo truyền xong
RJMP WAIT_STA
RET
Giáo Trình Vi xử lý Chương 8 Lưu Phú 67
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
1. Mode Master phát
B3. Phát địa chỉ Slave +tín hiệu ghi: Slav+W
 Chờ cờ TWINT=1, nạp TWCR bit TWINT=1, TWEN=1: xóa TWINT và cho phép TWI
(tác vụ này bao gồm luôn việc xóa bit TWSTA).
 Nạp TWDR Slav+W- địa chỉ Slave 7 bit khác 1111xxx theo định dạng: a6a5a4a3a2a1a00.
 Trường hợp muốn truy xuất tất cả Slave đặt Slav+W=$00 cuộc gọi chung.
 Trạng thái: - TWSR=0x18 báo Slav+W đã phát và nhận được ACK.
- TWSR=0x20 báo Slav+W đã phát và nhận được NACK.
- TWSR=0x38 báo mất phân xử,Master mất quyền điều khiển bus
B4. Phát data
 Chờ cờ TWINT=1,nạp TWCR bit TWINT=1,TWEN=1: xóa TWINT và cho phép TWI.
 Ghi vào TWDR data cần phát(MSB truyền trước ra TWI).
 Lặp lại bước B4 cho đến khi Master muốn kết thúc phát hoặc Slave báo NACK ngưng
nhận data.
 Trạng thái: - TWSR=0x28 báo data đã phát và nhận được ACK.
- TWSR=0x30 báo data đã phát và nhận được NACK.
- TWSR=0x38 báo mất phân xử,Master mất quyền điều khiển bus.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 68
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
1. Mode Master phát
Ví dụ 8.18: Viết CTC Master ghi địa chỉ/data ra TWI,địa chỉ/data cất trong R17.
Giải:
;Phần chờ cờ TWINT=1 đã thực hiện trong ctc TWI_START ví dụ 8.17
TWI_WRITE: STS TWDR,R17 ;ghi địa chỉ/data
LDI R17,(1<<TWEN)|(1<<TWINT) ;cho phép TWI,xóa TWINT
STS TWCR,R17
WAIT_WR: LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong
SBRS R17,TWINT
RJMP WAIT_WR
RET
B5. Phát xung STOP
 Nạp TWCR các bit TWINT=1,TWSTO=1,TWEN=1:TWINT=1 xóa cờ TWINT,
TWSTO=1 phát xung STOP,TWEN=1 cho phép TWI.
Ví dụ 8.19: Viết một CTC Master phát xung STOP.
Giải:
TWI_STOP: LDI R17,(1<<TWEN)|(1<<TWSTO)|(1<<TWINT);cho phép TWI,xóa TWINT,phát STOP
STS TWCR,R17
RET Giáo Trình Vi xử lý Chương 8 Lưu Phú 69
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
2. Mode Master thu
B1. Khởi động: tương tự mode master phát
B2. Phát xung START: tương tự mode master phát
B3. Phát địa chỉ Slave +tín hiệu đọc: Slav+R
 Chờ cờ TWINT=1, nạp TWCR bit TWINT=1, TWEN=1: xóa TWINT và cho phép TWI
(tác vụ này bao gồm luôn việc xóa bit TWSTA).
 Nạp TWDR Slav+R- địa chỉ Slave 7 bit khác 1111xxx theo định dạng : a6a5a4a3a2a1a01.
 Trạng thái: - TWSR=0x40 báo Slav+R đã phát và nhận được ACK.
- TWSR=0x48 báo Slav+R đã phát và nhận được NACK.
- TWSR=0x38 báo mất phân xử,Master mất quyền điều khiển bus.
B4. Thu data
 Chờ cờ TWINT=1, nạp TWCR bit TWINT=1, TWEA=1, TWEN=1: xóa TWINT, gửi
ACK, cho phép TWI.
 Đọc data từ TWDR.
 Lặp lại bước B4 cho đến khi Master muốn kết thúc phát sẽ gửi NACK báo ngưng nhận
data khi thu byte data cuối, bằng cách xóa bit TWEA=0 ở dòng đầu bước 4.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 70
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
2. Mode Master thu
 Trạng thái: - TWSR=0x50 báo data đã thu và gửi ACK.
- TWSR=0x58 báo data đã thu và gửi NACK.
- TWSR=0x38 báo mất phân xử,Master mất quyền điều khiển bus.
Ví dụ 8.20: Viết 1 CTC đọc data từ TWI trả về ACK khi đọc xong data.
Giải:
;Phần chờ cờ TWINT=1 đã thực hiện trong ctc TWI_START hoặc TWI_WRITE
TWI_READ: LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA);cho phép TWI,xóa TWINT,trả ACK
STS TWCR,R17
WAIT_RD: LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong
SBRS R17,TWINT
RJMP WAIT_RD
LDS R17,TWDR ;đọc data thu được
RET
B5. Phát xung STOP
Tương tự như mode Master phát
Giáo Trình Vi xử lý Chương 8 Lưu Phú 71
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
Ví dụ 8.21: Viết 1 CTC Master trả về NACK khi muốn dừng đọc data.
Giải:
TWI_NAK: LDI R17,(1<<TWEN)|(1<<TWINT);cho phép TWI,xóa TWINT,trả NACK
STS TWCR,R17
WAIT_NAK: LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong
SBRS R17,TWINT
RJMP WAIT_NAK
RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 72


8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
3. Mode Slave phát
B1. Khởi động Slave:
 Ghi địa chỉ Slave vào 7 bit cao thanh ghi TWBR, bit TWGCE=0.
 Nạp TWCR bit TWEA=1 kết nối bus TWI gửi ACK báo đáp ứng đúng địa chỉ Slave,
TWEN=1 cho phép TWI.
 Trường hợp bit TWGCE=1 Slave sẽ đáp ứng cuộc gọi chung từ Master.
Ví dụ 8.22: Viết một CTC khởi động Slave,input địa chỉ Slave=TWI_ADDR
Giải:
TWI_INIT: LDI R17,TWI_ADDR<<1 ;địa chỉ Slav
STS TWAR,R17
LDI R17,(1<<TWEN)|(1<<TWEA) ;cho phép TWI,trả ACK
STS TWCR,R17
RET
B2. Chờ đáp ứng địa chỉ Slave +tín hiệu đọc từ Master: Slav+R
 Chờ cờ TWINT=1 báo Master gọi đúng địa chỉ và xem trạng thái hướng truyền.
 Trạng thái: - TWSR=0xA8 báo Slav+R đã nhận và gửi ACK.
- TWSR=0xB0 báo mất phân xử ở mode Master phát Slav+R/W, chuyển
sang Slave đáp ứng địa chỉ Slav+R đã nhận và gửi ACK.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 73
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
3. Mode Slave phát
Ví dụ 8.23: Viết một CTC Slave nhận dạng địa chỉ và trả về R18=mã trạng thái tương ứng
Giải:
TWI_DET: LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA);cho phép TWI,xóa TWINT,kết nối bus và trả ACK
STS TWCR,R17
WAIT_DET:
LDS R17,TWCR ;đọc cờ TWINT
SBRS R17,TWINT ;chờ cờ TWINT=1 báo đúng địa chỉ Slav
RJMP WAIT_DET
LDS R18,TWSR ;đọc mã trạng thái báo truy xuất
ANDI R18,0B11111000 ;che 5 bit cao mã trạng thái
RET
B3. Phát data
 Chờ cờ TWINT=1, nạp TWCR bit TWINT=1, TWEA=1, TWEN=1: xóa TWINT, kết nối
bus TWI và cho phép TWI.
 Nạp TWDR data cần phát (MSB truyền trước ra TWI).
Giáo Trình Vi xử lý Chương 8 Lưu Phú 74
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
3. Mode Slave phát
 Lặp lại bước B3 cho đến khi nhận được NACK từ Master báo ngưng nhận data hoặc
Slave muốn kết thúc phát data bằng cách xóa bit TWEA khi phát byte cuối.
 Trạng thái: - TWSR=0xB8 báo data đã phát và nhận được ACK.
- TWSR=0xC0 báo data đã phát và nhận được NACK.
- TWSR=0xC8 báo byte data cuối đã phát (TWEA=0) và nhận được
ACK.
B4. Dừng phát data
 Trường hợp nhận tín hiệu NACK từ Master báo ngưng nhận data sau đó là xung STOP
hoặc xung START mới (REPEATED START).
 Trường hợp Slave muốn kết thúc phát data, ở lần phát byte data cuối Slave xóa bit
TWEA=0 bằng cách nạp TWCR các bit TWINT=1, TWEN=1. Slave sau khi phát xong
byte data cuối sẽ tạm cách ly khỏi bus TWI.
 Nếu Master vẫn gửi ACK, byte kế tiếp Master sẽ nhận được là 0xFF.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 75
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
3. Mode Slave phát
Ví dụ 8.24: Viết một CTC Slave phát data.
Giải:
;Phần chờ cờ TWINT=1 đã thực hiện trong ctc TWI_DET ví dụ 8.23
TWI_WRITE: STS TWDR,R17 ;ghi data
LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA);cho phép TWI,xóa TWINT,kết nối bus
STS TWCR,R17
WAIT_WR: LDS R17,TWCR ;chờ cờ TWINT=1 báo truyền xong
SBRS R17,TWINT
RJMP WAIT_WR
RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 76


8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
4. Mode Slave thu
B1. Khởi động Slave: Tương tự mode Slave phát
B2. Chờ đáp ứng địa chỉ Slave +tín hiệu ghi từ Master: Slav+W:
 Chờ cờ TWINT=1 báo Master gọi đúng địa chỉ và xem trạng thái hướng truyền.
 Trạng thái: - TWSR=0x60 báo Slav+W đã nhận và gửi ACK.
- TWSR=0x68 báo mất phân xử ở mode Master phát Slav+R/W,
chuyển sang Slave đáp ứng địa chỉ Slav+W đã nhận và gửi ACK.
- TWSR=0x70 báo đã nhận cuộc gọi chung và gửi ACK.
- TWSR=0x78 báo mất phân xử ở mode Master phát Slav+R/W,
chuyển sang Slave đáp ứng cuộc gọi chung và gửi ACK.

Giáo Trình Vi xử lý Chương 8 Lưu Phú 77


8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
4. Mode Slave thu
B3. Thu data
 Chờ cờ TWINT=1, nạp TWCR bit TWINT=1, TWEA=1, TWEN=1: xóa TWINT kết nối
bus TWI và cho phép TWI.
 Đọc data từ TWDR.
 Lặp lại bước B3 cho đến khi Master phát xung STOP hoặc Slave muốn ngưng thu data
bằng cách gửi NACK khi thu byte cuối.
 Trạng thái:
- TWSR=0x80 báo Slav+W trước đó và data đã thu được và gửi ACK.
- TWSR=0x88 báo Slav+W trước đó và data đã thu được và gửi NACK.
- TWSR=0x90 báo địa chỉ cuộc gọi chung trước đó và data đã thu được và gửi ACK.
- TWSR=0x98 báo địa chỉ cuộc gọi chung trước đó và data đã thu được và gửi NACK
B4. Dừng thu data
 Trường hợp nhận xung STOP hoặc xung START mới (REPEATED START).
 Trường hợp Slave muốn ngưng thu data, ở lần thu byte data cuối Slave xóa bit TWEA=0
bằng cách nạp TWCR các bit TWINT=1, TWEN=1. Slave sau khi thu xong byte data cuối
sẽ gửi NACK báo Master và tạm cách ly khỏi bus TWI.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 78
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
Ví dụ 8.25: Viết một chương trình giao tiếp giữa 2 MCU324P qua TWI thực hiện như sau:
 MCU Master
 Nhấn SW,MCU Master sẽ phát chuỗi ký tự kết thúc bằng mã NULL cất trong Flash ROM
sang MCU Slave.
 Sau đó thu chuỗi ký tự kết thúc bằng mã NULL từ Slave về cất trong SRAM.
 Nhấn SW hiển thị từng ký tự thu được ra PortA cho đến mã NULL.
 Lặp vòng lại từ đầu.
 MCU Slave
 MCU Slave thu chuỗi ký tự từ Master cất trong SRAM
 Chờ MCU Master yêu cầu, phát chuỗi ký tự kết thúc bằng mã NULL cất trong Flash ROM
sang MCU Master
 Hiển thi từng ký tự thu được từ Master ra PortA cho đến mã NULL,thời gian hiển thị mỗi ký
tự cách nhau 0.5s.
 Lặp vòng lại từ đầu
Cho tốc độ truyền TWI = 100KHz, địa chỉ Slave = 0x10.

Giáo Trình Vi xử lý Chương 8 Lưu Phú 79


8.4 Truyền TWI(Two Wired Interface) Hình 8.25
8.4.3 Lập trình các mode TWI
Giải:
 MCU Master:
 Chờ nhấn SW - chương trình con (ctc) SW_RD.
 Khởi động TWI: tốc độ truyền SCL=100KHz, cho phép TWI làm việc - ctc TWI_INIT.
 Phát xung START - ctc TWI_START.
 Phát địa chỉ Slav+W - ctc TWI_WRITE.
 Bắt đầu phát chuỗi ký tự kết thúc bằng mã NULL trong Flash ROM - ctc TWI_WRITE.
 Phát xung STOP - ctc TWI_STOP.
 Phát xung START - ctc TWI_START.
 Phát địa chỉ Slav+R - ctc TWI_WRITE.
 Bắt đầu chờ thu chuỗi ký tự kết thúc bằng mã NULL cất trong SRAM - ctc TWI_READ.
 Phát xung STOP - ctc TWI_STOP.
 Mỗi lần SW nhấn, hiển thị ký tự thu được ra PortA cho đến mã NULL.
 Lặp vòng lại từ đầu.
 Trong mode phát Master không cần đặt TWEA=1. Trong mode thu Master nên đặt TWEA=1
để Master trả về Slave ACK sau mỗi lần nhận data đảm bảo đồng bộ tốt với Slave.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 80
8.4 Truyền TWI(Two Wired Interface)
8.4.3 Lập trình các mode TWI
 MCU Slave:
 Khởi động TWI: đặt địa chỉ Slav,cho phép TWI làm việc - ctc TWI_INIT.
 Chờ nhận đúng địa chỉ (TWINT=1) Slav+W - ctc TWI_DET.
 Bắt đầu thu chuỗi ký tự kết thúc bằng mã NULL cất trong SRAM - ctc TWI_READ.
 Chờ nhận đúng địa chỉ (TWINT=1) Slav+R - ctc TWI_DET.
 Bắt đầu phát chuỗi ký tự kết thúc bằng mã NULL cất trong Flash ROM - ctc TWI_WRITE.
 Hiển thị ký tự thu được ra PortA cho đến mã NULL, thời gian hiển thị mỗi ký tự cách nhau
0.5s - ctc DELAY_500.
 Lặp vòng lại từ đầu.
 Trong cả 2 mô thức phát/thu Slave phải đặt TWEA=1 để Slave nhận đúng địa chỉ của mình
và kết nối bus với Master, mỗi lần nhận dữ liệu xong sẽ trả ACK cho Master, đảm bảo đồng
bộ tốt. Khi Slave muốn dừng thu dữ liệu sẽ xóa TWEA=0, ở lần thu dữ liệu kế tiếp sẽ trả về
Master NACK và tạm ngắt kết nối TWI, Master sẽ phát xung STOP báo dừng truyền TWI.
• CTC TWI_DET nhận dạng địa chỉ của Slave và yêu cầu truy xuất của Master là ghi hay đọc,
bằng cách đọc mã trạng thái sau khi xóa 2 bit TWPS1:0:
 Kiểm tra cờ TWINT,TWINT=1 báo đúng địa chỉ Slave.
 Nếu là địa chỉ Slav+W, thanh ghi TWSR=0x60 báo Slav thu dữ liệu.
 Nếu là địa chỉ Slav+R, thanh ghi TWSR=0xA8 báo Slav phát dữ liệu.
Giáo Trình Vi xử lý Chương 8 Lưu Phú 81
8.4 Truyền TWI(Two Wired Interface)
 Chương trình cho Master
8.4.3 Lập trình các mode TWI
.EQU OUTPORT=PORTA;PORTA hiển thị START: LDI ZH,HIGH(MSG_OUT<<1);Z trỏ đ/c đầu
.EQU OUTPORT_DR=DDRA LDI ZL,LOW(MSG_OUT<<1);bảng MSG
.EQU CONT=PORTC ;PORTC điều khiển ;------------------------------------------------------------------
.EQU CONT_DR=DDRC ; ;Phát data cho Slav
.EQU CONT_IN=PINC ; ;------------------------------------------------------------------
.EQU SCL=0 ;ký hiệu chân SCL RCALL SW_RD ;đọc SW chờ SW nhấn
.EQU SDA=1 ;ký hiệu chân SDA RCALL TWI_START ;phát xung START
.EQU SW=2 ;ký hiệu chân SW LDI R17,(TWI_ADDR<<1);truy xuất ghi Slav
.EQU NULL=$00 ;mã kết thúc chuỗi ký tự ;đ/chỉ TWI_ADDR
.EQU TWI_ADDR=0X10;địa chỉ TWI Slav RCALL TWI_WRITE ;ghi Slav addr.+W
.EQU SR_BUF=0X200 LOOP_WR: LPM R17,Z+ ;nạp data ghi
.ORG 0 PUSH R17 ;cất data
RJMP MAIN RCALL TWI_WRITE ;ghi data ra Slav
.ORG 0X40 POP R17 ;phục hồi data vừa ghi
MAIN: LDI R16,HIGH(RAMEND) CPI R17,NULL ;data=NULL kết thúc đọc
OUT SPH,R16
BRNE LOOP_WR ;khác,tiếp tục đọc Slav
LDI R16,LOW(RAMEND)
OUT SPL,R16 SKIP_WR: RCALL TWI_STOP ;phát xung STOP
LDI R16,0XFF ;----------------------------------------------------------------
OUT OUTPORT_DR,R16 ;Thu data từ Slav
LDI R16,0X00 ;----------------------------------------------------------------
OUT OUTPORT,R16 LDI XH,HIGH(SR_BUF) ;X trỏ đ/chỉ đầu
CBI CONT_DR,SW ;chân SW input LDI XL,LOW(SR_BUF) ;buffer SRAM
SBI CONT,SW;điện trở kéo lên chân SW RCALL TWI_START ;phát xung START
RCALL TWI_INIT ;khởi động TWI Master
Giáo Trình Vi xử lý Chương 8 Lưu Phú 82
8.4 Truyền TWI(Two Wired Interface)
 Chương trình cho Master
8.4.3 Lập trình các mode TWI
LDI R17,(TWI_ADDR<<1|0X01) ;truy xuất ;----------------------------------------------------------
;đọc Slav đ/chỉ TWI_ADDR ;SW_RD đọc trạng thái nút nhấn có chống rung
RCALL TWI_WRITE ;ghi Slav addr.+R ;Chỉ thoát khi có SW nhấn
LOOP_RD: RCALL TWI_READ ;đọc data từ Slav ;Sử dụng R16
ST X+,R17 ;cất vào buffer,tăng con trỏ X ;-----------------------------------------------------------
CPI R17,NULL ;data=NULL kết thúc đọc SW_RD: LDI R16,50 ;kiểm tra SW nhấn 50 lần liên tục
BRNE LOOP_RD ;khác,tiếp tục đọc Slav WAIT0: SBIC CONT_IN,SW
SKIP_RD: RCALL TWI_NAK ;Master phát NACK báo RJMP SW_RD
;Slav kết thúc đọc DEC R16
RCALL TWI_STOP ;phát xung STOP BRNE WAIT0
LDI XH,HIGH(SR_BUF);X trỏ lại đ/chỉ đầu BACK1: LDI R16,50 ;kiểm tra sw nhả 50 lần liên tục
LDI XL,LOW(SR_BUF) ; buffer WAIT1: SBIS CONT_IN,SW
DISP: RCALL SW_RD ;chờ nhấn SW RJMP BACK1
LD R17,X+ ;nạp data từ buffer,tăng X DEC R16
OUT OUTPORT,R17 ;hiển thị data ra PORTA BRNE WAIT1
CPI R17,NULL ;data=NULL RET
BRNE DISP ;khác,tiếp tục
RJMP START ;lăp vòng lại từ đầu  Master truy xuất Slave bằng cách phát đ/chỉ Slave(7 bit)
dịch trái +bit0=R/W(1/0): Slav addr.<<1+R/W

Giáo Trình Vi xử lý Chương 8 Lưu Phú 83


8.4 Truyền TWI(Two Wired Interface)
 Chương trình cho Master
8.4.3 Lập trình các mode TWI
;--------------------------------------------------------- ;----------------------------------------------------------
;TWI_INIT khởi động cổng TWI TWI_WRITE: STS TWDR,R17 ;ghi data
;Đặt tốc độ tuyền=100Khz LDI R17,(1<<TWEN)|(1<<TWINT);cho phép
;--------------------------------------------------------- ;TWI,xóa TWINT
TWI_INIT: LDI R17,8 ;tốc độ truyền SCL=100Khz STS TWCR,R17
STS TWBR,R17 WAIT_WR: LDS R17,TWCR ;chờ cờ TWINT=1 báo
LDI R17,1 SBRS R17,TWINT ; truyền xong
STS TWSR,R17 ;hệ số đặt trước=4 RJMP WAIT_WR
LDI R17,(1<<TWEN) ;cho phép TWI RET
STS TWCR,R17 ;----------------------------------------------------------
RET TWI_READ: ;cho phép TWI,xóa TWINT,trả ACK
;---------------------------------------------------------- LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA)
TWI_START: ;cho phép TWI,START,xóa TWINT STS TWCR,R17
LDI R17,(1<<TWEN)|(1<<TWSTA)|(1<<TWINT) WAIT_RD: LDS R17,TWCR ;chờ cờ TWINT=1 báo
STS TWCR,R17 SBRS R17,TWINT ; truyền xong
WAIT_STA: LDS R17,TWCR ;đọc cờ TWINT RJMP WAIT_RD
SBRS R17,TWINT;chờ cờ TWINT=1 báo LDS R17,TWDR ;đọc data thu được
RJMP WAIT_STA ; truyền xong RET
RET

Giáo Trình Vi xử lý Chương 8 Lưu Phú 84


8.4 Truyền TWI(Two Wired Interface)
 Chương trình cho Master
8.4.3 Lập trình các mode TWI
;--------------------------------------------------  Trong chương trình trên để đơn giản ta không kiểm
TWI_NAK: ;cho phép TWI,xóa TWINT,trả NAK tra tín hiệu ACK từ Slave khi Master phát hoặc đáp
LDI R17,(1<<TWEN)|(1<<TWINT) ứng thu data từ Slave khi Master ở mode thu.
STS TWCR,R17
 Để kiểm tra các trạng thái thu/phát chính xác,ta
WAIT_NAK: LDS R17,TWCR ;chờ cờ TWINT=1
đọc data từ reg.TWSR(xóa 2 bit thấp sau khi đọc)
SBRS R17,TWINT ; báo truyền xong
RJMP WAIT_NAK và kiểm tra theo giá trị TWSR cho ở từng mode và
RET trạng thái tương ứng.
;----------------------------------------------------------
TWI_STOP: ;cho phép TWI,xóa TWINT,STOP
LDI R17,(1<<TWEN)|(1<<TWSTO)|(1<<TWINT)
STS TWCR,R17
RET
;---------------------------------------------------------
.ORG 0X200
MSG_OUT: .DB "ABCDEFGHIJKLMNO",$00
;---------------------------------------------------------

Giáo Trình Vi xử lý Chương 8 Lưu Phú 85


8.4 Truyền TWI(Two Wired Interface)
 Chương trình cho Slave
8.4.3 Lập trình các mode TWI
.EQU OUTPORT=PORTA;PORTA hiển thị LDI R16,0X00 ;Timer1 mode CTC4
.EQU OUTPORT_DR=DDRA STS TCCR1A,R16
.EQU SCL=0 ;ký hiệu chân SCL START: RCALL TWI_INIT ;khởi dộng Slav
.EQU SDA=1 ;ký hiệu chân SDA
LDI ZH,HIGH(MSG_OUT<<1);Z trỏ đ/chỉ đầu
.EQU NULL=$00 ;mã kết thúc chuỗi ký tự
.EQU TF=15624 ;GTĐT OCR1A tạo delay 0.5s LDI ZL,LOW(MSG_OUT<<1);bảng MSG
.EQU TWI_ADDR=0X10;địa chỉ TWI Slav LDI XH,HIGH(SR_BUF) ;X trỏ đ/chỉ đầu
.EQU SR_BUF=0X200 LDI XL,LOW(SR_BUF); buffer SRAM
.ORG 0 RCALL TWI_DET ;nhận dạng Slav, y/cầu truy xuất
RJMP MAIN CPI R18,0X60 ;Slav+W?
.ORG 0X40 BRNE SLAV_T ;khác kiểm tra Slav+R
MAIN: LDI R16,HIGH(RAMEND)
OUT SPH,R16 ;------------------------------------------------------------------
LDI R16,LOW(RAMEND) ;Slav thu data
OUT SPL,R16 ;-----------------------------------------------------------------
LDI R16,0XFF ;OUTPORT=ouput SLA_RD: RCALL TWI_READ ;đọc data từ Master
OUT OUTPORT_DR,R16 ST X+,R17 ;cất vào buffer,tăng con trỏ X
LDI R16,0X00 ;xóa OUTPORT CPI R17,NULL ;data=NULL kết thúc đọc
OUT OUTPORT,R16 BRNE SLA_RD ;khác,tiếp tục đọc data
LDI R16,HIGH(TF) ;GTĐT OCR1A SKIP_SLA: RCALL TWI_NAK;Slav phát NACK báo
STS OCR1AH,R16
LDI R16,LOW(TF) ;kết thúc đọc
STS OCR1AL,R16 RJMP START

Giáo Trình Vi xử lý Chương 8 Lưu Phú 86


8.4 Truyền TWI(Two Wired Interface)
 Chương trình cho Slave
8.4.3 Lập trình các mode TWI
;---------------------------------------------------------------- ;---------------------------------------------------------
;Slav phát data ;TWI_INIT khởi động cổng TWI
;---------------------------------------------------------------- ;Đặt địa chỉ nhận dạng Slav
SLAV_T: CPI R18,0XA8 ;Slav+R? ;---------------------------------------------------------
TWI_INIT: LDI R17,TWI_ADDR<<1 ;địa chỉ Slav+0
BRNE START ;khác ,lặp vòng lại STS TWAR,R17
SLA_WR: LPM R17,Z+ ;nạp data ghi LDI R17,(1<<TWEN)|(1<<TWEA)
PUSH R17 ;cất data ;cho phép TWI,kết nối bus ,trả ACK
RCALL TWI_WRITE ;ghi data ra Master STS TWCR,R17
POP R17 ;phục hồi data vừa ghi RET
CPI R17,NULL;data=NULL kết thúc đọc ;--------------------------------------------------------
BRNE SLA_WR ;khác,tiếp tục ghi data TWI_DET: ;cho phép TWI,xóa TWINT,trả ACK
RCALL TWI_NAK;phát NAK báo k/thúc ghi data LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA)
STS TWCR,R17
LDI XH,HIGH(SR_BUF) ;X trỏ lại đ/chỉ đầu WAIT_DET: LDS R17,TWCR ;đọc cờ TWINT
LDI XL,LOW(SR_BUF) ; buffer SBRS R17,TWINT;chờ cờ TWINT=1 báo đúng
DISP: LD R17,X+ ;nạp data từ buffer,tăng X ;địa chỉ Slav
OUT OUTPORT,R17 ;hiển thị data ra PORTA RJMP WAIT_DET
RCALL DELAY_500 ;delay 0.5s LDS R18,TWSR;đọc mã tr/ thái báo truy xuất
CPI R17,NULL ;data=NULL ANDI R18,0B11111000 ;che 5 bit cao mã tr/ thái
BRNE DISP ;khác,tiếp tục RET
RJMP START ;lặp vòng lại từ đầu
 Trong ctc TWI_INIT đ/c Slave dịch trái trước khi ghi vào
TWAR và bit0(TWGCE)=0:Slav addr.<<1
Giáo Trình Vi xử lý Chương 8 Lưu Phú 87
8.4 Truyền TWI(Two Wired Interface)  Chương trình cho Slave
8.4.3 Lập trình các mode TWI ;--------------------------------------------------
TWI_WRITE: STS TWDR,R17 ;ghi data TWI_NAK: LDI R17,(1<<TWEN)|(1<<TWINT)
LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA) ;cho phép TWI,xóa TWINT,trả NACK,cách ly bus
;cho phép TWI,xóa TWINT,kết nối bus STS TWCR,R17
STS TWCR,R17 WAIT_NAK: LDS R17,TWCR ;chờ cờ TWINT=1 báo
WAIT_WR: LDS R17,TWCR ;chờ cờ TWINT=1 báo SBRS R17,TWINT ; truyền xong
SBRS R17,TWINT ;truyền xong RJMP WAIT_NAK
RJMP WAIT_WR RET
RET ;----------------------------------------------------------
;---------------------------------------------------------- DELAY_500: LDI R16,0B00001100 ;Timer1 mode CTC4,
TWI_READ: ;cho phép TWI,xóa TWINT,trả ACK STS TCCR1B,R16 ; N=256,chạy Timer1
LDI R17,(1<<TWEN)|(1<<TWINT)|(1<<TWEA) WAIT_F: IN R16,TIFR1 ;đọc cờ OCF1A
STS TWCR,R17 SBRS R16,OCF1A ;cờ OCF1A=1 báo đủ 0.5s
WAIT_RD: LDS R17,TWCR ;chờ cờ TWINT=1 báo RJMP WAIT_F ;chờ cờ OCF1A=1
SBRS R17,TWINT ; truyền xong OUT TIFR1,R16 ;xóa cờ OCF1A
RJMP WAIT_RD LDI R16,0X00 ;dừng Timer1
LDS R17,TWDR ;đọc data thu được STS TCCR1B,R16
RET RET
;---------------------------------------------------------
 Phần mô tả hoạt động IC RTC MCP79410 và giao tiếp .ORG 0X200
với MCU324P xem chi tiết trong giáo trình chương 8 MSG_OUT: .DB "abcdefghijklmno",$00

Giáo Trình Vi xử lý Chương 8 Lưu Phú 88

You might also like