Path: Home => AVR-Übersicht => Hardware => LCD

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

; TestLcd clears the LCD-Display and displays a text on the LCD

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

; Basics of the LCD operation on the STK200 boad

; Hardware: The 2-line-LCD-Display must be mounted
;LCD
; on the board and connected correctly. It is recommended
; to connect a 14-pin female connector to the backside
; of the LCD display board that fits the male connector
;LCD
; on the STK200. That's all for the hardware, all other
;LCD
; hardware is already on board of the STK200 (lousy
; documentation of this!).
; Software: The access to the LCD is in this case programmed
; in memory-mapped mode, not via I/O commands. This
; has the advantage that the same commands of the RAM
; access can be used, complicated port bits programming
; is avoided and external 32 kB memory can be used in
; parallel. (Example programs for LCD access found in the
; internet are all I/O-mapped and do not run correct with
; the 32 kB memory on board the STK200 in parallel.
; The adress for LCD access is $8000 for commands and
; $C000 for access to the charcater generator and the
; display lines (both read and write).
; As memory-mapped access is too fast for most LCDs
; the WAIT-Bit in the MCUCR register has to be set to insert
; a wait state. This slows down the RAM access, too, but
; should not be a problem in most cases. To speed-up
; RAM access the WAIT-bit could be set to zero during
; times where only RAM access is made and set to 1 again
; when access to the LCD follows.
; Used Ports: The following ports are used, both by LCD and RAM
; access:
; Port A: Alternate use as LSB adress bus and data bus; not
; used during LCD access, but blocked by memory-
; mapped access
; Port C: MSB adress bus for SRAM access; used for LCD
; access: Bit 7 (Adress signal) and 6 (RS signal of
; the LCD)
; Port D: Bit 6 is /RD (Read) on the SRAM, not used by LCD
; access, Bit 7 is /WR (Write) on the SRAM and on the
; LCD
;
; Test program sequence: Sequentially the following steps are
; executed:
; 0. Wait until the LCD is not busy any more
; 1. Clear the LCD
; 2. Set the transfer mode to 8-bit, a fixed display window and
; define other display properties
; 3. Output to lines of text on the LCD window
; Before each operation takes place a LED is switched on
; to allow debugging the single steps. If all steps are executed
; correct LED 4 is on and the text on the LCD is visible
; (if not visible: correct contrast setting of the LCD).
;
; Structure of the software: All LCD operations are programmed as
; subroutines and so can be exported and used in other programs
; easily. Used registers are: mp=Allround register for handing
; values to subroutines; R26/27=XL/XH is a 16-bit-adress
; for SRAM/LCD-access commands ST X and LD X
;

; Load 8515-library

.NOLIST
.INCLUDE "8515def.inc"
.LIST

; Registers

.def   mp = R16 ; Multi-Purpose
.def   test = R17 ; Counts the test phases for debugging

; Reset-/Interrupt-Vector

   RJMP   main

; Subroutines for LCD access

LcdWt: ; Wait until the LCD-Busy-Flag is zero
   LDI   XH,0x80 ; Upper byte of RAM adress of LCD
   LDI   XL,0x00 ; Lower Byte of RAM-Adresse of LCD
   LD   mp,X ; Read Busy flag und AC-Adress
   ROL   mp ; Shift Bit 7 to carry flag
   BRCS   LcdWt ; If one, then busy, repeat
   RET

LcdCl:
; Clear the LCD
   LDI   mp,0x01 ; Clear command is 01h

LcdBef: ; Command byte in mp to LCD, if it is ready
   PUSH   mp ; Command in mp to stack
   RCALL   LcdWt ; Wait until LCD is not busy
   POP   mp ; Pop command from stack
   ST   X,mp ; Command to LCD
   RET ; End of subroutine

LcdInit: ; Init mode of LCD
   LDI   mp,0b00111000 ; 8-Bit-Transfer, not four bit
   RCALL   LcdBef ; command to LCD
   LDI   mp,0b00000110 ; Increment, Display freeze
   RCALL   LcdBef ; command to LCD
   LDI   mp,0b00010000 ; Cursor move, not shift
   RCALL   LcdBef ; command to LCD
   RET ; Back

LcdBu: ; Write character in mp to LCD
   PUSH   mp ; Save character on stack
   RCALL   LcdWt ; Wait until not busy
   POP   mp ; Restore character
   LDI   XH,0xC0 ; Storage of LCD on adress 0C00h
   ST   X,mp ; Write character to LCD
   RET ; Back

LcdTs: ; Write the word "Test" to the current line
   PUSH   mp ; Save the line adress in mp
   RCALL   LcdWt ; Wait for not busy
   POP   mp ; Line adress to mp
   ORI   mp,0x80 ; Set Bit 7 of line adress
   RCALL   LcdBef ; Command to LCD
   LDI   mp,'T' ; Letter T
   RCALL   LcdBu ; Write to LCD
   LDI   mp,'e' ; Letter e
   RCALL   LcdBu ; Write to LCD
   LDI   mp,'s' ; Letter s
   RCALL   LcdBu ; Write to LCD
   LDI   mp,'t' ; Letter t
   RCALL   LcdBu ; Write to LCD
   RET ; Ready, Back

LcdTst:   ; Write the word "Test" to line 1 and 2
   LDI   mp,0x00 ; Line 1 starts at adress 00h
   RCALL   LcdTs ; Write to line 1
   LDI   mp,0x40 ; Line 2 starts at adress 40h
   RCALL   LcdTs ; Write to line 2
   LDI   mp,0b00001111 ; Command Display On, Cursor On und Blink
   RCALL   LcdBef ; Command to LCD
   RET ; Back

; Main program

main:   LDI   mp,LOW(RAMEND) ;Initiate Stackpointer
   OUT   SPL,mp ; for subroutine use
   LDI   mp,HIGH(RAMEND)
   OUT   SPH,mp

; Port B outputs to the LEDs

   LDI   mp,0xFF ; All output
   OUT   DDRB,mp ; to Data Direction

   IN   mp,MCUCR ; Read MCU-Control-Register
   ORI   mp,0xC0 ; Set Bit 7 (SRAM) and Bit 6 (WAIT-STATE)
   OUT   MCUCR,mp

; Here starts the test of the LCD

   LDI   test,0xFE ; Set Bit 0 to 0 = LED 0 on
   OUT   PORTB,test ; LED 0 on
   RCALL   LcdWt ; Wait on busy
       ;if error, stops here with LED 0 on

   SEC ; Set Carry Flag
   ROL   test ; Shift one left = LED 1 on
   OUT   PORTB,test
   RCALL   LcdCl
; Clear LCD

   SEC ; Carry to 1
   ROL   test ; Shift left for LED 2 on
   OUT   PORTB,test
   RCALL   LcdInit
; Init LCD

   SEC ; Set Carry Flag
   ROL   test ; Shift left for LED 3 on
   OUT   PORTB,test
   RCALL   LcdTst
; Write the test lines

   SEC ; Carry on
   ROL   test ; Shift left to LED 4 on
   OUT   PORTB,test

ende:   RJMP   ende
; Loop forever


©2002 by http://www.avr-asm-tutorial.net