;************************************************** ; Pic By Example ; LCD1.ASM ; ; (c) 2004, Sergio Tanzilli ; http://www.tanzilli.com ;************************************************** PROCESSOR 16F84A RADIX DEC INCLUDE "P16F84A.INC" ERRORLEVEL -302 __CONFIG 0x3FF1 ;Linee di controllo dell'LCD LCD_RS equ 2 ;Register Select LCD_E equ 3 ;Lcd Enable ;LCD data line bus LCD_DB4 equ 4 ;LCD data line DB4 LCD_DB5 equ 5 ;LCD data line DB5 LCD_DB6 equ 6 ;LCD data line DB6 LCD_DB7 equ 7 ;LCD data line DB7 SET_EN MACRO bsf PORTB,LCD_E ENDM CLEAR_EN MACRO bcf PORTB,LCD_E ENDM EN_STROBE MACRO SET_EN nop CLEAR_EN ENDM ;Alloca nella memoria registri lo spazio per le variabili utilizzate dal programma ORG 0x0C tmpLcdRegister res 2 msDelayCounter res 2 ;Inizio programma ORG 0x00 Start bsf STATUS,RP0 ;Seleziona il banco di registri 1 movlw 00011110B ;Configura le linee della porta A movwf TRISA movlw 00000011B ;Configura le linee della porta B movwf TRISB bcf STATUS,RP0 ;Seleziona il banco di registri 0 ;Inizializza il display LCD call LcdInit ;Posiziona il cursore dell'LCD in posizione 0,0 movlw 0x00 call LcdLocate ;Visualizza "HELLO WORLD" sul display LCD movlw 'H' call LcdSendData movlw 'E' call LcdSendData movlw 'L' call LcdSendData movlw 'L' call LcdSendData movlw 'O' call LcdSendData movlw 0x10 call LcdLocate movlw 'W' call LcdSendData movlw 'O' call LcdSendData movlw 'R' call LcdSendData movlw 'L' call LcdSendData movlw 'D' call LcdSendData movlw ' ' call LcdSendData movlw '!' call LcdSendData ;Blocca il programma su se stesso in un loop ;infinito foreverLoop bcf PORTA,0 movlw 250 call msDelay bsf PORTA,0 movlw 250 call msDelay goto foreverLoop ;********************************************************************** ; Routine di ritardo ; ; W = Ritardo richiesto in ms (con quarzo a 4MHz) ;********************************************************************** msDelay movwf msDelayCounter+1 clrf msDelayCounter+0 ; Loop interno da circa 1 ms msDelayLoop nop decfsz msDelayCounter+0,F goto msDelayLoop nop decfsz msDelayCounter+1,F goto msDelayLoop return ;********************************************************************** ; Inizializza il display LCD ; Questa funzione deve essere chiamata prima di ogni altra funzione ; di gestione dell'LCD ;********************************************************************** LcdInit bcf PORTB,LCD_E ;Disabilita l'LCD bcf PORTB,LCD_RS ;Mette l'LCD in modo comando movlw 250 call msDelay movlw 250 call msDelay movlw 250 call msDelay movlw 250 call msDelay ; Invia all'LCD la sequenza di reset bsf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 EN_STROBE movlw 2 call msDelay EN_STROBE movlw 2 call msDelay EN_STROBE movlw 2 call msDelay ;-------------------------------- bcf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 EN_STROBE movlw 2 call msDelay ;Configura il bus dati a 4 bit movlw 0x28 ;movlw 0x2C call LcdSendCommand ;Entry mode set, increment, no shift movlw 0x06 ;movlw 0x09 call LcdSendCommand ;Display ON, Curson OFF, Blink OFF movlw 0x0C ;movlw 0x07 call LcdSendCommand movlw 0x01 call LcdSendCommand return ;********************************************************************** ; Clear LCD ;********************************************************************** LcdClear movlw 0x01 call LcdSendCommand movlw 2 call msDelay ;DD RAM address set 1st digit movlw 0x80 call LcdSendCommand return ;********************************************************************** ; Locate cursor on LCD ; W = D7-D4 row, D3-D0 col ;********************************************************************** LcdLocate movwf tmpLcdRegister+0 movlw 0x80 movwf tmpLcdRegister+1 movf tmpLcdRegister+0,W andlw 0x0F iorwf tmpLcdRegister+1,F btfsc tmpLcdRegister+0,4 bsf tmpLcdRegister+1,6 movf tmpLcdRegister+1,W call LcdSendCommand return ;********************************************************************** ; Send a data to LCD ;********************************************************************** LcdSendData bsf PORTB,LCD_RS call LcdSendByte return ;********************************************************************** ; Send a command to LCD ;********************************************************************** LcdSendCommand bcf PORTB,LCD_RS call LcdSendByte return ;********************************************************************** ; Send a byte to LCD by 4 bit data bus ;********************************************************************** LcdSendByte ;Save value to send movwf tmpLcdRegister ;Invia i quattro bit piu' significativi bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 btfsc tmpLcdRegister,4 bsf PORTB,LCD_DB4 btfsc tmpLcdRegister,5 bsf PORTB,LCD_DB5 btfsc tmpLcdRegister,6 bsf PORTB,LCD_DB6 btfsc tmpLcdRegister,7 bsf PORTB,LCD_DB7 EN_STROBE movlw 2 call msDelay ;Send lower four bits bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 btfsc tmpLcdRegister,0 bsf PORTB,LCD_DB4 btfsc tmpLcdRegister,1 bsf PORTB,LCD_DB5 btfsc tmpLcdRegister,2 bsf PORTB,LCD_DB6 btfsc tmpLcdRegister,3 bsf PORTB,LCD_DB7 EN_STROBE movlw 2 call msDelay return END