Full Version : Ott's 2313 control of a 4-Wire LCD (ASM)
avr >>LCD BASED PROJECTS >>Ott's 2313 control of a 4-Wire LCD (ASM)


Admin5- 04-19-2006
Charles Ott's lcd.asm

Control 2-line LCD using 4-wire interface

CODE

;   Control 2-line LCD with AT90S2313 AVR RISC Processor

;   Using 4-wire interface

;

;   Charles R. Ott

;   May 22, 1998



.nolist            ;Suppress listing of include file

.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    lcdstat =R18       ;LCD busy/wait status

.def    longtime=R19       ;Long timer for powerup



;***** 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



;   Timer/Counter prescaler values

.equ    TSTOP   =0     ;Stop Timer/Counter

.equ    TCK1    =1     ;Timer/Counter runs from CK

.equ    TCK8    =2     ;Timer/Counter runs from CK / 8

.equ    TCK64   =3     ;Timer/Counter runs from CK / 64

.equ    TCK256  =4     ;Timer/Counter runs from CK / 256

.equ    TCK1024 =5     ;Timer/Counter runs from CK / 1024

.equ    TEXF    =6     ;Timer/Counter runs from external falling edge

.equ    TEXR    =7     ;Timer/Counter runs from external rising edge



.cseg



;   Interrupt vectors



.org    0

   rjmp    reset      ;Reset Vector



.org    INT0addr       ;External Interrupt0 Vector

   reti



.org    INT1addr       ;External Interrupt1 Vector

   reti



.org    ICP1addr       ;Input Capture1 Interrupt Vector

   reti



.org    OC1addr        ;Output Compare1 Interrupt Vector

   reti



.org    OVF1addr       ;Overflow1 Interrupt Vector

   reti



.org    OVF0addr       ;Overflow0 Interrupt Vector

   rjmp    t0int



.org    URXCaddr       ;UART Receive Complete Interrupt Vector

   reti



.org    UDREaddr       ;UART Data Register Empty Interrupt Vector

   reti



.org    UTXCaddr       ;UART Transmit Complete Interrupt Vector

   reti



.org    ACIaddr        ;Analog Comparator Interrupt Vector

   reti





;   Main program entry point on reset



reset:

   ldi wreg,RAMEND;Init Stack Pointer

   out SPL,wreg

   ldi wreg,TSTOP ;Timer 0 off (just in case)

   out TCCR0,wreg ;Stop timer

   ldi wreg,0b00000010;Enable Timer 0 interrupt

   out TIMSK,wreg

   sei        ;Enable interrupts

   ldi wreg,0xFF  ;Turn off all LEDs

   out PORTB,wreg

   ldi wreg,0xFF  ;Make port B pin all outputs

   out DDRB,wreg

   ldi longtime,100   ;Wait 1.5 second for LCD power up

   ldi timeout,256;Delay 15 mS

puwait:

   rcall   delay

   dec longtime

   brne    puwait

main:

   rcall   lcdinit    ;Initialize LCD module

   rcall   lcdclr     ;Clear LCD screen

   ldi wreg,0x80  ;Set address to line 1

   rcall   lcdcmd

   ldi ZH,high(message*2)

   ldi ZL,low(message*2);Init Z-pointer

nextc:

   lpm        ;Get next character from ROM

   tst R0     ;See if at end of message

   breq    line2      ;If so, do next message

   mov wreg,R0    ;Send it

   rcall   lcdput

   adiw    ZL,1       ;Increment Z-pointer

   rjmp    nextc      ;Loop for more

line2:

   ldi wreg,0xC0  ;Set address to line 2

   rcall   lcdcmd

   ldi ZH,high(message2*2)

   ldi ZL,low(message2*2);Init Z-pointer

nextc2:

   lpm        ;Get next character from ROM

   tst R0     ;See if at end of message

   breq    halt       ;If so, quit

   mov wreg,R0    ;Send it

   rcall   lcdput

   adiw    ZL,1       ;Increment Z-pointer

   rjmp    nextc2     ;Loop for more

