📄 lcd.asm
字号:
/* ***********************************************************************
**
** Copyright (C) 2002 Jesper Hansen <jesperh@telia.com> and
** Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-7/USB - low level support library
**
**
*************************************************************************
**
** 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-09-22 1.0 MIS initial public release
** 2002-10-15 1.10 MIS added support for Nokia LCD to yampp7
** 2002-10-30 1.11 MIS added support for national characters displaying
**
*********************************************************************** */
#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0
#include <avr/io.h>
#define LCD_ASM
#include "lcd.h"
#define __tmp_reg__ r0
#define __zero_reg__ r1
#define LCD_ASM
.comm lcd_x,1
.comm lcd_y,1
.text
.extern vs1001_init_io
.comm lcd_inv,1
.text
;************************************************
;LCD control routine
;void lcd_init(u08 mode)
.global lcd_init
lcd_init: mov r25,r24
andi r25,254
sbi PORTB,PB4 ;deselect Display
sbi DDRB,PB4 ;
sbi DDRD,PD0 ;C/D = output
call vs1001_init_io ;init SPI
ldi r24,0x21 ;LCD extended cmds
rcall lcd_wrcmd
ldi r24,0xC8 ;set LCD Vop (contrast)
rcall lcd_wrcmd
ldi r24,0x06 ;set temperatur coefficent
rcall lcd_wrcmd
ldi r24,0x13 ;LCD bias mode 1:48
rcall lcd_wrcmd
ldi r24,0x20 ;LCD standard cmds, Horizontal adressing mode
rcall lcd_wrcmd
ldi r24,0x0C ;LCD in normal mode
add r24,r25 ;set mode to eventually REVERS
rcall lcd_wrcmd
;fall trough
;************************************************
;clear LCD
;void lcd_clrscr(void)
.global lcd_clrscr
lcd_clrscr: sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
sts lcd_inv,__zero_reg__
ldi r24,0x40 ;clear LCD y addr
rcall lcd_wrcmd
ldi r24,0x80 ;clear LCD x addr
rcall lcd_wrcmd
ldi r21, 84 ;84 chars on display
LCD_CLEAR_1: clr r24 ;char #0
rcall lcd_data
dec r21
brne LCD_CLEAR_1
ldi r24,0x40 ;clear LCD y addr
rcall lcd_wrcmd
ldi r24,0x80 ;clear LCD x addr
rjmp lcd_wrcmd
;************************************************
;display graphics welcome screen from eeprom
;Screen must have size of 84x32 pixesls, and LCD ram format.
;It must be loaded into EEPROM from 0x05C address and have 4*84 bytes length.
;u08 lcd_logo(u08 line)
.global lcd_logo
lcd_logo: ori r24,0x40 ;set line number
rcall lcd_wrcmd
ldi r24,0x80
rcall lcd_wrcmd
ldi r30,EEPROM_LOGO ;EEPROM data start pointer (512 - 4*84 - 2)
clr r31
rcall get_eep
cpi r24,'y'
brne no_logo
rcall get_eep
cpi r24,'W'
brne no_logo
sbi PORTD,PD0 ;set DATA mode
sbi DDRD,PD0 ;PD0 - output for LCD D/C
cbi PORTB,PB4 ;enable LCD
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_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 lcd_off(void)
.global lcd_off
lcd_off: rcall lcd_clrscr
ldi r24,0x08
rcall lcd_wrcmd
ldi r24,0x24 ;LCD off
rjmp lcd_wrcmd
;************************************************
;void lcd_invert(void)
.global lcd_invert
lcd_invert: ldi r24,0x7f
sts lcd_inv,r24
ret
;************************************************
;void lcd_normal(void)
.global lcd_normal
lcd_normal: sts lcd_inv,__zero_reg__
ret
;************************************************
; r24
;void lcd_contrast(u08 cont)
.global lcd_contrast
lcd_contrast: mov r25,r24
ldi r24,0x21 ;LCD extended cmds
rcall lcd_wrcmd
mov r24,r25
ori r24,0x80 ;add Set Vop command
rcall lcd_wrcmd
ldi r24,0x20 ;LCD in normal mode
rjmp lcd_wrcmd
;************************************************
;display a bar
;Lenght(on display) is in r22 and value(how much is filled) in r24
; r24 r22
;void lcd_bar(u08 val, u08 len)
.global lcd_bar
lcd_bar: mov r25,r24
ldi r24,0b01111111 ;begin of bar
cbi PORTB,PB4 ;enable LCD
sbi PORTD,PD0 ;set DATA mode
sbi DDRD,PD0 ;PD0 - output for LCD D/C
rcall SPI_SEND
LCD_BAR_2: ldi r24,0b01011101 ;full bar pixel
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 lcd_wrdata
;************************************************
; r24 r22
;void lcd_gotoxy(u08 x, u08 y)
.global lcd_gotoxy
lcd_gotoxy:
sts lcd_x,r24
sts lcd_y,r22
; Fall trough
;void lcd_goto(void)
lcd_goto:
lds r24,lcd_y ; get y position
ori r24,0x40
rcall lcd_wrcmd
lds r0,lcd_x
ldi r24,6
mul r24,r0
mov r24,r0
clr __zero_reg__
ori r24,0x80 ; get x position
rjmp lcd_wrcmd
;************************************************
;display a character
; r24
;void lcd_data(u08 data)
.global lcd_data
lcd_data:
clr r22 ;offset = 0
;void lcd_data_o(u08 data, u08 offset)
.global lcd_data_o
lcd_data_o: push r30
push r31
lds r23,lcd_inv ;get lcd_invert flag
cbi PORTB,PB4 ;enable LCD
sbi PORTD,PD0 ;set DATA mode
sbi DDRD,PD0 ;PD0 - output for LCD D/C
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,lo8(ASCIITAB) ;set pointer to Ascii table
ldi r31,hi8(ASCIITAB)
add r30, r0
adc r31, r1
clr __zero_reg__
add r30, r22 ;add offset
adc r31, __zero_reg__
sub r25,r22 ;substract bytes count
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
rjmp LCD_SEXIT
NATCH: mov r25,r24
ldi r30,EEPROM_LANGTAB ;codes conversion table addres
out EEARH,__zero_reg__ ;set eeprom address
NTABS: rcall get_eep1
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,(EEPROM_LANGTAB+20) ;check for table end
brne NTABS ;next search
NTABNF: ldi r24,'_' ;end of table -> print "_"
rjmp LCD_SENDASC
NATCH_F: subi r30,(EEPROM_LANGTAB+1) ;substract cargen table base = char number
ldi r25,6 ;6 bytes per char
mul r30,r25
mov r30,r0
clr __zero_reg__
subi r30,-(EEPROM_LANGCHARS) ;add character generator table offset
add r30,r22 ;add offset
sub r25,r22 ;substract bytes count
NAT_CHAR_1: rcall get_eep1 ;get byte from eeprom
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
; r24
; void lcd_wrcmd(u08 cmd)
.global lcd_wrcmd
lcd_wrcmd: cbi PORTD,PD0 ;set CMD mode
rjmp LCD_SEND
;************************************************
;send LCD data
; r24
;void lcd_wrdata(u08 data)
.global lcd_wrdata
lcd_wrdata: sbi PORTD,PD0 ;set DATA mode
;fall trough
;************************************************
;using the SPI for communication
LCD_SEND: cbi PORTB,PB4 ;enable LCD
sbi DDRD,PD0 ;PD0 - output for LCD D/C
rcall SPI_SEND
LCD_SEXIT: sbi PORTB,PB4 ;disable LCD
cbi DDRD,PD0 ;PD0 - input for DREQ handling
sbi PORTD,PD0 ;enable pullup
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
;************************************************
;void lcd_newline(void)
lcd_newline:
sts lcd_x,__zero_reg__ ; lcd_x = 0
lds r18,lcd_y ; lcd_y++
inc r18
cpi r18,6 ; Ymax
brge lcd_nl2
sts lcd_y,r18
lcd_nl2: ret
; r24
;void lcd_putchar(u08 data)
.global lcd_putchar
lcd_putchar:
cpi r24,'\n'
brne lcd_pc2
rcall lcd_newline
rjmp lcd_goto
lcd_pc2: cpi r24,'\r'
breq lcd_p3
lds r25,lcd_x
cpi r25,14 ;Xmax
brge lcd_p3
inc r25
sts lcd_x,r25
rjmp lcd_data
; r25/r24
;void lcd_puts(char *s)
.global lcd_puts
lcd_puts:
movw r30,r24
sbiw r30,0 ; test for zero
breq lcd_p3
lcd_p2:
ld r24,Z+
tst r24
breq lcd_p3
rcall lcd_putchar
rjmp lcd_p2
lcd_p3: ret
; r25/r24
;void lcd_progputs(char *s)
.global lcd_progputs
lcd_progputs:
movw r30,r24
sbiw r30,0 ; test for zero
breq lcd_p3
lcd_pp2:
lpm r24,Z
tst r24
breq lcd_p3
rcall lcd_putchar
adiw r30,1
rjmp lcd_pp2
;Ascii table for character definition
ASCIITAB:
#include "ascii.def"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -