والله ما قصرتوا جزاكم الله كل خير
هذي هي الرسمة النهائية للمشروع
وايضا هذا هو البرنامج
LIST P=16F84, F=INHX8M
; ERRORLEVEL 2
__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC
;************************************************* ****************************
;
; This program interfaces to a Hitachi HD77480-based LC-Display
; Currently a 4 line * 20 characters display module.
;
; This program assembles for an 8-bit data interface.
; See AN587 for 4-bit and 8-bit interfaces.
;
; Program LCD.ASM
; Last update 96-01-12
; Author Peter Ouwehand
;
;************************************************* ****************************
;************************************************* ****************************
; Fosc = 4MHz
; Cycle_time = 1/Fosc / 4
; = 1/(4*10^6) / 4
; = 1uSec
;************************************************* ****************************
include <p16f84.inc>
;************************************************* ****************************
; Equates, I/O, vars
;************************************************* ****************************
RESET_V EQU 0x0000 ; Address of RESET Vector
ISR_V EQU 0x0004 ; Address of Interrupt Vector
OSC_FREQ EQU D'4000000' ; Oscillator Frequency is 4 MHz
LCD_DATA EQU PORTB ; LCD data lines interface
LCD_DATA_TRIS EQU TRISB
LCD_CTRL EQU PORTA ; LCD control lines interface
LCD_LINE0 EQU 0x000
LCD_LINE1 EQU 0x040
LCD_LINE2 EQU 0x014
LCD_LINE3 EQU 0x054
; PORTA bits
LCD_E EQU 2 ; LCD Enable control line
LCD_RW EQU 1 ; LCD Read/Write control line
LCD_RS EQU 0 ; LCD Register-Select control line
; PORTB bits
DB7 EQU 7 ; LCD dataline 7 (MSB)
DB6 EQU 6 ; LCD dataline 6
DB5 EQU 5 ; LCD dataline 5
DB4 EQU 4 ; LCD dataline 4
DB3 EQU 3 ; LCD dataline 3
DB2 EQU 2 ; LCD dataline 2
DB1 EQU 1 ; LCD dataline 1
DB0 EQU 0 ; LCD dataline 0 (LSB)
; misc.
LCD_TEMP EQU 0x020 ; LCD subroutines internal use
TABLE_INDEX EQU 0x021 ; Index to table strings
COUNT EQU 0x022 ; A counter
DELAY equ 0x023 ; Used in DELAYxxx routines
X_DELAY equ 0x024 ; Used in X_DELAYxxx routines
;************************************************* ****************************
; Program start
;************************************************* ****************************
ORG RESET_V ; RESET vector location
RESET GOTO START
;************************************************* ****************************
; This is the Periperal Interrupt routine. Should NOT get here
;************************************************* ****************************
ORG ISR_V ; Interrupt vector location
INTERRUPT BCF STATUS, RP0 ; Select bank 0
GOTO INTERRUPT
;************************************************* ****************************
; Initialize processor registers
;************************************************* ****************************
START ; POWER_ON Reset (Beginning of program)
CLRF STATUS ; Do initialization, Select bank 0
CLRF INTCON ; Clear int-flags, Disable interrupts
CLRF PCLATH ; Keep in lower 2KByte
CLRF PORTA ; ALL PORT output should output Low.
CLRF PORTB
BSF STATUS, RP0 ; Select bank 1
MOVLW 0x0F8 ; RA2-0 outputs, RA4-3 inputs
MOVWF TRISA
MOVLW 0x000 ; RB7-0 outputs
MOVWF TRISB
BSF OPTION_REG, NOT_RBPU
; Disable PORTB pull-ups
BCF STATUS, RP0 ; Select bank 0
CALL LCDINIT ; Initialize LCDisplay
;************************************************* ****************************
; Display some lines, here
; ----------------------
; |This is on line : 0|
; |This is on line : 1|
; |This is on line : 2|
; |This is on line : 3|
; ----------------------
; OK
;************************************************* ****************************
MOVLW 0x030 ; ASCII '0'
MOVWF COUNT
MOVLW LCD_LINE0
CALL LCDSDDA ; Position cursor leftmost on first line
CALL TABLE_MSG ; Display message
MOVLW LCD_LINE0 + 0x013
CALL LCDSDDA ; Position cursor
MOVF COUNT, W
CALL LCDPUTCHAR ; Display line number
INCF COUNT, F
MOVLW LCD_LINE1
CALL LCDSDDA
CALL TABLE_MSG
MOVLW LCD_LINE1 + 0x013
CALL LCDSDDA
MOVF COUNT, W
CALL LCDPUTCHAR
INCF COUNT, F
MOVLW LCD_LINE2
CALL LCDSDDA
CALL TABLE_MSG
MOVLW LCD_LINE2 + 0x013
CALL LCDSDDA
MOVF COUNT, W
CALL LCDPUTCHAR
INCF COUNT, F
MOVLW LCD_LINE3
CALL LCDSDDA
CALL TABLE_MSG
MOVLW LCD_LINE3 + 0x013
CALL LCDSDDA
MOVF COUNT, W
CALL LCDPUTCHAR
;************************************************* ****************************
; Program ends here
; OK
;************************************************* ****************************
LOOP
GOTO LOOP ; Stay here forever
;************************************************* ****************************
; Send a message using a table to output a message
; OK
;************************************************* ****************************
TABLE_MSG
MOVLW 0 ; Startindex of table message
DISP_MSG
MOVWF TABLE_INDEX ; Holds message address
CALL MSG1
ANDLW 0x0FF ; Check if at end of message
BTFSC STATUS, Z ; (zero returned at end)
GOTO TABLE_MSG_END
CALL LCDPUTCHAR ; Display character
MOVF TABLE_INDEX, W ; Point to next character
ADDLW 1
GOTO DISP_MSG
TABLE_MSG_END RETURN
;************************************************* ****************************
; LCD Module Subroutines
;************************************************* ****************************
;
;================================================= ============================
; LCDINIT
; Initilize LC-Display Module
; Should be modified to your needs (i.e. display type, cursor on/off, etc.)
; OK
;================================================= ============================
LCDINIT
; Busy-flag is not yet valid
CLRF LCD_CTRL ; ALL PORT output should output Low.
; power-up delay
MOVLW 0x01E
CALL X_DELAY500 ; 30 * 0.5mS = 15mS
; Busy Flag should be valid from here
MOVLW 0x038 ; 8-bit-interface, 2-lines
CALL LCDPUTCMD
MOVLW 0x000 ; disp.off, curs.off, no-blink
CALL LCDDMODE
CALL LCDCLEAR
MOVLW 0x004 ; disp.on, curs.off
CALL LCDDMODE
MOVLW 0x002 ; auto-inc (shift-cursor)
CALL LCDEMODE
RETURN
;================================================= ============================
; LCD_ENABLE
; Pulses LCD enable pin
; OK
;================================================= ============================
LCD_ENABLE
BSF LCD_CTRL, LCD_E ; LCD E-line High
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;================================================= ============================
; LCDBUSY
; Returns when LCD busy-flag is inactive
; OK
;================================================= ============================
LCDBUSY
BSF STATUS,RP0 ; Select Register page 1
MOVLW 0x0FF ; Set PORTB for input
MOVWF LCD_DATA_TRIS
BCF STATUS, RP0 ; Select Register page 0
BCF LCD_CTRL, LCD_RS; Set LCD for command mode
BSF LCD_CTRL, LCD_RW; Setup to read busy flag
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_DATA, W ; Read busy flag + DDram address
BCF LCD_CTRL, LCD_E ; LCD E-line Low
ANDLW 0x80 ; Check Busy flag, High = Busy
BTFSS STATUS, Z
GOTO LCDBUSY
LCDNOTBUSY BCF LCD_CTRL, LCD_RW
BSF STATUS, RP0 ; Select Register page 1
MOVLW 0x000
MOVWF LCD_DATA_TRIS ; Set PORTB for output
BCF STATUS, RP0 ; Select Register page 0
RETURN
;================================================= ============================
; LCDCLEAR
; Clears display and returns cursor to home position (upper-left corner).
;
;================================================= ============================
LCDCLEAR
MOVLW 0x001
CALL LCDPUTCMD
RETURN
;================================================= ============================
; LCDHOME
; Returns cursor to home position.
; Returns display to original position (when shifted).
;
;================================================= ============================
LCDHOME
MOVLW 0x002
CALL LCDPUTCMD
RETURN
;================================================= ============================
; LCDEMODE
; Sets entry mode of display.
; Required entry mode must be set in W
; b0 : 0 = no display shift 1 = display shift
; b1 : 0 = auto-decrement 1 = auto-increment
; b2-7 : don't care
; OK
;================================================= ============================
LCDEMODE
ANDLW 0x003 ; Strip upper bits
IORLW 0x004 ; Function set
CALL LCDPUTCMD
RETURN
;================================================= ============================
; LCDDMODE
; Sets display control.
; Required display mode must be set in W
; b0 : 0 = cursor blink off 1 = cursor blink on
; b1 : 0 = cursor off 1 = cursor on
; b2 : 0 = display off 1 = display on (display data remains in DDRAM)
; b3-7 : don't care
; OK
;================================================= ============================
LCDDMODE
ANDLW 0x007 ; Strip upper bits
IORLW 0x008 ; Function set
CALL LCDPUTCMD
RETURN
;================================================= ============================
; LCDSCGA
; Sets Character-Generator-RAM address. CGRAM is read/written after
; this setting.
; Required CGRAM address must be set in W
; b0-5 : required CGRAM address
; b6-7 : don't care
;
;================================================= ============================
LCDSCGA
ANDLW 0x03F ; Strip upper bits
IORLW 0x040 ; Function set
CALL LCDPUTCMD
RETURN
;================================================= ============================
; LCDSDDA
; Sets the Display-Data-RAM address. DDRAM data is read/written after
; this setting.
; Required DDRAM address must be set in W
; b0-6 : required DDRAM address
; b7 : don't care
; OK
;================================================= ============================
LCDSDDA
IORLW 0x080 ; Function set
CALL LCDPUTCMD
RETURN
;================================================= ============================
; LCDGADDR
; Returns address counter contents, used for both DDRAM and CGRAM.
; RAM address is returned in W
;
;================================================= ============================
LCDGADDR
BSF STATUS,RP0 ; Select Register page 1
MOVLW 0x0FF ; Set PORTB for input
MOVWF LCD_DATA_TRIS
BCF STATUS, RP0 ; Select Register page 0
BCF LCD_CTRL, LCD_RS; Set LCD for command mode
BSF LCD_CTRL, LCD_RW; Setup to read busy flag
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_DATA, W ; Read busy flag + RAM address
BCF LCD_CTRL, LCD_E ; LCD E-line Low
ANDLW 0x07F ; Strip upper bit
BCF LCD_CTRL, LCD_RW
BSF STATUS, RP0 ; Select Register page 1
MOVLW 0x000
MOVWF LCD_DATA_TRIS ; Set PORTB for output
BCF STATUS, RP0 ; Select Register page 0
RETURN
;================================================= ============================
; LCDPUTCHAR
; Sends character to LCD
; Required character must be in W
; OK
;================================================= ============================
LCDPUTCHAR
MOVWF LCD_TEMP ; Character to be sent is in W
CALL LCDBUSY ; Wait for LCD to be ready
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BSF LCD_CTRL, LCD_RS; Set LCD in data mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_TEMP, W
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;================================================= ============================
; LCDPUTCMD
; Sends command to LCD
; Required command must be in W
; OK
;================================================= ============================
LCDPUTCMD
MOVWF LCD_TEMP ; Command to be sent is in W
CALL LCDBUSY ; Wait for LCD to be ready
BCF LCD_CTRL, LCD_RW; Set LCD in read mode
BCF LCD_CTRL, LCD_RS; Set LCD in command mode
BSF LCD_CTRL, LCD_E ; LCD E-line High
MOVF LCD_TEMP, W
MOVWF LCD_DATA ; Send data to LCD
BCF LCD_CTRL, LCD_E ; LCD E-line Low
RETURN
;************************************************* ****************************
; Delay_time = ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value = (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
;
; i.e. (* 4MHz crystal)
; Delay_time = ((32 * 3) + 4) * 1uSec
; = 100uSec
; DELAY_value = (500uSec - 4) / 3
; = 165.33
; = 165
;************************************************* ****************************
DELAY500 MOVLW D'165' ; +1 1 cycle
MOVWF DELAY ; +2 1 cycle
DELAY500_LOOP DECFSZ DELAY, F ; step 1 1 cycle
GOTO DELAY500_LOOP ; step 2 2 cycles
DELAY500_END RETURN ; +3 2 cycles
;
;
X_DELAY500 MOVWF X_DELAY ; +1 1 cycle
X_DELAY500_LOOP CALL DELAY500 ; step1 wait 500uSec
DECFSZ X_DELAY, F ; step2 1 cycle
GOTO X_DELAY500_LOOP ; step3 2 cycles
X_DELAY500_END RETURN ; +2 2 cycles
;================================================= ============================
; Table message to display
;================================================= ============================
MSG1
addwf PCL ,F ;Jump to char pointed to in W reg
retlw 'T'
retlw 'h'
retlw 'i'
retlw 's'
retlw ' '
retlw 'i'
retlw 's'
retlw ' '
retlw 'o'
retlw 'n'
retlw ' '
retlw 'l'
retlw 'i'
retlw 'n'
retlw 'e'
retlw ' '
retlw ':'
retlw ' '
retlw ' '
retlw '#'
MSG1_END
retlw 0
;
IF ( (MSG1 & 0x0FF) >= (MSG1_END & 0x0FF) )
MESSG "Warning - User Definded: Table 'MSG1' crosses page boundry in computed jump"
ENDIF
END ; End of program
اخواني اريد شرح الكود اذا ممكن
وبدي معلومات عن lcd