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

📄 lcd.c

📁 图形点阵液晶模块相关的各种面板大小驱动程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*! \file lcd.c \brief Character LCD driver for HD44780/SED1278 displays. */
//*****************************************************************************
//
// File Name	: 'lcd.c'
// Title		: Character LCD driver for HD44780/SED1278 displays
//					(usable in mem-mapped, or I/O mode)
// Author		: Pascal Stang
// Created		: 11/22/2000
// Revised		: 4/30/2002
// Version		: 1.1
// Target MCU	: Atmel AVR series
// Editor Tabs	: 4
//
// This code is distributed under the GNU Public License
//		which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************

#include <avr/io.h>
#include <avr/pgmspace.h>

#include "global.h"
#include "timer.h"

#include "lcd.h"

// custom LCD characters
static unsigned char __attribute__ ((progmem)) LcdCustomChar[] =
{
	0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, // 0. 0/5 full progress block
	0x00, 0x1F, 0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, // 1. 1/5 full progress block
	0x00, 0x1F, 0x18, 0x18, 0x18, 0x18, 0x1F, 0x00, // 2. 2/5 full progress block
	0x00, 0x1F, 0x1C, 0x1C, 0x1C, 0x1C, 0x1F, 0x00, // 3. 3/5 full progress block
	0x00, 0x1F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x00, // 4. 4/5 full progress block
	0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 5. 5/5 full progress block
	0x03, 0x07, 0x0F, 0x1F, 0x0F, 0x07, 0x03, 0x00, // 6. rewind arrow
	0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, // 7. stop block
	0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, // 8. pause bars
	0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00, // 9. fast-forward arrow
	0x00, 0x04, 0x04, 0x0E, 0x0E, 0x1F, 0x1F, 0x00, // 10. scroll up arrow
	0x00, 0x1F, 0x1F, 0x0E, 0x0E, 0x04, 0x04, 0x00, // 11. scroll down arrow
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 12. blank character
	0x00, 0x0E, 0x19, 0x15, 0x13, 0x0E, 0x00, 0x00,	// 13. animated play icon frame 0
	0x00, 0x0E, 0x15, 0x15, 0x15, 0x0E, 0x00, 0x00,	// 14. animated play icon frame 1
	0x00, 0x0E, 0x13, 0x15, 0x19, 0x0E, 0x00, 0x00,	// 15. animated play icon frame 2
	0x00, 0x0E, 0x11, 0x1F, 0x11, 0x0E, 0x00, 0x00,	// 16. animated play icon frame 3
};

/*************************************************************/
/********************** LOCAL FUNCTIONS **********************/
/*************************************************************/

void lcdInitHW(void)
{
	// initialize I/O ports
	// if I/O interface is in use
#ifdef LCD_PORT_INTERFACE
	// initialize LCD control lines
	cbi(LCD_CTRL_PORT, LCD_CTRL_RS);
	cbi(LCD_CTRL_PORT, LCD_CTRL_RW);
	cbi(LCD_CTRL_PORT, LCD_CTRL_E);
	// initialize LCD control lines to output
	sbi(LCD_CTRL_DDR, LCD_CTRL_RS);
	sbi(LCD_CTRL_DDR, LCD_CTRL_RW);
	sbi(LCD_CTRL_DDR, LCD_CTRL_E);
	// initialize LCD data port to input
	// initialize LCD data lines to pull-up
	#ifdef LCD_DATA_4BIT
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);		// set data I/O lines to input (4bit)
		outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);	// set pull-ups to on (4bit)
	#else
		outb(LCD_DATA_DDR, 0x00);						// set data I/O lines to input (8bit)
		outb(LCD_DATA_POUT, 0xFF);						// set pull-ups to on (8bit)
	#endif
#endif
}

void lcdBusyWait(void)
{
	// wait until LCD busy bit goes to zero
	// do a read from control register
#ifdef LCD_PORT_INTERFACE
	cbi(LCD_CTRL_PORT, LCD_CTRL_RS);				// set RS to "control"
	#ifdef LCD_DATA_4BIT
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);	// set data I/O lines to input (4bit)
		outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);	// set pull-ups to on (4bit)
	#else
		outb(LCD_DATA_DDR, 0x00);					// set data I/O lines to input (8bit)
		outb(LCD_DATA_POUT, 0xFF);					// set pull-ups to on (8bit)
	#endif
	sbi(LCD_CTRL_PORT, LCD_CTRL_RW);				// set R/W to "read"
	sbi(LCD_CTRL_PORT, LCD_CTRL_E);					// set "E" line
	LCD_DELAY;								// wait
	while(inp(LCD_DATA_PIN) & 1<<LCD_BUSY)
	{
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);		// clear "E" line
		LCD_DELAY;									// wait
		LCD_DELAY;									// wait
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);		// set "E" line
		LCD_DELAY;									// wait
		LCD_DELAY;									// wait
		#ifdef LCD_DATA_4BIT						// do an extra clock for 4 bit reads
			cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
			LCD_DELAY;								// wait
			LCD_DELAY;								// wait
			sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
			LCD_DELAY;								// wait
			LCD_DELAY;								// wait
		#endif
	}
	cbi(LCD_CTRL_PORT, LCD_CTRL_E);			// clear "E" line
	//	leave data lines in input mode so they can be most easily used for other purposes
