본문 바로가기
임베디드/Atmega328p

16x2 LCD (LC1621-SMLYH6)

by sj0020 2020. 11. 6.
/*
 * LCD16x2.c
 *
 * Created: 2020-11-06 오후 2:00:16
 * Author : User
 */ 

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>

#define RS	PORTB0
#define RW	PORTB1
#define E	PORTB2


int main(void)
{
	int r, c;
	char *string[] = {"1st line", "2nd line"};
	lcdInit();
	
	for (r=0; r<2; r++){
		for(c =0; c<16; c++){
			if (string[r][c] == '\0'){
				if (r == 0){
					//DDRAM 주소 설정 및 커서 위치 이동
					LCD_command(0xC0);
				}
				break;
			}
			else{
				LCD_data_write(string[r][c]);
			}			
		}		
	}
    while (1);
    
}

void get_E_Strobe()
{
	volatile int i; //
	
	PORTB |= 1 << E; //E signal high
	for (i=0; i<10; i++);  //for문을 도는데에 최소 230가 걸림.시간을 delay 시켜주는 코드
	PORTB &= ~(1 << E);	// E signal low 
}

void wait_BusyFlag()
{
	volatile int i;
	unsigned char bf;
	
	//Busy Flag(LCD의D7)를 읽기 위해 PORTD를 입력핀으로 설정
	DDRD = 0x0;
	// RS -> low, RW -> high
	PORTB = (PORTB & ~(1 <<RS)) | 1 << RW;
	
	do{
		PORTB |= 1 << E;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
		for (i=0; i<10; i++);
		// bf가 1이면 내부 동작 진행중
		// bf가 0이면 내부 동작 완료. 다음 동작 명령 수령 가능.
		bf = PIND & (1 << PORTD7);
		PORTB &= ~(1 << E);
	} while(bf); //bf가 1이면 계속 처리... 0이 될때까지 동작		
}

// 명령 레지스터에 명령어 전달
void LCD_command(unsigned char data)
{
	wait_BusyFlag();	//bf가 0이 될때까지 대기
	DDRD = 0xFF;		//D포트를 출력으로 설정
	PORTD = data;		// 명령어 전달. data 출력
	// lcd command(화면 클리어~ DDRAM 주소 설정)을 위한 RS, RW 설정
	PORTB &= ~(1 << RS | 1 << RW);
	get_E_Strobe();
}

//data 레지스터에 데이터 기록
void LCD_data_write(unsigned char data)
{
	wait_BusyFlag();
	DDRD = 0xFF;
	PORTD = data;
	// ram 데이터 쓰기. RS -> high, RW -> low
	PORTB = (PORTB | 1 << RS) & ~(1 << RW);
	get_E_Strobe();
}

void lcdInit()
{
	DDRB |= 1 << RS | 1 << RW | 1 << E;
	PORTB &= ~(1 << RS | 1 << E | 1 << RW);
	
	// 인터페이스 / 디스플레이 설정 - 00(RS,R/W) 0011 11--
	// DL: 1 - 8bit interface
	// N: 1 - 2줄 표시
	// F: 1 - 문자 5x10 dot
	LCD_command(0x3C);
	
	// 커서 초기 위치 - 00 0000 001-
	// 커서 위치를 제 1행 1열로 이동.
	LCD_command(0x02);
	
	// 화면 클리어 - 00 0000 0001
	// 아스키코드 0x20 으로 화면 처리후 커서 위치를 1행 1열로 이동
	LCD_command(0x01);
	
	// 문자 입력 모드 - 00 0000 0110
	// 커서를 오른쪽으로 이동하면서 문자 입력
	LCD_command(0x06);
	
	// 디스플레이 on/off 제어 - 00 0000 1111
	// D: 1 - 디스플레이 on
	// C: 1 - 커서 on
	// B: 1 - 커서 깜빡임 on
	LCD_command(0x0f);
}

LC1621-SMLYH6.pdf
0.36MB

 

 

 

https://electronicsdo.tistory.com/entry/ATmega128%EC%8B%A4%EC%A0%84-CLCD-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

 

[ATmega128실전] CLCD 사용하기-1

ATmega128이나 ARM을 이용하여 작품을 만드는 졸작시즌이 드디어 다가왔습니다! ㅎㅎ 전국의 공대생분들께선 벌써부터 인터넷에 자료를 긁어모으시면서 이리저리 캡스톤을 구상하고 계실텐데요

electronicsdo.tistory.com