Maswie BloG

Free Delphi, Visual Basic, Microcontrol, Mechatronic tutorial

Antarmuka LCD dan Keypad 4×4

Posted by maswie2000 on November 5, 2007

Contoh Program ini merupakan program sederhana yang mengaplikasikan AT90S2313 sebagai pengendali LCD 2×16 karakter dan keypad 4×4.

screenhunter_07-nov-05-2027.gif


Gambar 9.1 Skema Rangkaian LCD dan Keypad 4×4

;* Description:Test program with At90S2313 AVR RISC Processor,

;* LCD disply using 4-wire interface and 4×4 keypad.

;* Based on Serasidis Program (http://www.serasidis.gr)

;*

;*

;* 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 4×4 keypad is connected to PortB pins (PB0-PB7)

;* PB0, PB1,PB2, PB3 inputs, PB4, PB5, PB6, PB7 outputs

;*

;*

;* This source is free, for all of you.

;*

;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

.nolist

.include “2313def.inc” ; Define chip particulars

.List

;* * * * * Global register variables

.def wreg =R16 ; General use working register

.def timeout=R17 ; Timeout value passed to subroutine

.def lcsdstat=R18 ; LCD busy/wait sstatus

.def longtime=R19 ; Long time for powerup

.def temp =R2

.def test =R21 ; test register

.def monads=R22

.def decades=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 line =0x80 ;

.equ line =0xC0 ;

.equ col1 =0b11101111 ;

.equ col2 =0b11011111 ;

.equ col3 =0b10111111 ;

.equ col4 =0b01111111 ;

; 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, 3inputs, PB4, 5, 6, 7outputs

out DDRB,temp

ldi temp, 0b00001111 ; enable internal pull-ups on PB0-PB4

out PORTB, temp

rcall lcdinit

; Initialize LCD module

again: ldi monads, $30

ldi decades, $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

key1: 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 key2 ; 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 key4 ; 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 key7 ; 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 decades, $31

rjmp disp_no_of_key

key11: sbic PINB, PB2 ; Pressed key No11 ?

rjmp key12 ; if Not. . .

ldi monades, $31 ;

ldi decades, $31

rjmp disp_no_of_key

key12: sbic PINB, PB3 ; Pressed key No12 ?

rjmp key13 ; if Not. . .

ldi monades, $32 ;

ldi decades, $31

rjmp disp_no_of_key

key13: ldi temp,col4 ;

out PORTB, temp

rcall delay

sbic PINB, PB0 ; Pressed key No103?

rjmp key14 ; if Not. . .

ldi monades, $33 ;

ldi decades, $31

rjmp disp_no_of_key

key14: sbic PINB, PB1 ; Pressed key No14 ?

rjmp key15 ; if Not. . .

ldi monades, $34 ;

ldi decades, $31

rjmp disp_no_of_key

key15: sbic PINB, PB2 ; Pressed key No15 ?

rjmp key16 ; if Not. . .

ldi monades, $35 ;

ldi decades, $31

rjmp disp_no_of_key

key16: sbic PINB, PB3 ; Pressed key No16 ?

rjmp check_keys ; if Not. . .

ldi monades, $36 ;

ldi decades, $31

rjmp disp_no_of_key

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

; Here is typed the message3, message4, decades and monads 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);

ldi ZL, Low(2*message3);

rcall loadbyte

ldi wreg, line2 ; Set address to line 2

rcall lcdcmd

ldi ZH,High(2*message4);

ldi ZL, Low(2*message4);

rcall loadbyte

mov wreg, decades

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 least100 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, 4line 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, 5×7 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, lcde ; 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

anto wreg, 0x0F

out PORTD, wreg

sbi PORTD, lcde ; Toggle enable line

cbi PORTD, lcde

mov wreg, test

anto 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 de 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

anto wreg, 0x0F ; Strip off upper bits

out PORTD, wreg ; Put on port

sbi PORTD,lcdrs ; Register select set for dat

sbi PORTD,lcde ; Toggle enable line

cbi PORTD,icde

mov wreg, test ; Recall character

anto wreg, 0x0F ; Strip off upper bits

out PORTD,wreg ; Put on port

sbi PORTD,lcdrs ; Register select set for dat

sbi PORTD,lcde ; Toggle enable line

cbi PORTD,icde

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 ms using timer 0, delay time passed in timeout delay:

ldi test, 64

cagain:

dec test, 64

brne cagain

dec timeout

brne delay

ret

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

loadbyte:

;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

lpm ; Load byte from program memory into r0

tst r0 ;

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:

.bd “Press any key”, 0

message2:

.bd “please”, 0

message3:

.bd “You pressed”, 0

message4:

.bd “key”, 0

.exit

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: