📄 lcd.c
字号:
/*
Copyright (C) 2001 Jesper Hansen <jesperh@telia.com>.
Rewritten by: Nikolai Vorontsov <nickviz@mail.be>
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.
*/
#include <io.h>
#include <progmem.h>
#include "lcd.h"
#include "mem.h"
#include "delay.h"
#ifdef ENABLE_LCD
static u08 lcd_x, lcd_y;
/*************************************************************/
/********************** LOCAL FUNCTIONS **********************/
/*************************************************************/
static u08 LCDSetAddress(u08 adr)
{
#ifdef YAMPP3USB
cbi(MCUCR,SRE); // disable ExtRAM
outp(0xff, DDRA); // set port as output
outp(adr, PORTA); // write addres
sbi(PORTE,PE1);
cbi(PORTE,PE1); // flip ALE
return 0;
#else
register u08 b = *(volatile u08 *)(0x8000 | adr);
cbi(MCUCR,SRE); // disable ExtRAM
return b; // dummy return to avoid compiler warning
#endif
}
static void lcd_waitbusy(void) // loops while lcd is busy
{ // no watchdog in this function
register u08 i = 0; // should work fast enough
register u08 data;
// setup RS and RW pins
LCDSetAddress(LCD_IO_FUNCTION | LCD_IO_READ);
outp(0x00, DDR(LCD_DATA_PORT)); // set port as input
outp(0xff, LCD_DATA_PORT); // enable pullup
do
{
lcd_e_high(); // set LCD enable high
data = inp(PIN(LCD_DATA_PORT)); // read byte
lcd_e_low(); // set LCD enable low
i++;
} while ((data & (1 << LCD_BUSY)) && (i != 255));
enable_ram(); // enable ExtRAM
}
static void lcd_write(u08 data, u08 rs)
{
lcd_waitbusy();
// setup RS and RW pins
LCDSetAddress(rs | LCD_IO_WRITE);
outp(0xff, DDR(LCD_DATA_PORT)); // set port as output
outp(data, LCD_DATA_PORT); // write byte
lcd_e_high(); // set LCD enable high
lcd_e_low(); // set LCD enable low
enable_ram(); // enable ExtRAM
}
static void lcd_newline(void) // goto start of next line
{
lcd_x = 0;
if (lcd_y < LCD_LINES)
lcd_y++;
}
void lcd_goto(void) // goto position (lcd_x,lcd_y)
{
#if (LCD_LINE_LENGTH == 16)
static u08 lcd_line[] = {0x00, 0x40, 0x10, 0x50};
#else
static u08 lcd_line[] = {0x00, 0x40, 0x14, 0x54};
#endif
lcd_command((1 << LCD_DDRAM) + lcd_line[lcd_y] + lcd_x);
}
/*************************************************************/
/********************* PUBLIC FUNCTIONS **********************/
/*************************************************************/
void lcd_command(u08 cmd) // send commando <cmd> to LCD
{
lcd_write(cmd, LCD_IO_FUNCTION);
}
void lcd_data(u08 data) // send data <data> to LCD
{
lcd_write(data, LCD_IO_DATA);
}
void lcd_gotoxy(u08 x, u08 y) // goto position (x,y)
{
lcd_x = x; lcd_y = y;
lcd_goto();
}
void lcd_clrscr(void) // clear lcd
{
lcd_x = lcd_y = 0;
lcd_command(1 << LCD_CLR);
delay10(300); // 3 ms delay
}
#ifdef ENABLE_LCD_HOME_COMMAND
void lcd_home(void) // set cursor
{ // to home position
lcd_x = lcd_y = 0;
lcd_command(1 << LCD_HOME);
delay10(200); // 2 ms delay
}
#endif
void lcd_putchar(u08 data) // print character to
{ // current cursor position
if (data == '\n')
{
lcd_newline();
lcd_goto();
}
else
{
if (lcd_x < LCD_LINE_LENGTH)
{
lcd_x++;
lcd_write(data, LCD_IO_DATA);
}
}
}
void lcd_puts(u08* str) // print string on lcd
{ // (no auto linefeed)
while (*str)
lcd_putchar(*str++);
}
void lcd_puts_p(u08* p) // print string from flash on lcd
{
register u08 b;
while ((b = PRG_RDB(p++)))
lcd_putchar(b);
}
static u16 wait[] = {7,7,500,1600};
#endif
// cursor: 0 = off, 2 = on, 3 = blinking
// fnc: see LCD_FUNCTION_xxx
void lcd_init(u08 cursor, u08 fnc)
{
#ifdef ENABLE_LCD
register u08 i = 3;
fnc |= (1 << LCD_FUNCTION);
do // reset lcd
{
delay10(wait[i]); // 16ms, 5ms, 70us, 70us
lcd_write(fnc, LCD_IO_FUNCTION); // reset function
} while (i--);
lcd_command(1 << LCD_ON);
lcd_clrscr();
lcd_command(LCD_MODE_DEFAULT);
lcd_command((1 << LCD_ON)|(1 << LCD_ON_DISPLAY) | cursor);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -