Kamis, 16 Juni 2011

LCD DAN KEYPAD




program yang digunakan :
---------------------------

;* Description: Test program with AT90S2313 AVR RISC Processor,
;* LCD display using 4-wire interface and 4x4 keypad.
;*
;* Writed at: 27-05-2003
;* Target: AT 90s2313
;* Author: tom
;*
;* Home page: electronicindonesia.blogspot.com 
;*
;* LCD rs pin connected to PD6
;* LCD r/w pin connected to PD5
;* LCD e pin connected to PD4 
;* D4-D7 FROM LCD IS CONNECTED TO PORTD PD0-PD3
;* The 4x4 keypad is conected to PortB pins (PB0-PB7)
;* PB0,PB1,PB2,PB3 inputs, PB4,PB5,PB6,PB7 outputs
;*
;*
;*
;***************************************************************************

.include "2313def.inc" ;Define chip particulars


;***** 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 lcdrs =PD6 ;LCD rs pin connected to PD6
.equ lcdrw =PD5 ;LCD r/w pin connected to PD5
.equ lcde =PD4 ;LCD e pin connected to PD4
.equ line1 =0x80 ;1ç ãñáììç ôïõ LCD
.equ line2 =0xC0 ;2ç ãñáììç ôïõ LCD
.equ col1 =0b11101111 ;Êïëüíá 1
.equ col2 =0b11011111 ;Êïëüíá 1
.equ col3 =0b10111111 ;Êïëüíá 1
.equ col4 =0b01111111 ;Êïëüíá 1



; Main program entry point on reset

reset:


ldi temp,RAMEND
out SPL,temp ;Init Stack Pointer


rcall longdelay ;Delay some time
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 lcdinit ;Initialize LCD module
again: ldi monades,$30
ldi dekades,$30
rcall lcdclr ;Clear the LCD
ldi wreg,line1 ;Set address to line 1
rcall lcdcmd
ldi ZH,high(2*message1) ;Type the message1
ldi ZL,low(2*message1) ;to the LCD
rcall loadbyte

ldi wreg,line2 ;Set address to line 2
rcall lcdcmd
ldi ZH,high(2*message2) ;Type the message2
ldi ZL,low(2*message2) ;to the LCD
rcall loadbyte

;=========================================================================
; Check all keys (1-16).
; The comments from the first 4 keys are the same with all other keys.
;=========================================================================
check_keys:
ldi temp,col1 ;Enable column1
out PORTB,temp 
rcall delay 

sbic PINB,PB0 ; Pressed key No1 ?
rjmp key2 ; if Not, check next key
ldi monades,$31 ; if yes...
rjmp disp_no_of_key ; goto type it to LCD

key2: sbic PINB,PB1 ; Pressed key No2 ?
rjmp key3 ; if Not, check next key
ldi monades,$32 ; if yes...
rjmp disp_no_of_key ; goto type it to LCD

key3: sbic PINB,PB2 ; Pressed key No3 ?
rjmp key4 ; if Not, check next key
ldi monades,$33 ; if yes...
rjmp disp_no_of_key ; goto type it to LCD

key4: sbic PINB,PB3 ; Pressed key No4 ?
rjmp key5 ; if Not, check next key
ldi monades,$34 ; if yes...
rjmp disp_no_of_key ; goto type it to LCD

key5: ldi temp,col2 ; Disable the first column...
out PORTB,temp ; and enable the second
rcall delay

sbic PINB,PB0 ; Pressed key No5 ?
rjmp key6 ; if Not...
ldi monades,$35 ;
rjmp disp_no_of_key

key6: sbic PINB,PB1 ; Pressed key No6 ?
rjmp key7 ; if Not...
ldi monades,$36 ;
rjmp disp_no_of_key

key7: sbic PINB,PB2 ; Pressed key No7 ?
rjmp key8 ; if Not...
ldi monades,$37 ;
rjmp disp_no_of_key

key8: sbic PINB,PB3 ; Pressed key No8 ?
rjmp key9 ; if Not...
ldi monades,$38 ;
rjmp disp_no_of_key

key9: ldi temp,col3 ;
out PORTB,temp
rcall delay

sbic PINB,PB0 ; Pressed key No9 ?
rjmp key10 ; if Not...
ldi monades,$39 ;
rjmp disp_no_of_key

key10: sbic PINB,PB1 ; Pressed key No10 ?
rjmp key11 ; if Not...
ldi monades,$30 ;
ldi dekades,$31
rjmp disp_no_of_key

key11: sbic PINB,PB2 ; Pressed key No11 ?
rjmp key12 ; if Not...
ldi monades,$31 ;
ldi dekades,$31
rjmp disp_no_of_key

key12: sbic PINB,PB3 ; Pressed key No12 ?
rjmp key13 ; if Not...
ldi monades,$32 ;
ldi dekades,$31
rjmp disp_no_of_key

key13: ldi temp,col4 ;
out PORTB,temp
rcall delay

sbic PINB,PB0 ; Pressed key No13 ?
rjmp key14 ; if Not...
ldi monades,$33 ;
ldi dekades,$31
rjmp disp_no_of_key

key14: sbic PINB,PB1 ; Pressed key No14 ?
rjmp key15 ; if Not...
ldi monades,$34 ;
ldi dekades,$31
rjmp disp_no_of_key

key15: sbic PINB,PB2 ; Pressed key No15 ?
rjmp key16 ; if Not...
ldi monades,$35 ;
ldi dekades,$31
rjmp disp_no_of_key

key16: sbic PINB,PB3 ; Pressed key No16 ?
rjmp check_keys ; if Not...
ldi monades,$36 ;
ldi dekades,$31
rjmp disp_no_of_key

;=========================================================================
; Here is typed the message3 ,message4, dekades and monades to LCD
;=========================================================================
disp_no_of_key:
rcall lcdclr ; Clear the LCD
ldi wreg,line1 ; Set address to line 1
rcall lcdcmd
ldi ZH,high(2*message3) ; Load high part of byte address into ZH
ldi ZL,low(2*message3) ; Load low part of byte address into ZL
rcall loadbyte

ldi wreg,line2 ; Set address to line 2
rcall lcdcmd
ldi ZH,high(2*message4) ; Load high part of byte address into ZH
ldi ZL,low(2*message4) ; Load low part of byte address into ZL
rcall loadbyte
mov wreg,dekades
rcall lcdput
mov wreg,monades
rcall lcdput
rcall longdelay ;Wait some time 
rjmp again

;=========================================================================
; Clear entire LCD and delay for a bit
;=========================================================================
lcdclr:
ldi wreg,1 ;Clear LCD command
rcall lcdcmd
ldi timeout,256 ;Delay 15 mS for clear command
rcall delay
ret


;=========================================================================
; Initialize LCD module
;=========================================================================

lcdinit:

ldi wreg,0 ;Setup port pins
out PORTD,wreg ;Pull all pins low
ldi wreg,0xff ;All pins are outputs
out DDRD,wreg
ldi timeout,256 ;Wait at least 15 mS at power up
rcall delay
ldi wreg,3 ;Function set
out PORTD,wreg
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
ldi timeout,65 ;Wait at least 4.1 mS
rcall delay
ldi wreg,3 ;Function set
out PORTD,wreg
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
ldi timeout,2 ;Wait at least 100 uS
rcall delay
ldi wreg,3 ;Function set
out PORTD,wreg
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
ldi wreg,2 ;Function set, 4 line interface
out PORTD,wreg
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
ldi wreg,0b11110000 ;Make 4 data lines inputs
out DDRD,wreg

; At this point, the normal 4 wire command routine can be used

ldi wreg,0b00100000 ;Function set, 4 wire, 2 line, 5x7 font
rcall lcdcmd
ldi wreg,0b00001100 ;Display on, cursor off, blink off
rcall lcdcmd
ldi wreg,0b00000110 ;Address increment, no scrolling
rcall lcdcmd

ret

; Wait for LCD to go unbusy
lcdwait:

ldi wreg,0xF0 ;Make 4 data lines inputs
out DDRD,wreg
sbi PORTD,lcdrw ;Set r/w pin to read
cbi PORTD,lcdrs ;Set register select to command
waitloop:

sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
in lcdstat,PIND ;Read busy flag
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
sbrc lcdstat,3 ;Loop until done
rjmp waitloop

ret

; Send command in wreg to LCD
lcdcmd:

mov test,wreg
rcall lcdwait
ldi wreg,0xFF
out DDRD,wreg
mov wreg,test
mov test,wreg
swap wreg
andi wreg,0X0F
out portD,wreg
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
mov wreg,test
andi wreg,0x0F ;Strip off upper bits
out PORTD,wreg ;Put on port
sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
ldi wreg,0xF0 ;Make 4 data lines inputs
out DDRD,wreg
ret 

; Send character data in wreg to LCD
lcdput:
mov test,wreg ;Save character
rcall lcdwait ;Wait for LCD to be ready
ldi wreg,0xFF ;Make all port D pins outputs
out DDRD,wreg
mov wreg,test ;Get character back
mov test,wreg ;Save another copy
swap wreg ;Get upper nibble
andi wreg,0x0F ;Strip off upper bits
out PORTD,wreg ;Put on port
sbi PORTD,lcdrs ;Register select set for data

sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
mov wreg,test ;Recall character
andi wreg,0x0F ;Strip off upper bits
out PORTD,wreg ;Put on port
sbi PORTD,lcdrs ;Register select set for data

sbi PORTD,lcde ;Toggle enable line
cbi PORTD,lcde
ldi wreg,0xF0 ;Make 4 data lines inputs
out DDRD,wreg
ret

longdelay:
ldi longtime,180 ;
ldi timeout,256 ;
puwait:
rcall delay
dec longtime
brne puwait
ret

;***** Delay n*64 microseconds using timer 0, delay time passed in timeout
delay: 

ldi test,64 
cagain: dec test
brne cagain
dec timeout
brne delay
ret

;=========================================================================
loadbyte:
;=========================================================================
lpm ; Load byte from program memory into r0

tst r0 ; Check if we've reached the end of the message
breq return ; If so, quit

mov wreg,r0
rcall lcdput ; Echo received char

adiw ZL,1 ; Increase Z registers
rjmp loadbyte

return: ret ;return
;=========================================================================


message1:
.db "Press any key",0
message2:
.db "please (1-16)",0
message3:
.db "You pressed",0
message4:
.db "key:",0
◄ Newer Post Older Post ►