📄 glcd_1.asm
字号:
/* ***********************************************************************
**
** Copyright (C) 2002 Jesper Hansen <jesperh@telia.com> and
** Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-3/USB - Nokia graphics LCD display driver
**
** File Glcd_1.asm
**
*************************************************************************
**
** This file is part of the yampp system.
**
** 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
**
** 2002-11-04 1.0 MIS initial public release
** 2002-11-10 1.1 MIS -added support for 84x40 pixels logo
-added support for displaying in negativ
*********************************************************************** */
#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0
#include <avr/io.h>
#include "Constants.h"
#include "mem.h"
#if(LCD_TYPE == 7) && !defined(SATTELITE)
#define CS_PORT PORTE
#define CS_PIN PE2
#define DC_PORT PORTD
#define DC_PIN PD2
#define __tmp_reg__ r0
#define __zero_reg__ r1
.extern delayms
.extern vs1001_init_io
.comm lcd_x,1
.comm lcd_y,1
.comm lcd_xmax,1
.comm lcd_ymax,1
.comm lcd_inv,1
.text
;************************************************
;LCD control routine
;void Vlcd_init(void)
.global Vlcd_init
Vlcd_init: ldi r24,14
sts lcd_xmax,r24
ldi r24,6
sts lcd_ymax,r24
sbi CS_PORT,CS_PIN ;deselect Display
sbi CS_PORT-1,CS_PIN ;
sbi DC_PORT-1,DC_PIN ;C/D = output
call vs1001_init_io ;init SPI
ldi r24,0x21 ;LCD extended cmds
rcall Vlcd_wrcmd
ldi r24,0xC8 ;set LCD Vop (contrast)
rcall Vlcd_wrcmd
ldi r24,0x06 ;set temperatur coefficent
rcall Vlcd_wrcmd
ldi r24,0x13 ;LCD bias mode 1:48
rcall Vlcd_wrcmd
ldi r24,0x20 ;LCD standard cmds, Horizontal adressing mode
rcall Vlcd_wrcmd
#ifdef LCD_NEGATIV
ldi r24,0x0D
#else
ldi r24,0x0C ;LCD in normal mode
#endif
rcall Vlcd_wrcmd
;fall trough
;************************************************
;clear LCD
;void Vlcd_clrscr(void)
.global Vlcd_clrscr
Vlcd_clrscr: sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
sts lcd_inv,__zero_reg__
rcall Vlcd_goto ;clear LCD x and y addr
cbi CS_PORT,CS_PIN ;enable LCD
sbi DC_PORT,DC_PIN ;set DATA mode
rcall LCD_CLEAR_1
rcall LCD_CLEAR_1
sbi CS_PORT,CS_PIN
rjmp Vlcd_goto ;clear LCD x and y addr
LCD_CLEAR_1: ldi r21, 252 ;2*202 bytes to clear
LCD_CLEAR_2: clr r24
rcall SPI_SEND
dec r21
brne LCD_CLEAR_2
ret
;************************************************
;display graphics welcome screen from eeprom
;Screen must have size of 84x32 or 84x40 pixesls, and LCD ram format.
;It must be loaded into EEPROM from 0xAE or 0x05A address
;and have 4*84 or 5*84 bytes length plus 2 bytes of TAG.
;u08 Vlcd_logo(void)
.global Vlcd_logo
Vlcd_logo: ldi r24,0x40 ;set line number
rcall Vlcd_wrcmd
ldi r24,0x80
rcall Vlcd_wrcmd
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: cbi CS_PORT,CS_PIN ;enable LCD
sbi DC_PORT,DC_PIN ;set DATA mode
lcd_wloop: rcall get_eep
rcall SPI_SEND ;Send over SPI
sbrs r31,1 ;if address == 512
rjmp lcd_wloop
rcall LCD_SEXIT
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
;************************************************
;void Vlcd_invert(void)
.global Vlcd_invert
Vlcd_invert: ldi r24,0x7f
sts lcd_inv,r24
ret
;************************************************
;void Vlcd_normal(void)
.global Vlcd_normal
Vlcd_normal: sts lcd_inv,__zero_reg__
ret
;************************************************
; r24
;void Vlcd_contrast(u08 cont)
.global Vlcd_contrast
Vlcd_contrast: mov r25,r24
ldi r24,0x21 ;LCD extended cmds
rcall Vlcd_wrcmd
mov r24,r25
ori r24,0x80 ;add Set Vop command
rcall Vlcd_wrcmd
ldi r24,0x20 ;LCD in normal mode
rjmp Vlcd_wrcmd
;************************************************
;display a bar
;Lenght(on display) is in r22 and value(how much is filled) in r24
; r24 r22
;void Vlcd_bar(u08 val, u08 len)
.global Vlcd_bar
Vlcd_bar: mov r25,r24
ldi r24,0b01111111 ;begin of bar
cbi CS_PORT,CS_PIN ;enable LCD
sbi DC_PORT,DC_PIN ;set DATA mode
rcall SPI_SEND
LCD_BAR_2:
#ifdef ALT_BAR_STYLE
ldi r24,0b01111111 ;full bar pixel
#else
ldi r24,0b01011101 ;full bar pixel
#endif
tst r25
brne LCD_BAR_1
ldi r24,0b01000001 ;empty bar pixel
inc r25
LCD_BAR_1: dec r25
rcall SPI_SEND
dec r22
brne LCD_BAR_2
ldi r24,0b01111111 ;end of bar
rjmp Vlcd_wrdata
;************************************************
; r24 r22
;void Vlcd_gotoxy(u08 x, u08 y)
.global Vlcd_gotoxy
Vlcd_gotoxy:
sts lcd_x,r24
sts lcd_y,r22
; Fall trough
Vlcd_goto:
lds r24,lcd_y ; get y position
ori r24,0x40
rcall Vlcd_wrcmd
lds r0,lcd_x
ldi r24,6
mul r24,r0
mov r24,r0
clr __zero_reg__
ori r24,0x80 ; get x position
rjmp Vlcd_wrcmd
;************************************************
;display a character
; r24
;void Vlcd_data(u08 data)
.global Vlcd_data
Vlcd_data: push r30
push r31
lds r23,lcd_inv ;get lcd_invert flag
cbi CS_PORT,CS_PIN ;enable LCD
sbi DC_PORT,DC_PIN ;set DATA mode
tst r24 ;test for code > 127
brmi 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
LCD_CHAR_1: lpm r24,Z+ ;load byte from ASCII table
eor r24,r23 ;Character inversion
rcall SPI_SEND ;Send over SPI
dec r25
brne LCD_CHAR_1 ;next byte
LCD_CHAR_2: pop r31
pop r30
clr __zero_reg__
rjmp LCD_SEXIT
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,r23 ;Character inversion
rcall SPI_SEND ;Send over SPI
dec r25 ;dec bytes counter
brne NAT_CHAR_1 ;next byte
rjmp LCD_CHAR_2
;************************************************
;send an LCD command
Vlcd_wrcmd: cbi DC_PORT,DC_PIN ;set CMD mode
rjmp LCD_SEND
;************************************************
;send LCD data
; r24
;void Vlcd_wrdata(u08 data)
.global Vlcd_wrdata
Vlcd_wrdata: sbi DC_PORT,DC_PIN ;set DATA mode
;fall trough
;************************************************
;using the SPI for communication
LCD_SEND: cbi CS_PORT,CS_PIN ;enable LCD
rcall SPI_SEND
LCD_SEXIT: sbi CS_PORT,CS_PIN ;disable LCD
ret
SPI_SEND: out SPDR,r24 ;load byte in SPI data register
SPI_SEND_0: sbis SPSR,SPIF
rjmp SPI_SEND_0 ;transmitt byte to LCD
in r24,SPDR
ret
Vlcd_newline:
sts lcd_x,__zero_reg__ ; lcd_x = 0
lds r18,lcd_y ; lcd_y++
inc r18
lds __tmp_reg__,lcd_ymax
cp r18,__tmp_reg__
brge lcd_nl2
sts lcd_y,r18
lcd_nl2: ret
; r24
;void Vlcd_putchar(u08 data)
.global Vlcd_putchar
Vlcd_putchar:
cpi r24,'\n'
brne lcd_pc2
rcall Vlcd_newline
rjmp Vlcd_goto
lcd_pc2: cpi r24,'\r'
breq lcd_p3
lds r25,lcd_x
lds __tmp_reg__,lcd_xmax
cp r25,__tmp_reg__
brge lcd_p3
inc r25
sts lcd_x,r25
rjmp Vlcd_data
; 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
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -