Full Version : Vasilis' LCD Display with Memory Backup (ASM)
avr >>LCD BASED PROJECTS >>Vasilis' LCD Display with Memory Backup (ASM)


Admin3- 04-19-2006
Serasidis Vasilis LCD Display with MEmory Backup

CODE

;
;* Description: Counter with AT90S1200 AVR RISC Processor and LCD display,
;*   with memory backup,Using 4-wire interface
;* Version:  1.0
;* First writing: 02-01-2000
;* Last Updated: 14-09-2001
;* Target:  AT 90s2313
;* Author:  Serasidis Vasilis
;* Support E-mail: info@serasidis.gr
;* Home page: http://www.serasidis.gr  
;*
;*  
;*
;*  
;*
;***************************************************************************

.nolist   ;Suppress listing of include file
.include "1200def.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
.def monada=R20 ;monades
.def deka=R21 ;dekades
.def ekato=R22 ;ekatontades
.def xilia=R23 ;xiliades
.def test2=R24 ;Test2 register
.def temp =R25
.def monada2=R26 ;monades from eeprom
.def deka2=R27 ;dekades from eeprom
.def ekato2=R28 ;ekatontades from eeprom
.def xilia2=R29 ;xiliades from eeprom
.def test=R30 ;test register

;***** 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
;   ;D4-D7 FROM LCD IS CONNECTED TO PORTD PD0-PD3
; Timer/Counter prescaler values
.equ EEMWE =2
.equ TCK256 =4 ;Timer/Counter runs from CK / 256

;EEPROM related variables

.def     EErtmp  =r25        ;temporary storage of address
.def     EEdrd_s =r1        ;result data byte

.def   EEwtmp  =r24 ;temporary storage of address
.def   EEdwr_s =r31 ;data to write




; Main program entry point on reset

reset:


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
sbi  ACSR,ACD;shut down comparator to save power

ldi longtime,10;Wait 1.5 second for LCD power up
ldi timeout,255;Delay 15 mS
puwait:
rcall delay
dec longtime
brne puwait
main:
rcall lcdinit ;Initialize LCD module
rcall type_msg2
ldi longtime,200;Wait 1.5 second
ldi timeout,255;Delay 15 mS
puwait2:
rcall delay
dec longtime
brne puwait2
;=============================================================

ldi EErtmp,0x3b ;Clear the temporary address  
out EEAR,EErtmp;Move the temporary address to EEAR  
      rcall EERead_seq    ;Get the data from EEPROM to xilia2
      mov xilia,EEdrd_s
      rcall EERead_seq    ;Get the data from EEPROM to ekato2
      mov ekato,EEdrd_s
      rcall EERead_seq    ;Get the data from EEPROM to deka2
      mov deka,EEdrd_s
      rcall EERead_seq    ;Get the data from EEPROM to monada2
      mov monada,EEdrd_s

from_telos:

ldi EErtmp,0x04 ;Clear the temporary address  
out EEAR,EErtmp;Move the temporary address to EEAR
      rcall EERead_seq    ;Get the data from EEPROM to xilia2
      mov xilia2,EEdrd_s
      rcall EERead_seq    ;Get the data from EEPROM to ekato2
      mov ekato2,EEdrd_s
      rcall EERead_seq    ;Get the data from EEPROM to deka2
      mov deka2,EEdrd_s
      rcall EERead_seq    ;Get the data from EEPROM to monada2
      mov monada2,EEdrd_s
rcall lcdclr ;Clear LCD screen
rjmp pbwait

f_pgm:
ldi monada,0x30
ldi deka,  0x30
ldi ekato, 0x30
ldi xilia, 0x30
rcall lcdclr ;Clear LCD screen
pbwait: rcall type_msg;Type the message


keys: ldi wreg,0xc7;Set address to line 2,but 11 points right
rcall lcdcmd

sbis PINB,3 ;Check for PB4 (Power off )
rjmp store2 ;If the power its off, go to "store2"

sbis PINB,5 ;Check for button PB5 (^)"programm"
rjmp pgm ;If pressed goto programming (pgm)
sbis PINB,6 ;Check for button  PB6 "Reset"
rjmp f_pgm ;
sbic PINB,7 ; Pressed button PB7 ?
rjmp keys ;If no check again

cpi monada,0x39;Check if monada is overflowed
breq zero_monada;If yes go to zero_monada

mov wreg,xilia
rcall lcdput ;Print on LCD the xilia
mov wreg,ekato
rcall lcdput ;Print on LCD the ekato
mov wreg,deka
rcall lcdput ;Print on LCD the deka
inc monada
mov wreg,monada
rcall lcdput ;Print on LCD the monada
rcall check_counts;Go to check if the current revolutions are
  ;the same with the stored.  

debounce:
sbis PINB,7 ;Wait for button release PB7
rjmp debounce
rjmp keys

zero_monada:

ldi monada,0x2f
cpi deka,0x39
breq zero_deka
inc deka
rjmp pbwait

zero_deka:

ldi deka,0x30
cpi ekato,0x39
breq zero_ekato
inc ekato
rjmp pbwait

zero_ekato:

ldi ekato,0x30
cpi xilia,0x39
breq te ;zero_xilia
inc xilia
rjmp pbwait

zero_xilia:

ldi xilia,0x30
cpi xilia,0x3b
breq te
rjmp pbwait
te:
rjmp telos
;===============================================================
;        The messages table
;===============================================================
type_msg:
ldi wreg,0x80;Set address to line 1
rcall lcdcmd

ldi EErtmp,0x08 ;Clear the temporary address  
out EEAR,EErtmp;Move the temporary address to EEAR  
again: rcall EERead_seq    ;Get the data from EEPROM to xilia2
mov wreg,eedrd_s
rcall lcdput
dec eedrd_s
brne  again
ldi wreg,0xC0;Set address to line 2
rcall lcdcmd
ldi WREG,' '
rcall lcdput
mov wreg,xilia2
rcall lcdput ;print on LCD  
mov wreg,ekato2
rcall lcdput ;print on LCD  
mov wreg,deka2
rcall lcdput ;print on LCD  
mov wreg,monada2
rcall lcdput ;print on LCD  
ldi wreg,' '
rcall lcdput ;print on LCD  
ldi wreg,' '
rcall lcdput ;print on LCD  
mov wreg,xilia
rcall lcdput ;print on LCD
mov wreg,ekato
rcall lcdput ;print on LCD  
mov wreg,deka
rcall lcdput ;print on LCD
mov wreg,monada
rcall lcdput ;print on LCD
ldi wreg,' '
rcall lcdput ;print on LCD
ldi wreg,'1'
rcall lcdput ;print on LCD
ldi wreg,'.'
rcall lcdput ;print on LCD
ldi wreg,'0'
rcall lcdput ;print on LCD


ret  ;return




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

;***************************************************************************
;*
;* EERead_seq
;*
;* This subroutine increments the address stored in EEAR and reads the
;* EEPROM into the register variable "EEdrd_s".
;*
;*
;***************************************************************************


EERead_seq:
        in EErtmp,EEAR      ;get address
        out EEAR,EErtmp     ;output address
        sbi EECR,EERE       ;set EEPROM Read strobe
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
        sbi EECR,EERE       ;set EEPROM Read strobe 2nd time
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
        in EEdrd_s,EEDR     ;get data
        in EErtmp,EEAR      ;get address
        inc EErtmp          ;increment address
        out EEAR,EErtmp     ;store it
        ret

;==============================================================
;***************************************************************************
;*
;* EEWrite_seq
;*
;* This subroutine increments the EEPROM address by one and waits until the
;* EEPROM is ready for programming. It then programs the EEPROM with
;* register variable "EEdwr_s".

;* Number of words :1200; 7 + return
;*   :8515; 10 + return
;* Number of cycles :1200; 10 + return (if EEPROM is ready)
;*   :8515; 15 + return (if EEPROM is ready)
;* Low Registers used :None
;* High Registers used: :3 (EEdwr_s,EEwtmp,EEwtmph)
;*
;***************************************************************************

EEWrite_seq:

; Write sequence for 90S1200

sbic EECR,EEWE;if EEWE not clear
rjmp EEWrite_seq;    wait more


out EEAR,EEwtmp
out EEDR,EEdwr_s;output data
sbi  EECR,EEMWE;set master write enable
sbi EECR,EEWE;set EEPROM Write strobe
  ;This instruction takes 4 clock cycles since
  ;it halts the CPU for two clock cycles
 inc EEwtmp ;increment address 8515


ret
;=========================================================================

; Clear entire LCD and delay for a bit
lcdclr:
ldi wreg,1 ;Clear LCD command
rcall lcdcmd
ldi timeout,255;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,255;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,0b00100000;Function set, 4 wire, 2 line, 5x7 font
rcall lcdcmd
ldi wreg,0b00001110;Display on,  cursor on, 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:
;;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

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

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