halt:  

   rjmp    halt       ;Sit here forever.....



;   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:

   cbi PORTB,0    ;Turn on LED 0

   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

;   rcall   strobe     ;Toggle enable line

   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

;   rcall   strobe     ;Toggle enable line

   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

;   rcall   strobe     ;Toggle enable line

   sbi PORTD,lcde ;Toggle enable line

   cbi PORTD,lcde

   ldi wreg,2     ;Function set, 4 line interface

   out PORTD,wreg

;   rcall   strobe     ;Toggle enable line

   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,0b00101000;Function set, 4 wire, 2 line, 5x7 font

   rcall   lcdcmd

   ldi wreg,0b00001100;Display on, no cursor, no blink

   rcall   lcdcmd

   ldi wreg,0b00000110;Address increment, no scrolling

   rcall   lcdcmd

   sbi PORTB,0    ;Turn off LED 0

   ret



;   Wait for LCD to go unbusy

lcdwait:

   cbi PORTB,1    ;Turn on LED 1

   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:

;   rcall   strobe

   sbi PORTD,lcde ;Toggle enable line

   cbi PORTD,lcde

   in  lcdstat,PIND   ;Read busy flag

;   rcall   strobe     ;Read, and ignore lower nibble

   sbi PORTD,lcde ;Toggle enable line

   cbi PORTD,lcde

   sbrc    lcdstat,3  ;Loop until done

   rjmp    waitloop

   sbi PORTB,1    ;Turn off LED 1

   ret



;   Send command in wreg to LCD

lcdcmd:

   push    wreg       ;Save character

   rcall   lcdwait    ;Wait for LCD to be ready

   ldi wreg,0xFF  ;Make all port D pins outputs

   out DDRD,wreg

   pop wreg       ;Get character back

   push    wreg       ;Save another copy

   swap    wreg       ;Get upper nibble

   andi    wreg,0x0F  ;Strip off upper bits

   out PORTD,wreg ;Put on port

;   rcall   strobe

   sbi PORTD,lcde ;Toggle enable line

   cbi PORTD,lcde

   pop wreg       ;Recall character

   andi    wreg,0x0F  ;Strip off upper bits

   out PORTD,wreg ;Put on port

;   rcall   strobe

   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:

   push    wreg       ;Save character

   rcall   lcdwait    ;Wait for LCD to be ready

   ldi wreg,0xFF  ;Make all port D pins outputs

   out DDRD,wreg

   pop wreg       ;Get character back

   push    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

;   rcall   strobe

   sbi PORTD,lcde ;Toggle enable line

   cbi PORTD,lcde

   pop wreg       ;Recall character

   andi    wreg,0x0F  ;Strip off upper bits

   out PORTD,wreg ;Put on port

   sbi PORTD,lcdrs;Register select set for data

;   rcall   strobe

   sbi PORTD,lcde ;Toggle enable line

   cbi PORTD,lcde

   ldi wreg,0xF0  ;Make 4 data lines inputs

   out DDRD,wreg

   ret



;***** Timer 0 overflow interrupt handler

t0int:

   set        ;Set T flag

   ldi wreg,TSTOP ;Timer 0 off

   out TCCR0,wreg ;Stop timer

   reti           ;Done, return



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

delay:

   in  wreg,SREG  ;Save status register

   push    wreg

   out TCNT0,timeout

   clt        ;Clear T

   ldi wreg,TCK256;Timer 0 prescaler, CK / 256

   out TCCR0,wreg ;Run timer

dwait:

   brtc    dwait      ;Wait for timer 0 interrupt to set T

   pop wreg       ;Restore status register

   out SREG,wreg

   ret



message:

   .db "Time 09:45:33 PM",0

message2:

   .db "Temp 75.6",0xDF," F",0





Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.