#else
	// memory bus read
	// sbi(MCUCR, SRW);			// enable RAM waitstate
	// wait until LCD busy bit goes to zero
	while( (*((volatile unsigned char *) (LCD_CTRL_ADDR))) & (1<<LCD_BUSY) );
	// cbi(MCUCR, SRW);			// disable RAM waitstate
#endif
}

void lcdControlWrite(u08 data) 
{
// write the control byte to the display controller
#ifdef LCD_PORT_INTERFACE
	lcdBusyWait();							// wait until LCD not busy
	cbi(LCD_CTRL_PORT, LCD_CTRL_RS);			// set RS to "control"
	cbi(LCD_CTRL_PORT, LCD_CTRL_RW);			// set R/W to "write"
	#ifdef LCD_DATA_4BIT
		// 4 bit write
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);	// set data I/O lines to output (4bit)
		outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );	// output data, high 4 bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );	// output data, low 4 bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
	#else
		// 8 bit write
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_DDR, 0xFF);				// set data I/O lines to output (8bit)
		outb(LCD_DATA_POUT, data);				// output data, 8bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
	#endif
	//	leave data lines in input mode so they can be most easily used for other purposes
	#ifdef LCD_DATA_4BIT
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);		// set data I/O lines to input (4bit)
		outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);	// set pull-ups to on (4bit)
	#else
		outb(LCD_DATA_DDR, 0x00);			// set data I/O lines to input (8bit)
		outb(LCD_DATA_POUT, 0xFF);			// set pull-ups to on (8bit)
	#endif
#else
	// memory bus write
	//sbi(MCUCR, SRW);			// enable RAM waitstate
	lcdBusyWait();				// wait until LCD not busy
	*((volatile unsigned char *) (LCD_CTRL_ADDR)) = data;
	//cbi(MCUCR, SRW);			// disable RAM waitstate
#endif
}

u08 lcdControlRead(void)
{
// read the control byte from the display controller
	register u08 data;
#ifdef LCD_PORT_INTERFACE
	lcdBusyWait();				// wait until LCD not busy
	#ifdef LCD_DATA_4BIT
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);		// set data I/O lines to input (4bit)
		outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);	// set pull-ups to on (4bit)
	#else
		outb(LCD_DATA_DDR, 0x00);			// set data I/O lines to input (8bit)
		outb(LCD_DATA_POUT, 0xFF);			// set pull-ups to on (8bit)
	#endif
	cbi(LCD_CTRL_PORT, LCD_CTRL_RS);		// set RS to "control"
	sbi(LCD_CTRL_PORT, LCD_CTRL_RW);		// set R/W to "read"
	#ifdef LCD_DATA_4BIT
		// 4 bit read
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		LCD_DELAY;						// wait
		LCD_DELAY;						// wait
		data = inb(LCD_DATA_PIN)&0xF0;	// input data, high 4 bits
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
		LCD_DELAY;						// wait
		LCD_DELAY;						// wait
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		LCD_DELAY;						// wait
		LCD_DELAY;						// wait
		data |= inb(LCD_DATA_PIN)>>4;	// input data, low 4 bits
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
	#else
		// 8 bit read
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		LCD_DELAY;						// wait
		LCD_DELAY;						// wait
		data = inb(LCD_DATA_PIN);		// input data, 8bits
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
	#endif
	//	leave data lines in input mode so they can be most easily used for other purposes
#else
	//sbi(MCUCR, SRW);			// enable RAM waitstate
	lcdBusyWait();				// wait until LCD not busy
	data = *((volatile unsigned char *) (LCD_CTRL_ADDR));
	//cbi(MCUCR, SRW);			// disable RAM waitstate
#endif
	return data;
}

void lcdDataWrite(u08 data) 
{
// write a data byte to the display
#ifdef LCD_PORT_INTERFACE
	lcdBusyWait();							// wait until LCD not busy
	sbi(LCD_CTRL_PORT, LCD_CTRL_RS);		// set RS to "data"
	cbi(LCD_CTRL_PORT, LCD_CTRL_RW);		// set R/W to "write"
	#ifdef LCD_DATA_4BIT
		// 4 bit write
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);	// set data I/O lines to output (4bit)
		outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );	// output data, high 4 bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -