* Chương 6: Giao tiếp ngoại vi -1- Nguyễn Trọng Luật *
6.1 GIỚI THIỆU CHUNG Các thông số cơ bản của AVR MCU324P - Nguồn cấp điện Vcc: Vcc=1.8 - 5.5V Chọn Vcc=5V - Tần số dao động Fosc: Fosc=0 - 20Mhz Chọn Fosc=8Mhz - Chu kỳ máy MC: 1MC=Tosc 1MC=125ns - Điện áp ngõ vào mức 0 max VILmax : VILmax=0.1Vcc VILmax=0.5V - Điện áp ngõ vào mức 1 min VIHmin: VIHmin=0.7Vcc VIHmin=3.5V - Điện áp ngõ ra mức 0 max VOLmax : VOLmax=0.9V IOL=20mA - Điện áp ngõ ra mức 1 min VOHmin : VOHmin=4.2V IOH=-20mA - Dòng ngõ vào(rĩ)mức 0 IIL: IIL=-1μA(VIL) - Dòng ngõ vào(rĩ)mức 1 IIH: IIH=1μA(VIH) - Dòng ngõ ra max: IOH/Lmax IOH/Lmax=-/+40mA - Tổng các dòng IOL/IOH max portB,D: 100mA - Tổng các dòng IOL/IOH max portA,C: 100mA * Chương 6: Giao tiếp ngoại vi -2- Nguyễn Trọng Luật * 6.2 GIAO TIẾP NÚT NHẤN (SW) – BÀN PHÍM (Keypad)
Vd: viết chương trình mỗi lần nhấn SW
đèn LED D sẽ lần lượt sáng /tối .ORG CBI DDRB, 0 ; PB0 là ngõ vào SBI PORTB, 0 ; điện trở kéo lên ngõ WAIT PB0 SBI DDRC, 0 ; PC0 là ngõ ra Y CBI PORTC, 0 ; PC0=0 Led tối PB0 = 0 WAIT: SBIC PINB,0 ; SW nhấn PB0=0 N RJMP WAIT ; SW không nhấn Nhảy Thực thi công việc PB0=1 có phím ấn ; lập vòng lại LDI R17, $01 ; đảo bit PC0 WAIT: SBIC PINB, 0 IN R18, PORTC RJMP WAIT EOR R18, R17 … (có phím ấn) OUT PORTC, R18 * Chương 6: Giao tiếp ngoại vi -3- RJMP WAIT Nguyễn Trọng Luật * Chống rung phím bằng phần mềm: dùng delay vài chục ms giữa 2 lần xét phím có ấn như lưu đồ: .ORG WAIT CBI DDRB, 0 Y SBI PORTB, 0 Phím ko nhấn SBI DDRC, 0 N CBI PORTC, 0 Delay 10ms WAIT: SBIC PINB,0 ; xét phím PB0 ấn? RJMP WAIT RCALL DL10ms ; delay 10ms Y SBIC PINB,0 ; xét phím PB0 ấn? Phím ko nhấn RJMP WAIT N LDI R17, $01 IN R18, PORTC Thực thi công việc EOR R18, R17 có phím ấn OUT PORTC, R18 RJMP WAIT Vd 6.3: viết chương trình mỗi lần nhấn DL10ms: … SW đèn LED D sẽ lần lượt sáng/tối. … RET Chương trình có chống rung phím * Chương 6: Giao tiếp ngoại vi -4- Nguyễn Trọng Luật * Một phương pháp chống rung SW khác là lập vòng n lần đọc trạng thái SW xác định SW nhấn liên tục và lập vòng n lần đọc trạng thái SW xác định SW nhả liên tục sẽ xác nhận SW có nhấn/nhả. Nếu chỉ 1 lần đọc không đúng trạng thái SW nhấn/nhả sẽ lập vòng đọc lại từ đấu. WAIT_0 WAIT_1 Bđ = n Bđ = n BACK1 BACK2 Y Y chưa nhấn chưa nhả N N
Giảm Bđ Giảm Bđ
Rung phím (Key bounce) Y Y
Bđ 0 Bđ 0 N N
Thực thi công việc
có phím ấn * Chương 6: Giao tiếp ngoại vi -5- Nguyễn Trọng Luật * Vd 6.4: Viết chương trình đọc trạng Chương trình con GET_KEY xác định có phím nhấn thái các SW và hiển thị dãy LED ;------------------------------------------ (bar LED) nếu có 1 SW nhấn/nhả ;GET_KEY đọc trạng thái các SW, như sau(có chống rung SW): ;Trả về R17= mã SW và C=1 nếu có SW nhấn - SW0 : tối dãy LED ;Trả về C=0 nếu SW chưa nhấn - SW1 : sáng 4 LED trọng số thấp ;------------------------------------------ - SW2 : sáng 4 LED trọng số cao GET_KEY: LDI R17, 4 ;R17 vị trí SW - SW3 : sáng toàn bộ dãy LED MOV R20, R17 ;cất số SW vào R20 IN R19, PINB ;đọc SW ANDI R19, 0X0F ;che 4 bit thấp CPI R19, 0X0F ;xem có SW nhấn? BRNE CHK_KEY ;R19 khác 0FH, có SW nhấn NO_KEY: CLC ;SW chưa nhấn,C=0 RJMP EXIT ;thoát CHK_KEY: ROR R19 ;quay phải vào C tìm vị trí SW nhấn BRCC KEY_CODE ;C=0 có SW nhấn DEC R20 ;SW không nhấn giảm vị trí SW BRNE CHK_KEY ;lập vòng xét đến hết số vị trí SW RJMP NO_KEY ;thoát khi không có SW nhấn KEY_CODE: SUB R17, R20 ;R17=mã SW SEC ;C=1 có SW nhấn EXIT: RET * Chương 6: Giao tiếp ngoại vi -6- Nguyễn Trọng Luật * Chương trình VD 6.4 CPI R17, 0 ; mã SW =0? .EQU OUTPORT=PORTC BREQ MD_0 ;hiển thị mode 0 .ORG 0 CPI R17, 1 ; mã SW =1? LDI R16, 0xF0 BREQ MD_1 ;hiển thị mode 1 OUT DDRB, R16 ;PB0-PB3 là ngõ vào CPI R17, 2 ;mã SW=2 LDI R16, 0x0F BREQ MD_2 ;hiển thị mode 2 OUT PORTB, R16 ;điện trở kéo lên CPI R17, 3 ;mã SW=3? PB0-PB3 BREQ MD_3 ;hiển thị mode 3 LDI R16, 0xFF RJMP WAIT_0 ;lập vòng từ đầu OUT DDRC, R16 ;PORTC là ngõ ra MD_0: LDI R18, 0x00 ;hiển thị mode 0 LDI R16, 0x00 OUT OUTPORT, R18 ;dãy LED tối OUT PORTC, R16 ;LED tối RJMP WAIT_0 WAIT_0: LDI R16, 50 ;50 lần xét SW nhấn MD_1: LDI R18,0x0F ;hiển thị mode 1 BACK1: RCALL GET_KEY ;gọi ctc nhận dạng SW OUT OUTPORT, R18 ;sáng 4 LED thấp BRCC WAIT_0 ;C=0 SW chưa nhấn: lập lại RJMP WAIT_0 DEC R16 MD_2: LDI R18,0xF0 ;hiển thị mode 2 BRNE BACK1 ;lập vòng cho đủ số lần đếm OUT OUTPORT, R18 ;sáng 4 LED cao PUSH R17 ; SW đã ấn, cất mã SW RJMP WAIT_0 WAIT_1: LDI R16, 50 ;50 lần xét SW nhả MD_3: LDI R18,0xFF ;hiển thị mode 3 BACK2: RCALL GET_KEY ;gọi ctc nhận dạng SW OUT OUTPORT, R18 ;sáng cả dãy LED BRCS WAIT_1 ;C=1 SW chưa nhả:lập lại RJMP WAIT_0 DEC R16 GET_KEY: … BRNE BACK2 ;lập vòng cho đủ số lần đếm RET POP R17 ;SW đã nhả, lấy lại mã SW * Chương 6: Giao tiếp ngoại vi -7- Nguyễn Trọng Luật * BÀN PHÍM (Keypad) o PB7:PB4: 4 hàng là ngõ vào, có điện trở kéo lên, bình thường mức 1 o PB3:PB0: 4 cột là ngõ ra.
Ý tưởng giải thuật nhận dạng phím nhấn
- Lần lượt xuất mức 0 ra từng cột - Đọc trạng thái từng hàng, nếu có phím nhấn kết nối với cột đang ở mức 0, hàng tương ứng sẽ bị kéo xuống mức 0 - Từ mã quét vị trí cột và vị trí hàng ở mức 0 suy ra mã phím bằng cách cộng vị trí cột và hàng: . Vị trí cột: 0, 1, 2, 3 . Vị trí hàng: 0, 4, 8, C Ví dụ khi xuất mã quét cột PB3:PB0 =0111, Vd 6.5: Viết một chương trình nhận dạng khi nếu đọc hàng về PB7:PB4 =1101, tương ứng nhấn một phím sẽ hiển thị mã ASCII tương ứng vị trí cột 3 (PB3=0) và vị trí hàng 4 (PB5=0). với mã phím. Chống rung phím khi nhấn và nhả. Suy ra mã phím ấn = 3 + 4 = 7
* Chương 6: Giao tiếp ngoại vi -8- Nguyễn Trọng Luật *
Chương trình con GET_KEY16 xác định phím nhấn ;----------------------------------------- ;GET_KEY16 đọc trạng thái các phím, CHK_KEY: ;Trả về R17= mã phím và C=1 nếu có phím nhấn SUBI R17, 4 ;tính vị trí cột ;Trả về C=0 nếu phím chưa nhấn NEG R17 ;bù 2 lấy số dương ;------------------------------------------ SWAP R19 ;đảo sang 4 bit thấp mã hàng LDI R20, 4 ;R20 đếm số lần quét hàng GET_KEY16: SCAN_ROW: LDI R17, 4 ;R17 đếm số lần quét cột ROR R19 ;quay phải qua C tìm bit 0 LDI R20, 0xFE;bắt đầu quét cột 0 BRCC SET_FLG ;C=0 vị trí hàng có phím SCAN_COL: nhấn OUT PORTB, R20 ; INC R17 ;không đúng hàng IN R19, PINB ;đọc trạng thái hàng ;tăng vị trí hàng thêm 4 IN R19, PINB ;đọc lại trạng thái hàng INC R17 ANDI R19, 0xF0 ;che 4 bit cao lấy mã hàng INC R17 CPI R19, 0xF0 ;xem có phím nhấn? INC R17 BRNE CHK_KEY ;R19 khác F0H, có phím nhấn DEC R20 LSL R20 ;quét cột kế tiếp BRNE SCAN_ROW ;quét hết 4 hàng INC R20 ;đặt LSB=1 CLC ;không có phím nhấn C=0 DEC R17 ;giảm số lần quét cột RJMP EXIT ;thoát BRNE SCAN_COL ;tiếp tục quét hết số cột SET_FLG: CLC ;phím chưa nhấn, C=0 SEC ;có phím nhấn C=1 RJMP EXIT ;thoát EXIT: RET * Chương 6: Giao tiếp ngoại vi -9- Nguyễn Trọng Luật * Chương trình con KEY_RD chống rung phím ;------------------------------------------ ;KEY_RD đọc trạng thái phím ;Chống rung phím khi nhấn/nhả 50 lần ;Sử dụng GET_KEY16 nhận dạng phím nhấn ;Chỉ thoát khi có phím nhấn!!! ;------------------------------------------- KEY_RD: LDIR16, 50 ;số lần nhận dạng phím nhấn BACK1: RCALL GET_KEY16 ;gọi ctc nhận dạng phím BRCC KEY_RD ;C=0 phím chưa nhấn lập lại DEC R16 ;đếm số lần nhận dạng phím BRNE BACK1 ;lập vòng cho đủ số lần đếm PUSH R17 ;xác nhận phím nhấn,cất mã phím WAIT_1: LDIR16, 50 ;số lần nhận dạng phím nhả BACK2: RCALL GET_KEY16 ;gọi ctc nhận dạng phím BRCS WAIT_1 ;C=1 phím chưa nhả DEC R16 ;đếm số lần nhận dạng phím BRNE BACK2 ;lập vòng cho đủ số lần đếm POP R17 ;xác nhận phím nhả lấy lại mã phím RET * Chương 6: Giao tiếp ngoại vi - 10 - Nguyễn Trọng Luật * Chương trình VD 6.5 .INCLUDE <M324PDEF.INC> ;------------------------------------------ .EQU OUTPORT=PORTC ;HEX_ASC chuyển từ mã Hex sang mã ASCII .ORG 0 ;Input R17=mã Hex,Output R18=mã ASCII RJMP MAIN ;------------------------------------------ .ORG 0X40 HEX_ASC: MAIN: LDI R16, HIGH(RAMEND);đưa stack lên vùng đ/c CPI R17, 0x0A ;ký tự <$0A? cao BRCS NUM ;C=1 nhỏ hơn OUT SPH, R16 LDI R18, 0x37 ;ký tự chữ LDI R16, LOW(RAMEND) RJMP CHAR OUT SPL, R16 NUM: LDI R18, 0x30 ;ký tự số LDI R16, 0x0F CHAR: ADD R18, R17 ;cộng thêm OUT DDRB, R16 ;PB4-PB7 ngõ vào, $30 ;PB0-PB3 ngõ ra RET LDI R16, 0xFF OUT PORTB, R16 ;điện trở kéo lên ngõ PB0-PB7 KEY_RD: LDI R16, 0xFF … OUT DDRC, R16 ;PORTC là output … LDI R16, 0x00 RET OUT PORTC, R16 ;PORTC=0 LED tối START: RCALLKEY_RD ;ctc đọc phím GET_KEY16: RCALLHEX_ASC ;chuyển mã Hex sang mã ASCII … OUT OUTPORT, R18 ;hiển thị bar LED … RJMP START ;lập vòng từ đầu RET * Chương 6: Giao tiếp ngoại vi - 11 - Nguyễn Trọng Luật *