;\\\\\\\\\\\\\ISR & Subroutine Section//////////// ;================================================ ; Clear entire LCD and delay for a bit lcdclr: ldi wreg,1 ;Clear LCD command rcall lcdcmd ldi timeout,256 ;Delay 15 mS for clear command rcall delay ret ;================================================ ; Initialize LCD module lcdinit: ldi wreg,0 ;Setup port pins out PORTC,wreg ;Pull all pins low ldi wreg,0xff ;All pins are outputs out DDRC,wreg ldi timeout,256 ;Wait at least 15 mS at power up rcall delay ; LCD specs call for 3 repetitions as follows ldi wreg,3 ;Function set out PORTC,wreg ;to 8-bit mode nop ;nop is data setup time sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde ldi timeout,256 ;Wait at least 15 mS rcall delay ldi wreg,3 ;Function set out PORTC,wreg nop sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde ldi timeout,256 ;Wait at least 15 ms rcall delay ldi wreg,3 ;Function set out PORTC,wreg nop sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde ldi timeout,256 ;Wait at least 15 ms rcall delay ldi wreg,2 ;Function set, 4 line interface out PORTC,wreg nop sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde ldi wreg,0b11110000 ;Make 4 data lines inputs out DDRC,wreg ldi wreg,0b00001000 ;Function set, 4 wire, 2 line, 5x10 font rcall lcdcmd ldi wreg,0b00000000 ;Display on, no cursor, no blink rcall lcdcmd ldi wreg,0b00001111 rcall lcdcmd ldi wreg,0b00000110 ;Address increment, no scrolling rcall lcdcmd ret ;============================================ ; Wait for LCD to go unbusy lcdwait: ldi wreg,0xF0 ;Make 4 data lines inputs out DDRC,wreg sbi PORTC,lcdrw ;Set r/w pin to read cbi PORTC,lcdrs ;Set register select to command waitloop: sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde in lcdstat,PINC ;Read busy flag ;Read, and ignore lower nibble sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde sbrc lcdstat,3 ;Loop until done rjmp waitloop ret ;============================================= ; Send command in wreg to LCD lcdcmd: push wreg ;Save character rcall lcdwait ;Wait for LCD to be ready ldi wreg,0xFF ;Make all port D pins outputs out DDRC,wreg pop wreg ;Get character back push wreg ;Save another copy swap wreg ;Get upper nibble andi wreg,0x0F ;Strip off upper bits out PORTC,wreg ;Put on port nop ;wait for data setup time sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde pop wreg ;Recall character andi wreg,0x0F ;Strip off upper bits out PORTC,wreg ;Put on port nop sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde ldi wreg,0xF0 ;Make 4 data lines inputs out DDRC,wreg ret ;============================================= ; Send character data in wreg to LCD lcdput: push wreg ;Save character rcall lcdwait ;Wait for LCD to be ready ldi wreg,0xFF ;Make all port D pins outputs out DDRC,wreg pop wreg ;Get character back push wreg ;Save another copy swap wreg ;Get upper nibble andi wreg,0x0F ;Strip off upper bits out PORTC,wreg ;Put on port sbi PORTC,lcdrs ;Register select set for data nop sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde pop wreg ;Recall character andi wreg,0x0F ;Strip off upper bits out PORTC,wreg ;Put on port sbi PORTC,lcdrs ;Register select set for data nop sbi PORTC,lcde ;Toggle enable line cbi PORTC,lcde ;cbi PORTC,lcdrs ;-- ldi wreg,0xF0 ;Make 4 data lines inputs out DDRC,wreg ret ;============================================= ;***** Timer 0 overflow interrupt handler t0int: set ;Set T flag ldi wreg,0xFF ;Turn off all LEDs ldi wreg,TSTOP ;Timer 0 off out TCCR0,wreg ;Stop timer reti ;Done, return ;***** Delay n*64 microseconds using timer 0, delay time passed in timeout ; weird construction, interrupt is called like a subroutine delay: in wreg,SREG ;Save status register push wreg out TCNT0,timeout clt ;Clear T ldi wreg,TCK256 ;Timer 0 prescaler, CK / 256 out TCCR0,wreg ;Run timer dwait: brtc dwait ;Wait for timer 0 interrupt to set T pop wreg ;Restore status register out SREG,wreg ret ;============================================= ;--------------Handle the sending of Characters---------------- ; UART needs a character TXempty:in savSREG, SREG ;save processor status tst TXflash ;Is the string in flash memory? breq TXram ;If not, it is in RAM inc ZL ;get the next char from flash lpm ;and put it in r0 rjmp TXfls TXram: inc ZL ;get the next char from RAM ld r0,Z TXfls: tst r0 ;if char is zero then exit breq TXend out UDR, r0 ;otherwise transmit it rjmp TXexit ;exit until next char TXend: clr TXbusy ;no more chars cbi UCR, UDRIE ;clear the TXempty interrupt TXexit: out SREG, savSREG ;restore proc status reti ;back to pgm ;--------------Handle the end of a transfer ------------------ ;--------------May be used to implement extra characteristics----- ; TX done -- buffer is empty -- unused here TXdone: in savSREG, SREG ;save processor status out SREG, savSREG ;restore proc status reti ;back to pgm ;--------------Handle Reading information from the PC---- ; UART read a character RXdone: in savSREG, SREG ;save processor status in RXchar, UDR ;get the character mov wreg,RXchar out SREG, savSREG ;restore proc status reti ;back to pgm ;--------------Wait and do nothing while information is being transmitted--- TXwait: tst TXbusy ;now wait for the tranmission to finish brne TXwait ret printRAM: nextc1: ld R0,Z tst R0 ;See if at end of message breq end1 ;If so, next message wrtit1: mov wreg,R0 ;Send it rcall lcdput adiw ZL,1 ;Increment Z-pointer rjmp nextc1 ;Loop for more end1: ret printfl: nextc2: lpm ;Get next character from ROM tst R0 ;See if at end of message breq end2 ;If so, next message wrtit2: mov wreg,R0 ;Send it rcall lcdput adiw ZL,1 ;Increment Z-pointer rjmp nextc2 ;Loop for more end2: ret