title "HelloWorld" LIST P=16F630, F=INHX8M #include __CONFIG _INTRC_OSC_NOCLKOUT & _CP_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_OFF #define BANK1 bsf STATUS,RP0 #define BANK0 bcf STATUS,RP0 #define COMPCONTROL b'00010100' ;Used to configure Comparator #define LCDEnable 4 ; The LCD enable pin on Port B #define LCDRS 5; The LCD R/S pins on Port B #define APULLUPS b'00110000'; The LCD E and R/S pins on Port A ; backup spots for registers during interrupt handling w_bak equ 0x20 status_bak equ 0x21 fsr_bak equ 0x22 ;variables LCDAdd equ 0x23 LCDByte equ 0x24 hiByte equ 0x25 loByte equ 0x26 nibToSend equ 0x27 d1 equ 0x28 d2 equ 0x29 ; startup org 0x0 goto Main ; interrupt handler org 0x4 IntHandle ; save registers movwf w_bak swapf STATUS, W clrf STATUS movwf status_bak movfw FSR movwf fsr_bak goto IntHandle_End ; if not, finish up interrupt handling IntHandle_End ; restore all the backed up registers movfw fsr_bak movwf FSR swapf status_bak, W movwf STATUS swapf w_bak, F swapf w_bak, W retfie ; return from interrupt ;FUNCTIONS LCDADD ; makes LCDAdd the current LCD Address nop BCF PORTA,LCDRS movf LCDAdd, 0 movwf LCDByte bsf LCDByte, 7 CALL LCDBYTE bsf PORTA,LCDRS nop nop RETURN LCDENT ; Entry Mode set - currently set to move cursor to right after each write nop BCF PORTA, LCDRS movlw b'00000110' movwf LCDByte CALL LCDBYTE BSF PORTA,LCDRS nop nop RETURN LCDDISP ; turns on display and cursor nop BCF PORTA,LCDRS movlw b'00001110' movwf LCDByte CALL LCDBYTE BSF PORTA,LCDRS nop nop RETURN LCDFUN ; sets up the LCD function byte, for 4 bit control, 2 lines, standard font nop movlw d'2' movwf nibToSend BCF PORTA, LCDRS ; we're sending a command, so R/S must be lo CALL SENDNIB ; due to 4 bit operation, we have to resend the first nibble CALL SHORTDLY movlw b'00101000' movwf LCDByte CALL LCDBYTE BSF PORTA, LCDRS nop nop RETURN LCDCLR ; clears the entire display clrf LCDAdd nop movlw d'1' movwf LCDByte BCF PORTA, LCDRS ; 'cause we are doing a command, set the R/S line lo CALL LCDBYTE ; writes LCDByte to the LCD CALL LONGDLY ; Clearing the LCD takes ages, so a larger delay is needed bsf PORTA, LCDRS ; set the R/S line, ready for characters RETURN LCDCHAR ;use this for displaying characters only, NOT control chars ;keeps track of cursor colation, and word wraps if necessary movf LCDAdd, 0 sublw h'50' btfsc STATUS, Z RETURN CALL LCDBYTE incf LCDAdd, 1 ;check if we have hit the end of the top line movlw d'16' subwf LCDAdd, 0 btfsc STATUS, Z ; skip if not zero GOTO LCDLINE2 ; must go to new line RETURN LCDLINE2 ;here we must go to the new line movlw b'01000000' movwf LCDAdd CALL LCDADD RETURN LCDBYTE ;sends a byte to the LCD, in 4bit fashion ;responsible for breaking up the byte to send into high and low nibbles ;and dumps them to LCD ;NOT responsible for the status of the LCDRS line, nor the major delays ;IN: LCDByte - distructive OUT: hiByte, loByte clrf hiByte ; clears the vars, to prevent bugs clrf loByte bcf STATUS,0 ; get rif of any carry which could screw up the bitshifts rlf LCDByte, 1 rlf hiByte rlf LCDByte, 1 rlf hiByte rlf LCDByte, 1 rlf hiByte rlf LCDByte, 1 rlf hiByte movf LCDByte, 0 movwf loByte swapf loByte, 1 movf hiByte,0 movwf nibToSend CALL SENDNIB movf loByte,0 movwf nibToSend CALL SENDNIB CALL SHORTDLY ; blocks until most instructions are done RETURN SENDNIB; responsible for sending nibble commands to the LCD. ;IN: nibToSend - non-distructive clrf W ; clears W movf nibToSend, 0 movwf PORTC nop bsf PORTA, LCDEnable; pulse the LCD Enable high nop nop bcf PORTA, LCDEnable ; lower LCD Enable nop nop RETURN SHORTDLY ;around 50us ;46 cycles movlw 0x0F movwf d1 SHORTDLY_0 decfsz d1, f goto SHORTDLY_0 ;4 cycles (including call) return LONGDLY ;25ms ;24993 cycles movlw 0x86 movwf d1 movlw 0x14 movwf d2 LONGDLY_0 decfsz d1, f goto $+2 decfsz d2, f goto LONGDLY_0;3 cycles goto $+1 nop ;4 cycles (including call) return LCDBACKSPACE ; acts like a backspace movf LCDAdd,0 andlw b'11111111' btfsc STATUS, Z ; skip if not zero RETURN ; already at end, so ignore backspace sublw h'40' btfsc STATUS, Z ; skip if at start of 2nd line GOTO LCDBSTARTBOTLINE ; correct for moveing up to new line decf LCDAdd, 1; CALL LCDADD ; move back one movlw d'32' ; wipe the current char movwf LCDByte CALL LCDBYTE CALL LCDADD RETURN LCDBSTARTBOTLINE ; correct for moveing up to new line movlw d'15' movwf LCDAdd CALL LCDADD ; put us at 15 movlw d'32' movwf LCDByte CALL LCDBYTE RETURN Main BANK1 call 3ffh movwf OSCCAL clrf TRISA ;set all to output clrf TRISC ;set all to output movlw APULLUPS movwf WPUA BANK0 clrf PORTA ;set all output latches to zero clrf PORTC ;set all output latches to zero CALL LONGDLY CALL LCDFUN ; sets the LCD's function to 4 bit, 2 line, 5x7 font CALL LONGDLY CALL LCDDISP ; Turns on the display and cursor CALL LONGDLY CALL LCDENT ; sets auto increment right after write (like a typewriter) CALL LCDCLR movlw "H" movwf LCDByte CALL LCDCHAR movlw "E" movwf LCDByte CALL LCDCHAR movlw "L" movwf LCDByte CALL LCDCHAR movlw "L" movwf LCDByte CALL LCDCHAR movlw "O" movwf LCDByte CALL LCDCHAR movlw " " movwf LCDByte CALL LCDCHAR movlw "W" movwf LCDByte CALL LCDCHAR movlw "O" movwf LCDByte CALL LCDCHAR movlw "R" movwf LCDByte CALL LCDCHAR movlw "L" movwf LCDByte CALL LCDCHAR movlw "D" movwf LCDByte CALL LCDCHAR END