📄 lcd.asm
字号:
/* ***********************************************************************
**
** Copyright (C) 2002 Jesper Hansen <jesperh@telia.com> and
** Romuald Bialy (MIS) <romek_b@o2.pl>.
**
**
** Yampp-3/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-01 1.0 MIS initial public release
** 2002-09-02 1.01 MIS added some nop's to lcd_read function
** 2002-10-02 1.02 MIS added more nop's to lcd functions
**
*********************************************************************** */
#define __ASSEMBLER__ 1
#define __SFR_OFFSET 0
#include <avr/io.h>
//#include <io-avr.h>
#define __tmp_reg__ r0
#define __zero_reg__ r1
#ifndef YAMPP7
#define LCD_ASM
#include "lcd.h"
.comm lcd_x,1
.comm lcd_y,1
.comm lcd_xmax,1
.comm lcd_ymax,1
.text
.extern ramenable
.extern ramdisable
.extern delay
.extern delayms
lcd_setaddress:
call ramdisable
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
lcd_write:
rcall lcd_setaddress
out LCD_DATA_PORT,r24 ; write data
lcd_e_toggle:
nop
nop
sbi LCD_E_PORT,LCD_E_PIN
nop
nop
nop
nop
cbi LCD_E_PORT,LCD_E_PIN
nop
call ramenable
ret
; r24
; void lcd_func(u08 data);
lcd_wrfunc:
ldi r23,LCD_IO_FUNCTION + LCD_IO_WRITE
rjmp lcd_write
; r24
; void lcd_data(u08 data);
lcd_wrdata:
ldi r23,LCD_IO_DATA + LCD_IO_WRITE
rjmp lcd_write
;u08 lcd_read(void)
lcd_read:
ldi r23,LCD_IO_FUNCTION + LCD_IO_READ
rcall lcd_setaddress
out LCD_DATA_PORT-1,__zero_reg__ ; set port as input
nop
sbi LCD_E_PORT,LCD_E_PIN
nop
nop
nop
nop
in r24,LCD_DATA_PORT-2
nop
cbi LCD_E_PORT,LCD_E_PIN
clr r25
ret
lcd_waitbusy:
push r24
ldi r27,hi8(8000) ; break out counter
ldi r26,lo8(8000)
lcd_wb2:
rcall lcd_read
andi r24,(1<<LCD_BUSY)
breq lcd_ready
sbiw r26,1
brne lcd_wb2
lcd_ready:
pop r24
ret
;void lcd_newline(void)
lcd_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 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
andi r24,3 ; mask 6 higher bits
clc ; clear carry
ror r24
ror r24 ; move bit 0 to 6th position (0x40)
ror r24 ; and bit 1 to 7th position
brpl lcd_goto2 ; check 7th bit is cleared (its mean 1 or 2 line)
lds r25,lcd_xmax
add r24,r25 ; add lcd_xmax for propper value of 3 or 4 line
lcd_goto2:
ori r24,128 ; set 7th bit (DDRAM address)
lds r25,lcd_x
add r24,r25 ; add x position
; fall through (fixed missing call to lcd_waitbusy by MIS)
; r24
;void lcd_command(u08 cmd)
.global lcd_command
lcd_command:
rcall lcd_waitbusy
rjmp lcd_wrfunc
; r24
;void lcd_data(u08 data)
.global lcd_data
lcd_data:
rcall lcd_waitbusy
rjmp lcd_wrdata
;void lcd_clrscr(void)
.global lcd_clrscr
lcd_clrscr:
sts lcd_x,__zero_reg__
sts lcd_y,__zero_reg__
ldi r24,(1>>LCD_CLR)
rjmp lcd_command
; r24
;void lcd_putchar(u08 data)
.global lcd_putchar
lcd_putchar:
cpi r24,'\n' ;new line
brne lcd_pc2
rcall lcd_newline
rjmp lcd_goto
lcd_pc2: cpi r24,'\r' ;line home
brne lcd_pc3
sts lcd_x,__zero_reg__
rjmp lcd_goto
lcd_pc3: lds r25,lcd_x
lds __tmp_reg__,lcd_xmax
cp r25,__tmp_reg__
brge lcd_p3
inc r25
sts lcd_x,r25
tst r24
brpl lcd_data
NATCHAR: mov r25,r24
push r30
push r31
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 NATCHX
NATCH_F: adiw r30,23
ld r24,Z
NATCHX: pop r31
pop r30
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
; r24 r22 r21 = y / r20 = x
;void lcd_init(u08 cursor, u08 fnc, u16 xymax)
.global lcd_init
lcd_init:
sts lcd_xmax,r20 ; store max x position
sts lcd_ymax,r21 ; store max y position
sbi LCD_E_PORT-1,LCD_E_PIN ; set port as output
cbi LCD_E_PORT,LCD_E_PIN ; set pin low
push r24
ori r22,(1<<LCD_FUNCTION)
; 4 delays and 4 writes of fnc
ldi r21,4 ; loop counter
wrfun_loop: mov r24,r22
rcall lcd_wrfunc
clr r25
ldi r24,5
call delayms
dec r21
brne wrfun_loop
ldi r24,LCD_MODE_DEFAULT
rcall lcd_command
pop r24
ori r24, (1<<LCD_ON) | (1<<LCD_ON_DISPLAY)
rcall lcd_command
rjmp lcd_clrscr
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -