| CODE |
; ;* 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: Serasidis Vasilis ;* Support E-mail: info@serasidis.gr ;* Home page: 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 4x4 keypad is conected to PortB pins (PB0-PB7) ;* PB0,PB1,PB2,PB3 inputs, PB4,PB5,PB6,PB7 outputs ;* ;* ;* This source its free, for all of you. ;* ;*************************************************************************** .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 |