http://winavr.Scienceprog.com
AVR LCD 제어할때 4비트 모드로 사용하고 데이터 포트와 제어포트를 따로 쓰고 싶을때 !!
이 예에서는 데이터는 PORTD, 컨트롤포트는 PORTC로 나누어 쓰고 있다
단, PORTD는 하이비트, PORTC는 로우포트를 사용할것
//*****************************************************************************
//
// File Name : 'lcd_lib.h'
// Title : 8 and 4 bit LCd interface
// Author : Scienceprog.com - Copyright (C) 2007
// Created : 2007-03-29
// Revised : 2007-08-08
// Version : 1.0
// Target MCU : Atmel AVR series
//
// This code is distributed under the GNU Public License
// which can be found at http://www.gnu.org/licenses/gpl.txt
//
//*****************************************************************************
#ifndef LCD_LIB
#define LCD_LIB
#include <inttypes.h>
//Uncomment this if LCD 4 bit interface is used
//******************************************
#define LCD_4bit
//***********************************************
#define LCD_RS 0 //define MCU pin connected to LCD RS
#define LCD_RW 1 //define MCU pin connected to LCD R/W
#define LCD_E 2 //define MCU pin connected to LCD E
#define LCD_D0 0 //define MCU pin connected to LCD D0
#define LCD_D1 1 //define MCU pin connected to LCD D1
#define LCD_D2 2 //define MCU pin connected to LCD D1
#define LCD_D3 3 //define MCU pin connected to LCD D2
#define LCD_D4 4 //define MCU pin connected to LCD D3
#define LCD_D5 5 //define MCU pin connected to LCD D4
#define LCD_D6 6 //define MCU pin connected to LCD D5
#define LCD_D7 7 //define MCU pin connected to LCD D6
#define LDP PORTD //define MCU port connected to LCD data pins
#define LCP PORTC //define MCU port connected to LCD control pins
#define LDDR DDRD //define MCU direction register for port connected to LCD data pins
#define LCDR DDRC //define MCU direction register for port connected to LCD control pins
#define LCD_CLR 0 //DB0: clear display
#define LCD_HOME 1 //DB1: return to home position
#define LCD_ENTRY_MODE 2 //DB2: set entry mode
#define LCD_ENTRY_INC 1 //DB1: increment
#define LCD_ENTRY_SHIFT 0 //DB2: shift
#define LCD_ON_CTRL 3 //DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY 2 //DB2: turn display on
#define LCD_ON_CURSOR 1 //DB1: turn cursor on
#define LCD_ON_BLINK 0 //DB0: blinking cursor
#define LCD_MOVE 4 //DB4: move cursor/display
#define LCD_MOVE_DISP 3 //DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT 2 //DB2: move right (0-> left)
#define LCD_FUNCTION 5 //DB5: function set
#define LCD_FUNCTION_8BIT 4 //DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3 //DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2 //DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM 6 //DB6: set CG RAM address
#define LCD_DDRAM 7 //DB7: set DD RAM address
// reading:
#define LCD_BUSY 7 //DB7: LCD is busy
#define LCD_LINES 2 //visible lines
#define LCD_LINE_LENGTH 16 //line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR 0x00
#define LCD_LINE1_DDRAMADDR 0x40
#define LCD_LINE2_DDRAMADDR 0x14
#define LCD_LINE3_DDRAMADDR 0x54
// progress bar defines
#define PROGRESSPIXELS_PER_CHAR 6
LCD 라이브러리 화일
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include "lcd_lib.h"
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
const uint8_t LcdCustomChar[] PROGMEM=//define 8 custom LCD chars
{
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
0x18, 0x1C, 0x1E, 0x1F, 0x1E, 0x1C, 0x18, 0x00 // 7. fast-forward arrow
};
// ----------------------------------------------------------------------------------
void LCDchardefine(void){ // call after LCDinit()
//init 8 custom chars
uint8_t ch=0, chn=0;
while(ch<64){
LCDdefinechar((LcdCustomChar+ch),chn++);
ch=ch+8;
}
}
// ----------------------------------------------------------------------------------
void LCDsendChar(uint8_t ch){ //Sends Char to LCD
//4 bit part
LDP=(ch&0b11110000);
LCP|=1<<LCD_RS;
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
LCP&=~(1<<LCD_RS);
_delay_ms(1);
LDP=((ch&0b00001111)<<4);
LCP|=1<<LCD_RS;
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
LCP&=~(1<<LCD_RS);
_delay_ms(1);
}
// ----------------------------------------------------------------------------------
void LCDsendCommand(uint8_t cmd){ //Sends Command to LCD
//4 bit part
LDP=(cmd&0b11110000);
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
LDP=((cmd&0b00001111)<<4);
LCP|=1<<LCD_E;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
}
// ----------------------------------------------------------------------------------
void LCDinit(void){//Initializes LCD{
//4 bit part
_delay_ms(15);
LDP=0x00;
LCP=0x00;
LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4;
LCDR|=1<<LCD_E|1<<LCD_RW|1<<LCD_RS;
//---------one------
LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
//-----------two-----------
LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|1<<LCD_D4; //4 bit mode
LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
//-------three-------------
LDP=0<<LCD_D7|0<<LCD_D6|1<<LCD_D5|0<<LCD_D4; //4 bit mode
LCP|=1<<LCD_E|0<<LCD_RW|0<<LCD_RS;
_delay_ms(1);
LCP&=~(1<<LCD_E);
_delay_ms(1);
//--------4 bit--dual line---------------
LCDsendCommand(0b00101000);
//-----increment address, invisible cursor shift------
LCDsendCommand(0b00001100);
}
// ----------------------------------------------------------------------------------
void LCDstring(uint8_t* data, uint8_t nBytes){ //Outputs string to LCD
register uint8_t i;
// check to make sure we have a good pointer
if (!data) return;
// print data
for(i=0; i<nBytes; i++)
LCDsendChar(data[i]);
}
// ----------------------------------------------------------------------------------
void LCDGotoXY(uint8_t x, uint8_t y){ //Cursor to X Y position
register uint8_t DDRAMAddr;
// remap lines into proper order
switch(y) {
case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
}
// set data address
LCDsendCommand(1<<LCD_DDRAM | DDRAMAddr);
}
// ----------------------------------------------------------------------------------