* * Lcd2.asm ---- 16X2 LCD sample program for FOX11 Rev. C board * with BUFFALO monitor * (c)2003, EVBplus.com, Written by Wayne Chu * * Function: This program displays a message on a 16X2 LCD display module * by calling sel_inst(instruction), sel_data and wrt_pulse * subroutines. These subroutines are used for controlling * a different type of LCD display. * * ; DER - 3/22/05: Converted from AS11 syntax to GNU. Minor cleanup, exported functions. ; some handy symbols d40us = 15 ; 15x6us= 90 us, 60us ok ONE_MS = 167 ; for 8 MHz 1000us/6us=167 FIVE_MS = 835 TEN_MS = 1670 PORTF = 0x1403 ;STACK = 0x8FFF REG_SEL = 0x01 ; 0=reg, 1=data ENABLE = 0x02 NOT_REG_SEL = 0xFE NOT_ENABLE = 0xFD NOT_RESET = 0xF7 ; force bit 3 = 0 LCDimg = pfimg LCD_RSimg = pfimg LCD_ENimg = pfimg LCD = PORTF LCD_RS = PORTF LCD_EN = PORTF ; some variables .section .bss temp1: .rmb 1 pfimg: .rmb 1 reset_seq: .rmb 1 disp_ram: .rmb 3 .section .rodata inidsp1: .fcb 2 ; number of instrutions .fcb 0x33 ; reset char .fcb 0x32 ; reset char inidsp2: .fcb 4 ; number of instrutions .fcb 0x28 ; 4bit, 2 line, 5X7 dot .fcb 0x06 ; cursor increment, disable display shift .fcb 0x0c ; display on, cursor off, no blinking .fcb 0x01 ; clear display memory, set cursor to home pos .section .text .global LCD_INI LCD_INI: psha pshx clra staa pfimg staa PORTF ldx #inidsp1 ; point to init. codes. ldaa #1 staa reset_seq ; need more delay for the first reset seq. jsr outins1 ; output codes. ldx #inidsp2 ; point to init. codes. clr reset_seq jsr outins2 ; output codes. pulx pula rts outins1: pshb ; output instruction command. jsr sel_inst ldab 0,x inx onext1: ldaa 0,x jsr wrt_pulse ; initiate write pulse. inx jsr d5ms decb bne onext1 pulb rts outins2: pshb ; output instruction command. jsr sel_inst ldab 0,x inx onext2: ldaa 0,x jsr wrt_pulse ; initiate write pulse. inx decb bne onext2 jsr d5ms pulb rts delay_10ms: d10ms: pshx ldx #TEN_MS bsr del1 pulx rts d5ms: pshx ldx #FIVE_MS bsr del1 pulx rts del1: dex inx dex bne del1 rts sel_data: psha ldaa LCD_RSimg oraa #REG_SEL bra sel_i sel_inst: psha ldaa LCD_RSimg anda #NOT_REG_SEL sel_i: staa LCD_RSimg anda #NOT_RESET ; force bit3=0, no matter what happens staa LCD_RS pula rts * * @ enter, a=data to output * wrt_pulse: pshx psha ; save it tomporarily. anda #0xf0 ; mask out 4 low bits. staa temp1 ; save nibble value. ldaa LCDimg ; get LCD port image. anda #0x0f ; need low 4 bits. oraa temp1 ; add in low 4 bits. staa LCDimg ; save it anda #NOT_RESET ; force bit3=0, no matter what happens staa LCD ; output data bsr enable_pulse ldaa reset_seq beq wrtpls jsr d5ms ; delay for reset sequence wrtpls: pula asla ; move low bits over. asla asla asla staa temp1 ; store temporarily. ldaa LCDimg ; get LCD port image. anda #0x0f ; need low 4 bits. oraa temp1 ; add in loiw 4 bits. staa LCDimg ; save it anda #NOT_RESET ; force bit3=0, no matter what happens staa LCD ; output data bsr enable_pulse pulx rts * enable_pulse: ldaa LCD_ENimg oraa #ENABLE staa LCD_ENimg anda #NOT_RESET ; force bit3=0, no matter what happens staa LCD_EN ldaa LCD_ENimg anda #NOT_ENABLE staa LCD_ENimg anda #NOT_RESET ; force bit3=0, no matter what happens staa LCD_EN pshx ldx #d40us jsr del1 pulx rts .global LCD_LINE1 LCD_LINE1: psha pshb pshx jsr sel_inst ; select instruction ldaa #0x80 ; set starting address for line1 jsr wrt_pulse jsr sel_data ; select data ;ldx #MSG1 ; MSG1 for line1, x points to MSG1 ;ldab #16 ; send out 16 characters jsr msg_out pulx pulb pula rts .global LCD_LINE2 LCD_LINE2: psha pshb pshx jsr sel_inst ldaa #0xC0 ; set starting address for line2 jsr wrt_pulse jsr sel_data ;ldx #MSG2 ; MSG2 for line2, x points to MSG2 ;ldab #16 ; send out 16 characters jsr msg_out pulx pulb pula rts * at entry, x must point to the begining of the message, * b = number of characters to be sent out * msg_out: ldaa 0,x jsr wrt_pulse inx decb bne msg_out rts