;=================================================================
;   Here is the programming of revolutions
;=================================================================
pgm:
rcall delay
sbis PINB,5 ;Wait for button release PB5 (^)"increase"
rjmp pgm ;If didnt relish goto "pgm"

rcall lcdclr ;Clear LCD screen
ldi test2,0xc6
ldi wreg,0x80;Set address to line 1
rcall lcdcmd

ldi wreg,'S'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'E'
rcall lcdput ;print on LCD the xilia
ldi wreg,'L'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'.'
rcall lcdput ;print on LCD the xilia
ldi wreg,' '
rcall lcdput ;print on LCD the xilia  
ldi wreg,'R'
rcall lcdput ;print on LCD the xilia
ldi wreg,'E'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'V'
rcall lcdput ;print on LCD the xilia
ldi wreg,'O'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'L'
rcall lcdput ;print on LCD the xilia
ldi wreg,'U'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'T'
rcall lcdput ;print on LCD the xilia
ldi wreg,'I'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'O'
rcall lcdput ;print on LCD the xilia
ldi wreg,'N'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'S'
rcall lcdput ;print on LCD the xilia

loop2:
ldi wreg,0xc6;Set address to line 2 + 6
rcall lcdcmd
mov wreg,xilia2
rcall lcdput ;print on LCD the xilia  
mov wreg,ekato2
rcall lcdput ;print on LCD the xilia
mov wreg,deka2
rcall lcdput ;print on LCD the xilia  
mov wreg,monada2
rcall lcdput ;print on LCD the xilia

ldi wreg,0xc6;Set address to line 2 + 6
rcall lcdcmd

loop: sbic PINB,5 ;wait for button press PB5 (^)"increase"
rjmp here ;If didnt pressed goto here
cpi test2,0xc9
breq inc_monada2
cpi test2,0xc8
breq inc_deka2    
cpi test2,0xc7
breq inc_ekato2
cpi test2,0xc6
breq inc_xilia2

here:
sbis PINB,6 ;wait for button press PB6 (Reset)
rjmp store ;If pressed go to "store"

sbic PINB,4 ;Wait for button press PB4 (->)scroll the cersor
rjmp loop ;if not go to next
inc test2
mov wreg,test2;Set address to line 2 + 4
rcall lcdcmd
cpi test2,0xca
breq zero_test

rel:
rcall delay
sbis PINB,4 ;Wait for button release PB4 (->)scroll the cersor
rjmp rel
rjmp loop

zero_test:
ldi test2,0xc5
rjmp rel
inc_monada2:
rcall delay
sbis PINB,5 ;Wait for button relish PB5 (^)"increase"
rjmp inc_monada2;If didnt release goto inc_monada2
inc monada2
mov wreg,monada2
rcall lcdput ;print on LCD the monada2
mov wreg,test2;Set address to line 2 + 4
rcall lcdcmd  
cpi monada2,0x39
breq zero_monada2
rjmp loop

zero_monada2:

ldi monada2,0x2f
rjmp loop

inc_deka2:
rcall delay
sbis PINB,5 ;Wait for button relish PB5 (^)"increase"
rjmp inc_deka2;If didnt release goto inc_monada2
inc deka2
mov wreg,deka2
rcall lcdput ;print on LCD the monada2
mov wreg,test2;Set address to line 2 + 4
rcall lcdcmd  
cpi deka2,0x39
breq zero_deka2
rjmp loop

zero_deka2:

ldi deka2,0x2f
rjmp loop

inc_ekato2:
rcall delay
sbis PINB,5 ;Wait for button relish PB5 (^)"increase"
rjmp inc_ekato2;If didnt release goto inc_monada2
inc ekato2
mov wreg,ekato2
rcall lcdput ;print on LCD the monada2
mov wreg,test2;Set address to line 2 + 4
rcall lcdcmd  
cpi ekato2,0x39
breq zero_ekato2
rjmp loop

zero_ekato2:

ldi ekato2,0x2f
rjmp loop
inc_xilia2:
rcall delay
sbis PINB,5 ;Wait for button release PB5 (^)"increase"
rjmp inc_xilia2;If didnt release goto inc_monada2
inc xilia2
mov wreg,xilia2
rcall lcdput ;print on LCD the monada2
mov wreg,test2;Set address to line 2 + 4
rcall lcdcmd  
cpi xilia2,0x39
breq zero_xilia2
rjmp loop

zero_xilia2:

ldi xilia2,0x2f
rjmp loop

;=======================================================================
;    Store to EEprom routine
;=======================================================================
store:
ldi eewtmp,0x04
mov eedwr_s,xilia2
rcall eewrite_seq
mov eedwr_s,ekato2
rcall eewrite_seq
mov eedwr_s,deka2
rcall eewrite_seq
mov eedwr_s,monada2
rcall eewrite_seq
rjmp f_pgm ;if pressed goto "f_pgm"(its meen From_Pgm)

store2: ldi eewtmp,0x3b
mov eedwr_s,xilia
rcall eewrite_seq
mov eedwr_s,ekato
rcall eewrite_seq
mov eedwr_s,deka
rcall eewrite_seq
mov eedwr_s,monada
rcall eewrite_seq


 ldi temp,0x30 ;turn on sleep mode (Power down mode)
 out MCUCR,temp ;interrupt on low level.
 ldi temp,0x40 ;enable external interrupts
 out GIMSK,temp
 sei  ;enable global interrupts ready

 sleep  ;go to sleep mode

;=======================================================================
;    Its for reset the monada,deka....
;======================================================================


;=======================================================================
;    This routine is to check if the current resisters (monada,xilia...)
;    is the same with monada2,xilia2 ect.
;=======================================================================
check_counts:

cp monada,monada2
breq check_deka
ret
check_deka:
cp deka,deka2
breq check_ekato
ret
check_ekato:
cp ekato,ekato2
breq check_xilia
ret
check_xilia:
cp xilia,xilia2
breq telos
ret
;=======================================================================
telos:

rcall lcdclr ;Clear LCD screen
ldi wreg,0x80;Set address to line 1
rcall lcdcmd



ldi wreg,'R'
rcall lcdput ;print on LCD the xilia
ldi wreg,'E'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'V'
rcall lcdput ;print on LCD the xilia
ldi wreg,'O'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'L'
rcall lcdput ;print on LCD the xilia
ldi wreg,'U'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'T'
rcall lcdput ;print on LCD the xilia
ldi wreg,'I'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'O'
rcall lcdput ;print on LCD the xilia
ldi wreg,'N'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'S'
rcall lcdput ;print on LCD the xilia
ldi wreg,' '
rcall lcdput ;print on LCD the xilia  
ldi wreg,'E'
rcall lcdput ;print on LCD the xilia
ldi wreg,'N'
rcall lcdput ;print on LCD the xilia  
ldi wreg,'D'
rcall lcdput ;print on LCD the xilia
ldi wreg,' '
rcall lcdput ;print on LCD the xilia

ldi wreg,0xc6;Set address to line 2 + 6
rcall lcdcmd
mov wreg,xilia2
rcall lcdput ;print on LCD the xilia2  
mov wreg,ekato2
rcall lcdput ;print on LCD the ekato2
mov wreg,deka2
rcall lcdput ;print on LCD the deka2  
mov wreg,monada2
rcall lcdput ;print on LCD the monada2

halt2:
sbic PINB,6 ;Wait for button pressed PB6 "Reset"
rjmp halt2
rjmp f_pgm ;
;=====================================================================
power_off:






;====================================================================
type_msg2:
ldi wreg,0x80;Set address to line 1
rcall lcdcmd


ldi EErtmp,0x19 ;Clear the temporary address  
out EEAR,EErtmp;Move the temporary address to EEAR  
again2: rcall EERead_seq    ;Get the data from EEPROM to xilia2
mov wreg,eedrd_s
rcall lcdput
dec eedrd_s
brne  again2


ldi wreg,0xc0;Set address to line 2 + 6
rcall lcdcmd

ldi EErtmp,0x2A ;Clear the temporary address  
out EEAR,EErtmp;Move the temporary address to EEAR  
again3: rcall EERead_seq    ;Get the data from EEPROM to xilia2
mov wreg,eedrd_s
rcall lcdput
dec eedrd_s
brne  again3



ret  ;return

;*********************************************************************
;**** EEPROM Data
;****
;*********************************************************************
        .eseg

;EmptyPos:.db 00 ;leave eeprom location 00 empty due to bug
;in AVR that randomly erases the contens
InitString1:.db 0x30,0x30,0x30,0x35
InitString2:.db 0x30,0x30,0x31,0x32
InitString3:.db "TARGET DONE Ver ",1;Strings are 0 ended
InitString4:.db "     GREECE     ",1;Strings are 0 ended
InitString5:.db "  THESSALONIKI  ",1;Strings are 0 ended
InitString6:.db 0x30,0x30,0x30,0x32




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