www.pudn.com > 8051_pppsrc.zip > lcddrv.c, change:2001-01-16,size:8130b


#define Byte unsigned char 
 
unsigned char sysCounter; 
 
void PrintOffset (char* Msg, char Offset) { 
	Byte index; 
	LCDClear ();	 
	LCDCtrl (0x80); 
	for (index = 0; index  16; index++) { 
		if (index == 8) LCDCtrl (0xC0); 
		if (Msg[index] == 0) break; 
		LCDData (Msg[(index + Offset) & 0x0F]); 
	} 
} 
 
void PrintMsg (char* Msg) { 
	Byte index; 
	LCDClear ();	 
	LCDCtrl (0x80); 
	for (index = 0; index  16; index++) { 
		if (index == 8) LCDCtrl (0xC0); 
		if (Msg[index] == 0) break; 
		LCDData (Msg[index]); 
	} 
} 
 
void putch (char c) { 
} 
 
#asm 
 
	xref.b	_sysCounter 
	xdef	_LCDInit, _LCD8Ctrl, _LCDCtrl 
	xdef	_LCDClear, _LCDHome, _LCDData, _msDelay 
 
BUSFREQ:	EQU		2 
USCOUNT:	EQU		$0E 
USDELAY:	EQU		BUSFREQ*USCOUNT 
PORTB:		EQU		$01 
DDRB:		EQU		$05 
 
RS:		EQU		1 
RW:		EQU 	        2 
E_LCD:		EQU		3 
 
; ------------------------------------------------------------------- 
; LCD INITIALIZATION 
; Called on startup to initialize the LCD into 4-bit mode 
; Don't use the LCDControl subroutine at first, because initially 
; the LCD is in 8-bit interface mode. 
; ------------------------------------------------------------------- 
_LCDInit: 
	;----------------------------- 
	;Port B setup for LCD module 
	;----------------------------- 
		BCLR	        RS,PORTB                ;Preset control line output levels 
		BCLR	        RW,PORTB 
		BCLR	        E_LCD,PORTB 
		MOV		#$FE,DDRB		;Setup PB1-PB7 as outputs for LCD 
		BCLR	        RS,PORTB		;Preset control line output levels 
		BCLR	        RW,PORTB 
		BCLR	        E_LCD,PORTB 
 
	;------------------------------------------ 
	;8-bit interface at first 
	;------------------------------------------ 
		LDA		#$0F			;Wait 15ms 
		JSR		_msDelay 
 
		LDA		#$30			;Function set 
		JSR		_LCD8Ctrl 
 
		LDA		#5			;Wait 5ms 
		JSR		_msDelay 
 
		LDA		#$30			;Function set 
		JSR		_LCD8Ctrl 
 
		LDA		#1			;Wait 1ms 
		JSR		_msDelay 
 
		LDA		#$30			;Function set 
		JSR		_LCD8Ctrl 
 
		LDA		#$20			;Function set first set up 4-bit 
		JSR		_LCD8Ctrl 
 
	;------------------------------------------ 
	;4-bit operation 
	;------------------------------------------ 
		LDA		#$28			;Second 4-bit function set 
		JSR		_LCDCtrl			;Also 2-line setup 
 
		LDA		#$06			;Increment, no shift 
		JSR		_LCDCtrl 
 
		LDA		#$01			;Clear display, cursor home 
		JSR		_LCDCtrl 
 
		LDA		#$0C			;Display on, cursor off, blink off 
		JSR		_LCDCtrl 
 
		RTS 
 
 
; ------------------------------------------------------------------- 
; If the LCD is in 8-bit mode, just send the upper data bits through 
; the lower port C bits 
; Acc contains control byte 
; ------------------------------------------------------------------- 
_LCD8Ctrl: 
		AND		#$F0			;Mask out lower data bits 
		PSHA					;Store value to send temporarily 
		LDA		PORTB			;Don't change other PORTB pins 
		AND		#$0F			;Mask out UPPER nibble 
		ADD		1,SP			;Add value to send 
		STA		PORTB			;Store to PORTB 
 
		BSET	        E_LCD,PORTB			;Toggle enable line 
		BCLR	        E_LCD,PORTB 
 
 
		JSR		_40usDelay		;40us setup time 
 
		PULA					;Deallocate stack data 
		RTS 
 
; ------------------------------------------------------------------- 
; Write LCD control byte in 4-bit mode 
; For 4-bit mode, need to send the nibbles one at a time, high nibble first 
; Acc contains control byte to send 
; This routine is also used for Address writes to LCD, when MSbit of 
; data byte is set. (i.e. $80 for address 00) 
; ------------------------------------------------------------------- 
_LCDCtrl: 
	;------------------------------------------ 
	;Upper nibble 
	;------------------------------------------ 
		PSHA					;Store data on stack 
		AND		#$F0			;Mask out lower nibble 
		PSHA					;Store upper nibble on stack 
		LDA		PORTB			;Load PORTB contents 
		AND		#$0F			;Mask out UPPER nibble 
		ADD		1,SP			;Add the data nibble 
		STA		PORTB			;Present upper nibble to LCD 
 
		BSET	        E_LCD,PORTB			;Toggle Enable line 
		BCLR	        E_LCD,PORTB 
 
 
		JSR	        _40usDelay		;40us setup time 
 
	;------------------------------------------ 
	;Lower nibble 
	;------------------------------------------ 
		PULA					;Deallocate last temp storage 
		PULA					;Get original data byte 
		AND		#$0F			;Mask out upper nibble 
		NSA					;Put LOWER nibble in UPPER nibble 
		PSHA					;Store onto stack 
		LDA		PORTB			;Get existing PORTB data 
		AND		#$0F			;Mask out lower nibble 
		ADD		1,SP			;Add lower nibble of data byte 
		STA		PORTB			;Store to PORTB 
 
		BSET	        E_LCD,PORTB			;Toggle Enable line 
		BCLR	        E_LCD,PORTB 
 
		PULA					;Deallocate temp storage 
		CMP		#$10			;Longer delay for commands 1 or 2 
		BEQ		LCLonger 
		CMP		#$20 
		BEQ		LCLonger 
 
		JSR		_40usDelay		;40us for any other command 
		RTS					;Return 
 
LCLonger: 
		LDA		#2 
		JSR		_msDelay 
		RTS 
 
; ------------------------------------------------------------------- 
; Write data byte to LCD, using 4-bit mode 
; Acc contains data byte to send 
; ------------------------------------------------------------------- 
_LCDData: 
	;------------------------------------------ 
	;First nibble 
	;------------------------------------------ 
		PSHA					;Store data on stack temporarily 
		AND		#$F0			;Mask out lower nibble 
		PSHA					;Store upper nibble on stack 
		LDA		PORTB			;Load PORTB contents 
		AND		#$0F			;Mask out UPPER nibble 
		ADD		1,SP			;Add the data nibble 
 
		STA		PORTB			;Store to PORTB 
 
		BSET	        RS,PORTB		;Set RS for control 
 
		BSET	        E_LCD,PORTB			;Toggle Enable line 
		BCLR	        E_LCD,PORTB 
 
 
	;------------------------------------------ 
	;Second nibble 
	;------------------------------------------ 
		PULA					;Deallocate temp storage 
		PULA					;Get original data 
		AND		#$0F			;Mask out upper nibble 
		NSA					;Put LOWER nibble in UPPER port pins 
		PSHA					;Store onto stack 
		LDA		PORTB 
		AND		#$0F 
		ADD		1,SP 
		STA		PORTB 
 
		BSET	        E_LCD,PORTB			;Toggle enable line 
		BCLR	        E_LCD,PORTB 
 
 
		JSR		_40usDelay		;40us setup time 
		JSR		_40usDelay		;40us setup time 
 
		BCLR	        RS,PORTB		;Clear RS for data 
 
		JSR		_40usDelay		;40us setup time 
		JSR		_40usDelay		;40us setup time 
 
 
		PULA					;Deallocate temp storage 
		RTS 
 
; ------------------------------------------------------------------- 
; Clear the LCD display by sending the appropriate command byte 
; ------------------------------------------------------------------- 
_LCDClear: 
		LDA		#$01			;Clear display AND home cursor 
		JSR		_LCDCtrl 
		RTS 
 
_LCDHome:        LDA		#$02 
		JSR		_LCDCtrl 
		RTS 
 
; ------------------------------------------------------------------- 
; DELAY ROUTINES 
; ------------------------------------------------------------------- 
; 1ms delay loop, causes _roughly_ 1.3ms delay @ fop = 8MHz 
; uses constant for loop control 
; cycles = 4 + X(6+7+1275) + 3 + 6 
; cycles = 13 + X(1288) 
; where X is value loaded into Acc 
; Causes 1.3ms delay for BUSFREQ values of (1-8 integer values) 
; ------------------------------------------------------------------- 
_1msDelay: 
		PSHA					;2 cycles 
		LDA		#BUSFREQ		;2 
DLLoop:	        DBNZA	        DLSub			;3 
		BRA		DLDone			;3 
DLSub:	         
		MOV		#$FF,_sysCounter 	        ;4 
Here: 
		DBNZ	        _sysCounter,Here	;5 
		BRA		DLLoop			;3 
DLDone:	        PULA					;2 
		RTS					;4 
 
; ------------------------------------------------------------------- 
; Variable ms delay loop 
; Calls DelayLoop Acc number of times 
; ------------------------------------------------------------------- 
_msDelay:         
		JSR   	        _1msDelay 
		DBNZA           _msDelay 
		RTS 
 
; ------------------------------------------------------------------- 
; 40usec delay routine. Important for LCD module, which requires 40us 
; delay for many of its commands, including the "data setup time" 
; 6+X(3) 
; Where X = BUSFREQ*USCOUNT = USDELAY 
; Provides _roughly_ 40us delay 
; ------------------------------------------------------------------- 
_40usDelay: 
		LDA		#BUSFREQ*USCOUNT        ;2 
		DBNZA	        *			;3 
		RTS                                     ;4 
 
#endasm