;************************** ;LCD Subroutines ; Clear entire LCD and delay for a bit lcdclr: ldi temp,1 ;Clear LCD command rcall lcdcmd ldi timeout,3 ;Delay 3 mS for clear command rcall delay ret ;================================================ ; Initialize LCD module lcdinit: ldi temp,0 ;Setup port pins out PORTD,temp ;Pull all pins low ldi temp,0xff ;All pins are outputs out DDRD,temp ldi timeout,15 ;Wait at least 15 mS at power up rcall delay ; LCD specs call for 3 repetitions as follows: ;first rep ldi temp,3 ;Function set out PORTD,temp ;to 8-bit mode nop ;nop is data setup time sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde ldi timeout,15 ;Wait at least 15 mS rcall delay ;second rep ldi temp,3 ;Function set out PORTD,temp nop sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde ldi timeout,15 ;Wait at least 15 ms rcall delay ;third rep ldi temp,3 ;Function set out PORTD,temp nop sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde ldi timeout,15 ;Wait at least 15 ms rcall delay ;Now change to 4-wire interface mode ldi temp,2 ;Function set, 4 wire databus out PORTD,temp nop sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde ; Finally, at this point, ; the normal 4 wire command routine (lcdcmd) can be used ldi temp,0b00100000 ;Function set, 4 wire, 1 line, 5x7 font rcall lcdcmd ldi temp,0b00001100 ;Display on, no cursor, no blink rcall lcdcmd ldi temp,0b00000110 ;Address increment, no scrolling rcall lcdcmd ret ;============================================ ; Wait for LCD to go unbusy lcdwait: ldi temp,0xF0 ;Make 4 data lines inputs out DDRD,temp sbi PORTD,lcdrw ;Set r/w pin to read cbi PORTD,lcdrs ;Set register select to command waitloop: sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde in lcdstat,PIND ;Read busy flag ;Read, and ignore lower nibble sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde sbrc lcdstat,3 ;Loop until done rjmp waitloop ret ;============================================= ; Send command in temp to LCD lcdcmd: push temp ;Save character rcall lcdwait ldi temp,0xFF ;Make all port D pins outputs out DDRD,temp pop temp ;Get character back push temp ;Save another copy swap temp ;Get upper nibble andi temp,0x0F ;Strip off upper bits out PORTD,temp ;Put on port nop ;wait for data setup time sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde pop temp ;Recall character andi temp,0x0F ;Strip off upper bits out PORTD,temp ;Put on port nop sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde ret ;============================================= ; Send character data in temp to LCD lcdput: push temp ;Save character rcall lcdwait ldi temp,0xFF ;Make all port D pins outputs out DDRD,temp pop temp ;Get character back push temp ;Save another copy swap temp ;Get upper nibble andi temp,0x0F ;Strip off upper bits out PORTD,temp ;Put on port sbi PORTD,lcdrs ;Register select set for data nop sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde pop temp ;Recall character andi temp,0x0F ;Strip off upper bits out PORTD,temp ;Put on port sbi PORTD,lcdrs ;Register select set for data nop sbi PORTD,lcde ;Toggle enable line nop cbi PORTD,lcde ret ;======================================================================== ;this routine waits for value in timeout in msecs delay: tst timeout brne delay ret