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

📄 glcd_2.asm

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