* ******************************************************* * Milwaukee School of Engineering * CS391 - Computer Embedded System Design * May 2007 * Marek Handl * * Based on LCDPRINT.ASM from Charles Hacker EAS, Wed Jul 22 09:45:50 1998 * ******************************************************* * LCD display * writes strings from memory to LCD * API for writing a string, clearing display, moving to second line, moving to beginning * if the first string is longer than one line it automatically continues on the 2nd line * technical details * to operate LCD the board needs to be in single chip mode * single chip mode cannot use extended RAM * therefore the LCD operating routine needs to be in zero-page memory (using 0x10) * in two lines mode - second line begins after 40 charecters of the 1st line * when writing to LCD, PORTB is used for R/W and RS bits * PORTC is used for B0-B7 bits * registers ******************************************** PORTA = 0x1000 sPORTA = 0x00 PORTB = 0x1004 sPORTB = 0x04 PORTC = 0x1003 sPORTC = 0x03 HPRIO = 0x103C ; Highest Priority Interrupt and misc. sHPRIO = 0x3C DDRC = 0x1007 ; Data Direction register for port C sDDRC = 0x07 SPCR = 0x1028 ; SPI control Register sSPCR = 0x28 SPSR = 0x1029 SPDR = 0x102A ; SCI Data Register BAUD = 0x102B ; SCI Baud Rate Control Register SCCR1 = 0x102C ; SCI Control Register 1 SCCR2 = 0x102D ; SCI Control Register 2 SCSR = 0x102E ; SCI Status Register SCDR = 0x102F ; SCI Data Register * constants ********************************************* single = 0b00100000 ; single chip mode TDRE = 0x80 ; Transmit Data Register Empty TRENA = 0x0C ; Transmit, Receive ENAble RDRF = 0x20 ; Receive Data Register Full PD_WOM = 0x20 brate = 0xB0 ; Baud Rate lcd_routine = 0x10 ; adress of lcd routine (it's in zero page memory because of single chip mode) lcd_temp = 0x09 ; address of a temp variable in single chip mode * ******************************************************* .section .bss pointer: .rmb 2 ; pointer to a charecter being displayed count: .rmb 1 ; how many characters have been displayed so far temp: .rmb 1 ; used for counting * ******************************************************* .section .rodata ; strings are null terminated mess1: .asciz "abcdefghijklmnopqrstuvwxyz" mess2: .asciz "Second line" mess3: .asciz "Third line" * ******************************************************* .section .text .global _start _start: ;initialization lds #_stack clr count ;bra 1f ldx #0x1000 bclr sSPCR, X PD_WOM ldaa #brate staa BAUD ldaa #TRENA staa SCCR2 jsr copy_routine ; copy LCD writing routine to zero page clra ; command ldab #0x0C ; Display On / Cursor Off / Flash Off jsr lcd_routine clra ; command ldab #0x38 ; two line display jsr lcd_routine jsr clear 1: ldx #mess2 stx pointer jsr print ; jsr new_line ldx #mess3 stx pointer ; jsr print ; jsr clear finito: jmp finito * ******************************************************* * Print a string to LCD * Starting address of the string in "pointer" * String is terminated with a null character * ******************************************************* print: ldx pointer ldaa #0x02 ; print command ldab 0, X ; character to be displayed beq 9f ; string is terminated with a "00" character inx stx pointer jsr lcd_routine ; print the charecter to the lcd display inc count ldaa count cmpa #16 ; first line is full bne 8f jsr nl_fill 8: bra print 9: rts * ******************************************************* * New Line Character - move to the second line * uses "temp" as a temp variable * ******************************************************* new_line: ldaa #16 suba count ; add spaces to the end of the line adda #24 staa temp bra 1f nl_fill: ldaa #24 ; number of character between the end of the 1st line and the beginning of the 2nd line staa temp 1: ldaa #0x02 ; print command ldab #32 ; space character jsr lcd_routine dec temp bne 1b clr count rts * ******************************************************* * Clear Display * Moves cursor to the beginning too * ******************************************************* clear: clra ldab #0x01 ; Clear Display jsr lcd_routine clra ldab #0x02 jsr lcd_routine ; Move cursor home clr count rts * ******************************************************* * Moves cursor to the beginning of the 1st line * ******************************************************* home: clra ldab #0x02 ; move cursor to beginning of 1st line jsr lcd_routine clr count rts * ******************************************************* * Copy LCD routine to zero page memory * necessary for single chip mode * ******************************************************* copy_routine: ldx #lcd_print ldy #lcd_routine copy_loop: ldaa 0,x staa 0,y inx iny cpx #routine_end bne copy_loop rts * ******************************************************* * LCD routine - prints out a character * command is in acc A * character is in acc B * for the list of possible commands/data see the manual * ******************************************************* lcd_print: sei staa lcd_temp ; save command value ldx #0x1000 bclr sHPRIO, X 0b00100000 ; switch to single chip mode bclr sPORTA, X 0b00010000 ; turn off LCD E line clr sDDRC, X ; port C as input lcd_busy: ldaa #1 staa sPORTB, X ; read operation from LCD bset sPORTA, X 0b00010000 ; frob LCD on ldaa sPORTC, X ; get status bclr sPORTA, X 0b00010000 ; frob LCD off anda #0x80 ; busy flag bne lcd_busy ; wait for LCD ready ldaa #0xFF staa sDDRC, X ; port C as output ldaa lcd_temp staa sPORTB, X ; command (only the 2 LSB are important - R/W and RS bits) stab sPORTC, X ; data (bits DB0-DB7) bset sPORTA, X 0b00010000 bclr sPORTA, X 0b00010000 ; frob LCD bset sHPRIO, X 0b00100000 ; switch back to extended mode cli rts routine_end: nop ; used just as a pointer to the end of the routine