📄 glcd_2.asm
字号:
/* ***********************************************************************
**
** Copyright (C) 2003 Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-3/USB - 128x64 graphics LCD display driver
**
** File Glcd_2.asm
**
*************************************************************************
**
** This file is part of the yampp system
** by Jesper Hansen <jesperh@telia.com>
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*************************************************************************
**
** Revision History
**
** when what who why
**
** 2003-07-10 1.0 MIS initial public release
** 2003-08-03 1.1 MIS Small bugfix.
**
*********************************************************************** */
#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0
#include <avr/io.h>
#include "Constants.h"
#include "mem.h"
#define __tmp_reg__ r0
#define __zero_reg__ r1
#if(LCD_TYPE == 8) && !defined(SATTELITE)
#define LCD_IO_DATA 0x0001 ; A0 goes to RS
#define LCD_IO_FUNCTION 0x0000
#define LCD_IO_READ 0x0002 ; A1 goes to R/-W
#define LCD_IO_WRITE 0x0000
#define LCD_DATA_PORT PORTA
#define LCD_E_PORT PORTE
#define LCD_E_PIN PE2
#define LCD_CS_PORT PORTD
#define LCD_CS_PIN PD2
.comm lcd_x,1
.comm lcd_y,1
.comm lcd_neg,1
.text
.extern ramenable
.extern ramdisable
;************************************************
Glcd_setaddress:
ser r25
out LCD_DATA_PORT-1,r25 ; set port as output
out LCD_DATA_PORT,r23 ; write address
sbi PORTE,PE1 ; toggle ALE
cbi PORTE,PE1
ret
; r24
; void lcd_func(u08 data);
Glcd_wrfunc:
push r25
rcall Glcd_waitbusy
ldi r23,LCD_IO_FUNCTION + LCD_IO_WRITE
rjmp Glcd_write
; r24
; void lcd_data(u08 data);
Glcd_wrdata:
push r25
rcall Glcd_waitbusy
ldi r23,LCD_IO_DATA + LCD_IO_WRITE
Glcd_write:
rcall Glcd_setaddress
out LCD_DATA_PORT,r24 ; write data
nop
sbi LCD_E_PORT,LCD_E_PIN
nop
nop
nop
cbi LCD_E_PORT,LCD_E_PIN
call ramenable
pop r25
ret
Glcd_waitbusy:
push r24
call ramdisable
ldi r27,hi8(8000) ; break out counter
ldi r26,lo8(8000)
ldi r23,LCD_IO_FUNCTION + LCD_IO_READ
rcall Glcd_setaddress
out LCD_DATA_PORT-1,__zero_reg__ ; set port as input
Glcd_wb2:
sbi LCD_E_PORT,LCD_E_PIN
nop
nop
nop
in r24,LCD_DATA_PORT-2
cbi LCD_E_PORT,LCD_E_PIN
andi r24,0x80
breq Glcd_ready
sbiw r26,1
brne Glcd_wb2
Glcd_ready:
pop r24
ret
;************************************************
lcd_newline:
sts lcd_x,__zero_reg__ ; lcd_x = 0
lds __tmp_reg__,lcd_y
inc __tmp_reg__ ; lcd_y++
ldi r18,8
cp __tmp_reg__,r18
brge lcd_nl2
sts lcd_y,__tmp_reg__
lcd_nl2:
ret
;************************************************
; r24 r22
;void Vlcd_gotoxy(u08 x, u08 y)
.global Vlcd_gotoxy
Vlcd_gotoxy: ldi r25,6
mul r24,r25
sts lcd_x,r0
sts lcd_y,r22
; Fall trough
;void lcd_goto(void)
lcd_goto:
lds r24,lcd_y ; add y position
andi r24,0x07
ori r24,0xB8
rcall Vlcd_command
lcd_goto2: lds r24,lcd_x ; get x position
andi r24,0x3f
ori r24,0x40
; Fall trough
;************************************************
; r24
;void Vlcd_command(u08 cmd)
.global Vlcd_command
Vlcd_command:
cbi LCD_CS_PORT, LCD_CS_PIN
rcall Glcd_wrfunc
sbi LCD_CS_PORT, LCD_CS_PIN
rjmp Glcd_wrfunc
;************************************************
; r24
;void Vlcd_wrdata(u08 data)
.global Vlcd_wrdata
Vlcd_wrdata:
push r24
rcall lcd_goto2
pop r24
lds r26,lcd_x ; get x position
sbrs r26,6
cbi LCD_CS_PORT, LCD_CS_PIN
lcd_data_1: rcall Glcd_wrdata
lds r26,lcd_x
inc r26
sts lcd_x,r26
ret
;************************************************
;void Vlcd_clrscr(void)
.global Vlcd_clrscr
Vlcd_clrscr: sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
rcall lcd_goto
sbi LCD_CS_PORT, LCD_CS_PIN
rcall lcd_clrscr_1
cbi LCD_CS_PORT, LCD_CS_PIN
lcd_clrscr_1: clr r30
lcd_clrscr_3: mov r24,r30
ori r24,0xB8
rcall Glcd_wrfunc
ldi r25,64
lcd_clrscr_2: clr r24
rcall Glcd_wrdata
dec r25
brne lcd_clrscr_2
inc r30
sbrs r30,3
rjmp lcd_clrscr_3
sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
ret
;************************************************
;void lcd_clrline(u08 line)
.global lcd_clrline
lcd_clrline:
sts lcd_x,__zero_reg__
sts lcd_y,r24
rcall lcd_goto
sbi LCD_CS_PORT, LCD_CS_PIN
rcall lcd_clrline_1
cbi LCD_CS_PORT, LCD_CS_PIN
lcd_clrline_1: ldi r25,64
lcd_clrline_2: clr r24
rcall Glcd_wrdata
dec r25
brne lcd_clrline_2
sts lcd_x,__zero_reg__
ret
;************************************************
;display a bar
;Lenght(on display) is in r22 and value(how much is filled) in r24
; r24 r22
;void Vlcd_bar(u08 pos, u08 len)
.global Vlcd_bar
Vlcd_bar: mov r25,r24
ldi r24,0b01111111 ;begin of bar
rcall Vlcd_wrdata
LCD_BAR_2:
#ifdef ALT_BAR_STYLE
ldi r24,0b01111111 ; alternate bar style
#else
ldi r24,0b01011101 ; standard bar style
#endif
tst r25
brne LCD_BAR_1
ldi r24,0b01000001 ;empty bar pixel
inc r25
LCD_BAR_1: dec r25
rcall Vlcd_wrdata
dec r22
brne LCD_BAR_2
ldi r24,0b01111111 ;end of bar
rjmp Vlcd_wrdata
;************************************************
; r24
;void Vlcd_putchar(u08 data)
.global Vlcd_putchar
Vlcd_putchar:
cpi r24,'\n' ;new line
brne lcd_pc2
rjmp lcd_newline
lcd_pc2: cpi r24,'\r' ;line home
breq lcd_pc3
ldi r25,(6*21)
lds __tmp_reg__,lcd_x
cp __tmp_reg__,r25
brge lcd_pc3
push r24
rcall lcd_goto
pop r24
push r30
push r31
lds r22,lcd_neg ;get lcd_invert flag
tst r24 ;test for code > 127
brpl LCD_SENDASC
rjmp NATCH ;go to national chars printing
LCD_SENDASC: ldi r25,6 ;6 byte/char
mul r24,r25 ;compute character offset
ldi r30,0x00 ;set pointer to Ascii table
ldi r31,0x3D
add r30, r0
adc r31, r1
clr __zero_reg__
LCD_CHAR_1: lpm r24,Z+
eor r24,r22
rcall Vlcd_wrdata
dec r25
brne LCD_CHAR_1
LCD_CHAR_2: pop r31
pop r30
lcd_pc3: ret
NATCH: mov r25,r24
ldi r31,hi8(LANGTAB_MEMORY)
ldi r30,lo8(LANGTAB_MEMORY) ;codes conversion table addres
NTABS: ld r24,Z+
tst r24
breq NTABNF ;test for 0 -> end of table -> print "_"
cp r24,r25 ;is this char ?
breq NATCH_F ;yes, display it
cpi r30,lo8(LANGTAB_MEMORY+20) ;check for table end
brne NTABS ;next search
NTABNF: ldi r24,'_' ;end of table -> print "_"
rjmp LCD_SENDASC
NATCH_F: dec r30
ldi r25,6 ;6 bytes per char
mul r30,r25
mov r30,r0
subi r30,-0x30
NAT_CHAR_1: ld r24,Z+ ;get byte from RAM
eor r24,r22 ;Character inversion
rcall Vlcd_wrdata ;Send to display
dec r25 ;dec bytes counter
brne NAT_CHAR_1 ;next byte
rjmp LCD_CHAR_2
;************************************************
; r25/r24
;void Vlcd_puts(char *s)
.global Vlcd_puts
Vlcd_puts:
movw r30,r24
sbiw r30,0 ; test for zero
breq lcd_p3
lcd_p2:
ld r24,Z+
tst r24
breq lcd_p3
rcall Vlcd_putchar
rjmp lcd_p2
lcd_p3: ret
; r25/r24
;void Vlcd_progputs(char *s)
.global Vlcd_progputs
Vlcd_progputs:
movw r30,r24
sbiw r30,0 ; test for zero
breq lcd_p3
lcd_pp2:
lpm r24,Z
tst r24
breq lcd_p3
rcall Vlcd_putchar
adiw r30,1
rjmp lcd_pp2
;************************************************
;void Vlcd_init(void)
.global Vlcd_init
Vlcd_init:
sts lcd_neg,__zero_reg__
sbi LCD_CS_PORT, LCD_CS_PIN
sbi LCD_CS_PORT-1, LCD_CS_PIN ; set port as output
cbi LCD_E_PORT,LCD_E_PIN ; set pin low
sbi LCD_E_PORT-1,LCD_E_PIN ; set port as output
ldi r24,0x3f ; LCD_ON
rcall Vlcd_command
ldi r24,0xc0
rcall Vlcd_command
sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
rjmp Vlcd_clrscr
;************************************************
;void Vlcd_invert(void)
.global Vlcd_invert
Vlcd_invert: ldi r24,0x7f
sts lcd_neg,r24
ret
;************************************************
;void Vlcd_normal(void)
.global Vlcd_normal
Vlcd_normal: sts lcd_neg,__zero_reg__
ret
;************************************************
;void Vlcd_contrast(u08 contrast)
.global Vlcd_contrast
Vlcd_contrast:
ret
;************************************************
;u08 Vlcd_logo(void)
.global Vlcd_logo
Vlcd_logo: ldi r30,EEPROM_LOGO_S ;EEPROM data start pointer (512 - 4*84 - 2)
clr r31
rcall get_eep
cpi r24,'y'
brne no_small_logo
rcall get_eep
cpi r24,'W'
brne no_small_logo
display_logo: ldi r20,1
sts lcd_y,r20
lcd_logo_3:
ldi r28,84
ldi r20,22
sts lcd_x,r20
rcall lcd_goto
lcd_logo_2: rcall get_eep
rcall Vlcd_wrdata
dec r28
brne lcd_logo_2
lds r18,lcd_y
inc r18
sts lcd_y,r18
sbrs r31,1 ;if address == 512
brne lcd_logo_3
clr r24
ret
no_small_logo: ldi r30,EEPROM_LOGO_L ;EEPROM data start pointer (512 - 5*84 - 2)
clr r31
rcall get_eep
cpi r24,'y'
brne no_logo
rcall get_eep
cpi r24,'W'
brne no_logo
rjmp display_logo
no_logo: ser r24
ret
get_eep: out EEARH,r31 ;set eeprom address
get_eep1: out EEARL,r30
sbi EECR,EERE ;eeprom read
in r24,EEDR ;get byte from eeprom
adiw r30,1 ;increament address
ret
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -