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

📄 lcd_avr_005.asm

📁 AVR单片机的典型程序
💻 ASM
字号:
; Serial Driver rutine for Densitron LM4068 LCD display by Per Byrgren
;	ver:	data:			who:	why:
;	0.01	April 29, 2001	PB	First draft
;	0.02	May  5, 2001		PB	Added Big (24x32 bit) chars
;	0.03	May 19, 2001		PB	Fix some minor bugs
;	0.04	May 23, 2001		PB	Use one reg less for counter
;	0.05	May 26, 2001		PB	Finish BIG char

;*********** These .DEFinitions should be defined in the main program *******************
;													*
; .equ		LCD_CDport	=PortA		; Control/Data = A0 pin on Densitron LM4068	*
; .equ		LCD_CDpin	=PA2									*
; .equ		LCD_Cport	=PortA		; Clk = SCL pin on Densitron LM4068		*
; .equ		LCD_Cpin	=PA0									*
; .equ		LCD_Dport	=PortA		; Data = SI pin on Densitron LM4068		*
; .equ		LCD_Dpin	=PA1									*
;													*
; .def		Fetch	= r00			; Must be r00						*
; .def		Line	= r02			; Can be another register				*
; .def		Temp	= r16			; Can be another register above r15		*
; .def		Lcount	= r17			; Can be another register				*
; .def		Xcount	= r18			; Can be another register				*
;													*
;****************************************************************************************

LCD_Init:

; Entry : no parameters
; Destroys TEMP

		cbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Commands
		ldi	TEMP,$E2		; Internal reset
		RCALL	LCD_Write
		ldi	Temp,$C4		; Set output state = 102 x 64 segments
		RCALL	LCD_Write
		ldi	Temp,$A9		; Set duty to 1/64
		RCALL	LCD_Write
		ldi	Temp,$25		; DC/DC ON
		RCALL	LCD_Write

		rcall	LCD_delay		; Delay to allow DC/DC to start up

		ldi	Temp,$ED		; Power-on completion
		rcall	LCD_Write
		ldi	Temp,$AF		; Display ON
		rcall	LCD_Write
		ldi	Temp,$A6		; Segments normal (0=off, 1 = on)
		rcall	LCD_Write
		ldi	Temp,$40		; Set line to top off display
		rcall	LCD_Write
		ldi	Temp,$81		; Contrast 8
		rcall	LCD_Write
		ldi	Temp,$A4		; All segments OFF
		rcall	LCD_Write
		ldi	Temp,$A0		; Normal scan direction
		rcall	LCD_Write
		ret


LCD_Write:
	
; Entry TEMP contains the byte to be sendt to the LCD
; Destroys TEMP

		cbi	LCD_Cport,LCD_Cpin	; Clear CLK just to be sure
		sec
		rol	Temp			; MSB out first
LCD_Wr1:	cbi	LCD_Dport,LCD_Dpin
		brcc	LCD_Wr2
		sbi	LCD_Dport,LCD_Dpin
LCD_Wr2:	nop				; Wait one clock
		sbi	LCD_Cport,LCD_Cpin
		nop
		cbi	LCD_Cport,LCD_Cpin
		lsl	Temp			; All 8 bits ?
		brne	LCD_Wr1		; Loop back if not
		ret

LCD_Char:

; Entry : Temp contains Char to be converted and printed at current cursor location
; Destroys : Temp, Z, Lcount

		ldi	ZH,high(Char_Tabel*2)
		ldi	ZL,low(Char_Tabel*2)

		add	Temp,Temp		; Temp = Temp * 2
		mov	Lcount,Temp		; Save Temp
		add	Temp,Temp		; Multiply Temp again (~*4)
		add	Temp,Lcount		; Now Temp has been Multiplied by 6

		add	ZL,Temp		; Add offset to table to get pointer
		ldi	Temp,0
		adc	ZH,Temp
		sbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Data
		ldi	Lcount,6
LCD_Char1:	lpm				; Fetch,(Z) : Get Data
		mov	Temp,Fetch
		adiw	ZL,1			; Inc Z
		rcall	LCD_Write
		dec	Lcount
		brne	LCD_Char1
		ret


LCD_Big:

; Entry : 	(X+) points to string to be converted and printed at top left position
;		Xcount = number of chars to be printed
; Destroys : Temp, Z, Lcount, Xcount, Line, Base1


; Set Cursor to top left

		clr	Line
		ldi	Temp,4			; 4 lines for big chars
		mov	Base1,Temp
LCD_Big_x:	push	XH			; Save pointer for later
		push	XL
		push	Xcount

		cbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Commands
		ldi	Temp,$B0		; Page 0
		add	Temp,Line
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write

LCD_Big1:	ldi	ZH,high(Char_Tabel*2)
		ldi	ZL,low(Char_Tabel*2)	; Z points to start of Char table (zero)

		ld	Temp,X+
		add	Temp,Temp		; Temp = Temp * 2
		mov	Lcount,Temp		; Save Temp
		add	Temp,Temp		; Multiply Temp again (~*4)
		add	Temp,Lcount		; Now Temp has been Multiplied by 6

		add	ZL,Temp		; Add offset to table to get pointer
		ldi	Temp,0
		adc	ZH,Temp
		sbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Data
		ldi	Lcount,6
LCD_Big2:	push	Line			; Save for later
		lsl	Line			; Multiply by 2
		lpm				; Fetch,(Z) : Get Data
		clr	Temp			; Clear before we "or" anything
		tst	Line
		breq	LCD_Big4		; Skip if first line
LCD_Big3:	lsr	Fetch			; Shift 2 bits out per line
		dec	Line		
		brne	LCD_Big3
