⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lcd.asm

📁 老外个人做的MP3/优盘。使用ATMEL MEGA系列的MCU
💻 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 + -