📄 lcd_avr_005.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 + -