LCD 16F628
LCD 16F628
LCD 16F628
; E pin 6 connects to A2 ; D4-D7 pins 11-14 connect to B0-B3. ; ; Not meant to be the best method, it's just a ; start point. It's no way optimized, it simply work. ; ; If this is not enough to get you started... i don't know ; what else i can do for you ;o) ; ; Enjoy! ; ; Steve AKA mister_e ; include "P16f628.inc" ; include all register declaration __CONFIG _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF & _BODEN_ON & _PWRT E_ON & _WDT_OFF ; Using Internal OSC ; MCLR = I/O ; Disable low voltage programming, PGM pin can be used as st andard I/O ; Enable Brown out detect ; Enable Power-up Timer ; Disable Watch Dog Timer ERRORLEVEL -302 nnoying ; ; Variable definition ; =================== CBLOCK 20H COUNTERA COUNTERB LCDCMD STRPOINTER ENDC ; ; ; CLR=.1 LINE1=.2 LINE2=H'C0' LINE3=H'94' LINE4=H'D4' ; ; ; #DEFINE #DEFINE ; I/O alias definition ==================== EPIN PORTA,2 RSPIN PORTA,1 Constants definition ==================== ; disable bank warning message... just a
; MACRO ; ===== LCD_STRING MACRO STRING, LCDLINE ; ; this macro allow to send a string of character to the LCD ; on a specific LCD line ; ; Using: ; LCD_STRING "HELLO",1 ; will display HELLO on lcd Line 1 ; LOCAL SENDCHAR, ENDSEND,SKIPIT,STRINGDEF MOVLW LINE#V(LCDLINE) CALL CMD GOTO SKIPIT STRINGDEF ADDWF PCL,F DT STRING,.0 SKIPIT CLRF STRPOINTER SENDCHAR MOVF STRPOINTER,W CALL STRINGDEF XORLW .0 BTFSC STATUS,Z GOTO ENDSEND CALL OUT_TXT INCF STRPOINTER,F GOTO SENDCHAR ENDSEND ENDM ; move right LCD LINE constant to W ; point cursor to the line ; jump over string definition
; clear string pointer ; ; ; ; ; ; ; ; move pointer to W call table xor with zero returned value is 0? YES, getout of here NO, send character to LCD increment string pointer do it again
LCD_UDT MACRO STRING, LCDLINE ; ; this macro allow to send a previously defined string of character ; or set of data to the LCD on a specific LCD line ; ; UDT definition ; STRING1 ADDWF PCL,F ; dt "Cheers", .0 ; ; Using ; LCD_UDT STRING,2 ; will display Cheers on lcd Line 2 ; LOCAL SENDCHAR, ENDSEND MOVLW LINE#V(LCDLINE) ; move right LCD line constant to W CALL CMD ; point cursor to the line CLRF SENDCHAR MOVF CALL XORLW BTFSC GOTO CALL INCF GOTO STRPOINTER,W STRING .0 STATUS,Z ENDSEND OUT_TXT STRPOINTER,F SENDCHAR ; ; ; ; ; ; ; ; move pointer to W call table xor with zero returned value is 0 YES, get out of here NO, send character to LCD increment string pointer do it again STRPOINTER ; clear string pointer
ENDSEND ENDM LCD_CLEAR MACRO ; ; Used to clear the lcd screen ; MOVLW CLR CALL CMD ENDM ; ; ------; ORG 0 GOTO START ; ; ; START BANKSEL CLRF CLRF MOVLW MOVWF PORTA PORTA PORTB .7 CMCON ; clears PORTA ; clears PORTB ; ****** DON'T REMOVE ****** -------------------------< PROGRAM START >----------------------
BANKSEL TRISA CLRF TRISA CLRF TRISB CALL ; ; ; MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL MOVLW CALL DELAY1SEC
; PORTA = all output ; PORTB= all output ; more than safe lcd start-up delay
LCD initialisation ================== ; 33H ; CMD ; 4 bit mode ; 32H ; CMD ; 4 bit mode, enter 4 bit mode ; 28H ; CMD ; Function set [4bit, 4lines,5X7] ; 0CH ; CMD ; turn on display ; 01H ; CMD ; clear display ; 06H ; CMD ; entry mode ; ; ---------< end initialisation >-----------; string , line
DISPLAYSTUFF
"programming in asm" " is really a" " pain in the" " ass"
,1 ,2 ,3 ,4
CALL DELAY1SEC CALL DELAY1SEC LCD_CLEAR LCD_UDT LCD_UDT LCD_UDT LCD_UDT STRING1,1 STRING2,2 STRING3,3 STRING4,4
; wait 1 second
CALL DELAY1SEC CALL DELAY1SEC LCD_CLEAR GOTO DISPLAYSTUFF ; ; ; STRING1 STRING2 STRING3 STRING4 ; ; ; ADDWF PCL,F DT "But",.0 ADDWF PCL,F DT "it's working",.0 ADDWF PCL,F DT "and easy",.0 ADDWF PCL,F DT "to learn... ROFL",.0 ------------------------< SUBROUTINE AREA >--------------------------------------------< UDT string definition >----------------------
DELAY100US ; ; Generate 100 uSec delay ; BANKSEL OPTION_REG MOVLW B'00001000' ; Prescaler 1:1 MOVWF OPTION_REG BANKSEL TMR0 MOVLW .157 GOTO START_TMR0 ; ------------------------------------DELAY2MS ; ; generate 2mSec delay ; BANKSEL OPTION_REG MOVLW B'00000010' ; Prescaler 1:8 MOVWF OPTION_REG
BANKSEL TMR0 MOVLW .6 GOTO START_TMR0 ; -----------------------------------DELAY1SEC ; ; generate 1 sec delay ; BANKSEL OPTION_REG MOVLW B'00000111' ; Prescaler 1:256 MOVWF OPTION_REG BANKSEL COUNTERB MOVLW .15 ; MOVWF COUNTERB ; load COUNTERB ; 1:256=~65 mSec ; 15*65mSec =~ 1Sec LOAD_AGAIN BANKSEL TMR0 ; MOVLW 0 ; clear timer CALL START_TMR0 ; wait 65mSec BANKSEL COUNTERB ; DECFSZ COUNTERB,F ; decrement COUNTERB GOTO LOAD_AGAIN ; delay loop not finished yet, do it again RETURN ; 15 loops done, bye bye! ; -------------------------------------------------------------START_TMR0 BCF INTCON, T0IF ; clear TMR0 overflow MOVWF TMR0 ; load timer BTFSS INTCON, T0IF ; overflow? GOTO $-1 ; NO, wait again RETURN ; YES, delay done, bye bye ! ; -----------------------------------------------CMD ; ; send command to lcd ; BANKSEL PORTA BCF RSPIN ; command mode BCF EPIN ; enable lcd GOTO SENDDATA ; OUT_TXT ; ; Send character/data to lcd ; BANKSEL PORTA BSF RSPIN ; data mode BCF EPIN ; clear E SENDDATA ; ; ; ; ; ; This will send data stored in W to the LCD 1. Split W in two nibble, 2. send high nibble, 3. send the low nibble
MOVF LCDCMD,W ANDLW H'0F' keep low nibble MOVWF PORTB send it to the lcd CALL TOGGLE_E toggle E BCF RSPIN clear RS CALL DELAY2MS wait 2mSec RETURN ; ----------------------------------------------------------------TOGGLE_E ; ; this will toggle lcd E pin ; WHY? BECAUSE IT'S WORKING LIKE THAT :o) ; BANKSEL PORTA BSF EPIN NOP NOP BCF EPIN NOP NOP RETURN END
; ; ; ; ; ; ; ; ; ; ; ; ;
copy W into LCDCMD swap nibble to send high nibble first keep low nibble send it to LCD toggle E