LCD_Big4:	lsr	Fetch			; LSB >> Carry
		brcc	LCD_Big5
		ori	Temp,$0F		; If Cy => set bits
LCD_Big5:	lsr	Fetch			; Repeat fot next bit
		brcc	LCD_Big6
		ori	Temp,$F0
LCD_Big6:	adiw	ZL,1			; Inc Z
		push	Lcount			; Save Lcount
		ldi	Lcount,4
LCD_Big7:	push	Temp
		rcall	LCD_Write		; "Print" this 4 times
		pop	Temp
		dec	Lcount			
		brne	LCD_Big7

		pop	Lcount			; Restore Lcount
		dec	Lcount			; Last byte off this char ?
		pop	Line			; Restore pointer
		brne	LCD_Big2		; No, Loop Back

		dec	Xcount			; Last digit ?
		brne	LCD_Big1		; No, Loop Back

		pop	Xcount
		pop	XL			; Restore string pointer
		pop	XH
		inc	Line			; Increment pointer
		dec	Base1			; Last line ?
		brne	LCD_Big_x		; No, Loop Back

		ret


LCD_String:

; Entry : Z points to start of string and &FF in last byte terminates string
; Destroys : Temp, Z

		sbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Data
LCD_Str1:	lpm				; Fetch,(Z)
		mov	Temp,Fetch
		adiw	ZL,1			; Inc Z
		inc	Temp			; End of String
		breq	LCD_StrEx		; Skip if yes
		dec	Temp
		rcall	LCD_Write
		rjmp	LCD_Str1
LCD_StrEx:	ret

LCD_Clear:

; Entry : no parameters
; Destroys : TEMP, Lcount

		cbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Commands

; Set Cursor to top left

		ldi	Temp,$B0		; Page 0
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B1		; Page 1
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B2		; Page 2
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B3		; Page 3
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B4		; Page 4
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B5		; Page 5
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B6		; Page 6
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ldi	Temp,$B7		; Page 7
		rcall	LCD_Write
		ldi	Temp,$01		; Colomn LOW
		rcall	LCD_Write
		ldi	Temp,$12		; Colomn HIGH
		rcall	LCD_Write
		
		rcall	LCD_Clr		; Clear this line

		ret

LCD_Clr:	sbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Data
		ldi	Lcount,100		; Clear all 100 (x8) pixels on this line
LCD_Clr2:	ldi	Temp,0
		rcall	LCD_Write
		dec	Lcount
		brne	LCD_Clr2
		cbi	LCD_CDport,LCD_CDpin	; Tell LCD this is Commands
		ret

; ********** Delay loop for Init **************************************************

LCD_delay:	clr	Temp
		clr	Lcount
LCD_delay1:	dec	Temp
		nop
		brne	LCD_delay1
		dec	Lcount
		brne	LCD_delay1
		ret

; **********	Character Table ******************************************************

Char_Tabel:

Char_0:					; Char 0 to F should be in this sequence

.db	$3E,$41,$41,$41,$3E,$00		; "0"
.db	$00,$42,$7F,$40,$00,$00		; "1"
.db	$42,$61,$51,$49,$46,$00		; "2"
.db	$21,$41,$45,$4B,$31,$00		; "3"
.db	$18,$14,$12,$7F,$10,$00		; "4"
.db	$27,$45,$45,$45,$39,$00		; "5"
.db	$3C,$4A,$49,$49,$30,$00		; "6"
.db	$01,$71,$09,$05,$03,$00		; "7"
.db	$36,$49,$49,$49,$36,$00		; "8"
.db	$06,$49,$49,$29,$1E,$00		; "9"
.db	$7E,$11,$11,$11,$7E,$00		; "A"
.db	$7F,$49,$49,$49,$36,$00		; "B"
.db	$3E,$41,$41,$41,$22,$00		; "C"
.db	$7F,$41,$41,$22,$1C,$00		; "D"
.db	$7F,$49,$49,$49,$49,$00		; "E"
.db	$7F,$09,$09,$09,$01,$00		; "F"
.db	$00,$36,$36,$00,$00,$00		; ":"
.db	$20,$10,$08,$04,$02,$00		; "/"
.db	$00,$00,$00,$00,$00,$00		; " "
.db	$00,$30,$30,$00,$00,$00		; "."
.db	$1C,$20,$40,$20,$1C,$00		; "v"

;.db	$7F,$08,$14,$22,$41,$00		; "K"
;.db	$01,$01,$7F,$01,$01,$00		; "T"

;.db	$20,$54,$54,$54,$78,$00		; "a"
;.db	$7F,$48,$44,$44,$38,$00		; "b"
;.db	$38,$44,$44,$44,$20,$00		; "c"
;.db	$38,$44,$44,$48,$7F,$00		; "d"
;.db	$38,$54,$54,$54,$18,$00		; "e"
;.db	$08,$7E,$09,$01,$02,$00		; "f"
;.db	$4C,$52,$52,$52,$3E,$00		; "g"
;.db	$7F,$08,$04,$04,$78,$00		; "h"
;.db	$00,$44,$7D,$40,$00,$00		; "i"
;.db	$7F,$10,$28,$44,$00,$00		; "k"
;.db	$00,$41,$7F,$00,$00,$00		; "l"
;.db	$3C,$04,$18,$04,$38,$00		; "m"
;.db	$7C,$08,$04,$04,$08,$00		; "r"
;.db	$48,$54,$54,$54,$20,$00		; "s"
;.db	$04,$3F,$44,$44,$20,$00		; "t"

; EOF

⌨️ 快捷键说明

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