;**** MODIFIED LCD CODE --- uses Port C for LCD display **** ;=================================== ; *** LCD support routines *** ;=================================== ;Clear entire LCD and delay for a bit .equ LCDPort = PortC .equ DataDir = DDRC .equ InputPin = PINC 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: ; cbi PORTB,0 ;Turn on LED 0 ldi temp,0 ;Setup port pins out LCDPort,temp ;Pull all pins low ldi temp,0xff ;All pins are outputs out DataDir,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 LCDPort,temp ;to 8-bit mode nop ;nop is data setup time sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde ldi timeout,15 ;Wait at least 15 mS rcall delay ;second rep ldi temp,3 ;Function set out LCDPort,temp nop sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde ldi timeout,15 ;Wait at least 15 ms rcall delay ;third rep ldi temp,3 ;Function set out LCDPort,temp nop sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,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 LCDPort,temp nop sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,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 ; sbi PORTB,0 ;Turn off LED 0 ret ;============================================ ;Wait for LCD to go unbusy lcdwait: ;cbi PORTB,1 ;Turn on LED 1 ldi temp,0xF0 ;Make 4 data lines inputs out DataDir,temp sbi LCDPort,lcdrw ;Set r/w pin to read cbi LCDPort,lcdrs ;Set register select to command waitloop: sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde in lcdstat,InputPin ;Read busy flag ;Read, and ignore lower nibble sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde sbrc lcdstat,3 ;Loop until done rjmp waitloop ; sbi PORTB,1 ;Turn off LED 1 ret ;============================================= ;Send command in temp to LCD lcdcmd: push temp ;Save character rcall lcdwait ldi temp,0xFF ;Make all port D pins outputs out DataDir,temp pop temp ;Get character back push temp ;Save another copy swap temp ;Get upper nibble andi temp,0x0F ;Strip off upper bits out LCDPort,temp ;Put on port nop ;wait for data setup time sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde pop temp ;Recall character andi temp,0x0F ;Strip off upper bits out LCDPort,temp ;Put on port nop sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,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 DataDir,temp pop temp ;Get character back push temp ;Save another copy swap temp ;Get upper nibble andi temp,0x0F ;Strip off upper bits out LCDPort,temp ;Put on port sbi LCDPort,lcdrs ;Register select set for data nop sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde pop temp ;Recall character andi temp,0x0F ;Strip off upper bits out LCDPort,temp ;Put on port sbi LCDPort,lcdrs ;Register select set for data nop sbi LCDPort,lcde ;Toggle enable line nop cbi LCDPort,lcde ret ;============================================= ;Subroutine waits for time equal to value in register timeout ;the register 'timeout' should be loaded before the call delay: tst timeout brne delay ret ; ---------------- (end of program) ------------------