📄 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 "lcd.h"
#include "mem.h"
#include "delay.h"
#include "uart.h"
#ifdef ENABLE_LCD
static u08 lcd_x, lcd_y;
/*************************************************************/
/********************** LOCAL FUNCTIONS **********************/
/*************************************************************/
static u08 LCDSetAddress(u08 adr)
{
return *(u08 *)(0x8000 + adr);
// dummy return to avoid optimization problems
}
static void lcd_write(u08 data, u08 rs)
{
// setup RS and RW pins
LCDSetAddress(rs + LCD_IO_WRITE);
cbi(MCUCR, SRE); // disable ExtRAM
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
sbi(MCUCR, SRE); // enable ExtRAM
}
static u08 lcd_read_func(void)
{
register u08 data;
// setup RS and RW pins
LCDSetAddress(LCD_IO_FUNCTION + LCD_IO_READ);
cbi(MCUCR, SRE); // disable ExtRAM
outp(0x00, DDR(LCD_DATA_PORT)); // set port as input
lcd_e_high(); // set LCD enable high
data = inp(PIN(LCD_DATA_PORT)); // read byte
lcd_e_low(); // set LCD enable low
sbi(MCUCR, SRE); // enable ExtRAM
return data;
}
static void lcd_waitbusy(void) // loops while lcd is busy
{ // no watchdog in this function
register u08 i = 0; // should work fast enough
while (lcd_read_func() & (1 << LCD_BUSY) && i != 255) i++;
}
static void lcd_newline(void) // goto start of next line
{
lcd_x = 0;
if (++lcd_y >= LCD_LINES)
lcd_y = 0;
}
static void lcd_goto(void) // goto position (lcd_x,lcd_y)
{
lcd_command((1 << LCD_DDRAM) + LCD_LINE_LENGTH * lcd_y + lcd_x);
}
/*************************************************************/
/********************* PUBLIC FUNCTIONS **********************/
/*************************************************************/
void lcd_command(u08 cmd) // send commando <cmd> to LCD
{
lcd_waitbusy();
lcd_write(cmd, LCD_IO_FUNCTION);
}
void lcd_data(u08 data) // send data <data> to LCD
{
lcd_waitbusy();
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(200); // 2 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
lcd_waitbusy();
if (data == '\n')
{
lcd_newline();
lcd_goto();
}
else
{
if (++lcd_x >= LCD_LINE_LENGTH)
{
lcd_newline();
lcd_goto();
}
lcd_write(data, LCD_IO_DATA);
}
}
void lcd_puts(u08* str) // print string on lcd
{ // (no auto linefeed)
if (str)
while (*str)
lcd_putchar(*str++);
}
static u16 wait[] = { 1600, 500, 7, 7 };
#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;
#endif
// configure control line pins as output
sbi(DDR(LCD_E_PORT), LCD_E_PIN);
// set enable line high
sbi(LCD_E_PORT, LCD_E_PIN);
// done via ld option!!!
// enable external SRAM (memory mapped lcd) and wait states
// outp((1 << SRE) | (1 << SRW), MCUCR);
#ifdef ENABLE_LCD
fnc |= (1 << LCD_FUNCTION);
for (i = 0; i < 4; i++) // reset lcd
{
delay10(wait[i]); // 16ms, 5ms, 70us, 70us
lcd_write(fnc, LCD_IO_FUNCTION); // reset function
}
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 + -