⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcddrv.c

📁 基于51的单片机的PPP协议实现
💻 C
字号:
#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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -