; lcdkeypad.asm ; Atualizado: 27 Set 2012 Prof. Celio G. ; MC404 2o Sem 2012 ;********************************************************************************* .nolist .include "m88def.inc" .list .listmac .equ LCDDATA=PORTD .equ LCDCTL=PORTC .EQU ENABLE=0 .EQU RS=1 .EQU RW=2 .def lcdinput = r19 rjmp RESET ;************************************************************************************* lcd_busy: ;test the busy state sbi LCDCTL,RW ; RW high to read cbi LCDCTL,RS ; RS low to read ldi r16,00 ; make port input out ddrd,r16 out LCDDATA,r16 loop: sbi LCDCTL,ENABLE ; begin read sequence in r16,pind ; read it cbi LCDCTL,ENABLE ; set enable back to low ;cbi LCDCTL,RW ; clear the RW back to write mode sbrc r16,7 ; test bit 7, skip if clear rjmp loop ; jump if set ldi r16,0xff ; make port output out ddrd,r16 ret ;*********************************************************************************** lcd_cmd: ; lcd_cmd writes the LCD command in r19 to the LCD cbi LCDCTL,RS ; RS low for command mode cbi LCDCTL,RW ; RW low to write sbi LCDCTL,ENABLE ; Enable HIGH out LCDDATA,lcdinput ; output cbi LCDCTL,ENABLE ; Enable LOW to execute rcall lcd_busy ret ;************************************************************************************ lcd_write: ; lcd_write writes the value in r19 to the LCD sbi LCDCTL,RS ; RS high cbi LCDCTL,RW ; RW low to write sbi LCDCTL,ENABLE ; Enable HIGH out LCDDATA,lcdinput ; output cbi LCDCTL,ENABLE ; Enable LOW to execute rcall lcd_busy ret ;***************************************************************** writemsg: lpm lcdinput,z+ ; load r0 with the character to display ; increment the string counter cpi lcdinput, 0 breq writedone rcall lcd_write rcall lcd_busy rjmp writemsg writedone: ret ;***************************************************************************** lcdinit: ;initialize LCD ldi r16,0xff out ddrd,r16 ;portb is the LCD data port, 8 bit mode set for output out ddrc,r16 ;portc is the LCD control pins set for output ldi lcdinput,$38 ; init the LCD. 8 bit mode, 2*16 lines rcall lcd_cmd ; execute the command ldi lcdinput,1 ; clear screen rcall lcd_cmd ldi lcdinput,14 ; show cursor but dont blink it rcall lcd_cmd ldi lcdinput,2 ; cursor home command rcall lcd_cmd ret magica: ret ;*************************************************************************** msg: .db "Press any key",0 msg2: .db "please (1-16)",0 msg3: .db "You pressed",0 msg4: .db "key: ",0 ;*************************************************************************** RESET: rcall lcdinit ; initialize LCD ldi temp,0b11110000 ; PB0,1,2,3 inputs, PB4,5,6,7 outputs out DDRB,temp ldi temp,0b00001111 ; enable internal pull-ups on PB0-PB4 out PORTB,temp rcall magica ldi temp, $0F out PINB, temp ; all input lines high when no key pressed out PORTB,temp ;enable pullups rcall magica ldi zl,low(msg*2) ; point to message for 1st line ldi zh,high(msg*2) rcall writemsg ; display it ldi lcdinput, $c0 ; go to the beginning of 2nd line rcall lcd_cmd ; do it ldi zl,low(msg2*2) ;point to message for 2nd line ldi zh,high(msg2*2) rcall writemsg ; display it again: ldi monades,$30 ldi dekades,$30 ldi lcdinput, $94 ; go to the beginning of 3rd line rcall lcd_cmd ; do it rcall lcd_busy rcall check_keys ldi zl,low(msg3*2) ; point to message for 3rd line ldi zh,high(msg3*2) rcall writemsg ; display it ldi lcdinput, $d4 ; go to the beginning of 4th line rcall lcd_cmd ; do it rcall lcd_busy ldi zl,low(msg4*2) ;point to message for 4th line ldi zh,high(msg4*2) rcall writemsg ; display it mov r19,monades rcall lcd_write rjmp again ;***** Global register variables .def wreg =R16 ;General use working register .def timeout =R17 ;Timeout value passed to subroutine .def lcdstat =R18 ;LCD busy/wait status .def longtime=R19 ;Long timer for powerup .def temp =R20 .def test =R21 ;test register .def monades =R22 .def dekades =R23 ;***** Other equates .equ col1 =0b11101111 .equ col2 =0b11011111 .equ col3 =0b10111111 .equ col4 =0b01111111 ;========================================================================= ; Check all keys (1-16). ; The comments from the first 4 keys are the same with all other keys. ;========================================================================= check_keys: ldi temp,$0f out PINB,temp out PORTB, temp ldi temp,$10 out DDRB,temp ; set output lines to input, rcall delay ldi temp, $ef out PORTB,temp ;cbi PORTB,4 ; enable column1 rcall delay sbic PINB,PB0 ; if pressed key No1 PB0 goes low rjmp key2 ; if not, check next key ldi monades,$31 ; if yes... ret ; goto type it to LCD key2: sbic PINB,PB1 ; Pressed key No2 ? rjmp key3 ; if not, check next key ldi monades,$34 ; if yes... ret ; goto type it to LCD key3: sbic PINB,PB2 ; Pressed key No3 ? rjmp key4 ; if not, check next key ldi monades,$37 ; if yes... ret ; goto type it to LCD key4: sbic PINB,PB3 ; Pressed key No4 ? rjmp key5 ; if not, check next key ldi monades,'C' ; if yes... ldi dekades,$30 ret ; goto type it to LCD key5: ldi temp,$20 out DDRB,temp ; set output lines to input,except col2 rcall delay cbi PORTB,5 ;enable col 2 rcall delay sbic PINB,PB0 ; pressed key No5 ? rjmp key6 ; if not... ldi monades,$32 ; ret key6: sbic PINB,PB1 ; pressed key No6 ? rjmp key7 ; if not... ldi monades,$35 ; ret key7: sbic PINB,PB2 ; Pressed key No7 ? rjmp key8 ; if not... ldi monades,$38 ret key8: sbic PINB,PB3 ; pressed key No8 ? rjmp key9 ; if not... ldi monades,$30 ret key9: ldi temp, $40 out DDRB, temp ; set output lines to input except col3 rcall delay cbi PORTB,6 ; enable col 3 rcall delay sbic PINB,PB0 ; pressed key No9 ? rjmp key10 ; if not... ldi monades,$33 ; ret key10: sbic PINB,PB1 ; pressed key No10 ? rjmp key11 ; if not... ldi monades,$36 ; ;ldi dekades,$31 ret key11: sbic PINB,PB2 ; pressed key No11 ? rjmp key12 ; if not... ldi monades,$39 ; ;ldi dekades,$31 ret key12: sbic PINB,PB3 ; pressed key No12 ? rjmp key13 ; if not... ldi monades,'E' ; ldi dekades,$20 ret key13: ldi temp, $80 out DDRB, temp ; set output lines to input except col4 cbi PORTB, 7 ; enable col 4 rcall delay sbic PINB,PB0 ; pressed key No13 ? rjmp key14 ; if not... ldi monades,'A' ldi dekades,$30 ret key14: sbic PINB,PB1 ; pressed key No14 ? rjmp key15 ; if not... ldi monades,'S' ; ldi dekades,$30 ret key15: sbic PINB,PB2 ; pressed key No15 ? rjmp key16 ; if not... ldi monades,'M' ldi dekades,$30 ret key16: sbic PINB,PB3 ; pressed key No16 ? rjmp check_keys ; if not, no key pressed, try again ldi monades,'D' ; ldi dekades,$30 ret ;***************************************************************** longdelay: ldi longtime, 180 ldi timeout,255 puwait: rcall delay dec longtime brne puwait ret delay: ; hapsim aceita qualquer valor para delay ;ret ldi test,$10 cagain: dec test brne cagain ret dec timeout brne delay ret