아트메가/활용

CLCD ATMEGA128로 제어하기 1편

원원 2022. 8. 14. 19:08

안녕하세요. 오늘은 MCU로 CLCD를 제어해 보겠습니다.

이전 글에서는 MCU 없이 CLCD를 버튼으로 제어를 했었는데, 버튼으로 했던 동작들을 MCU로 해보겠습니다.

사용하는 MCU는 ATMEGA128입니다.

 

기본 개념들은 이전글 참고 바랍니다

CLCD MCU없이 제어하기 (ADM1602) 1편 => CLCD 기초설명
CLCD MCU없이 제어하기 (ADM1602) 2편 => 여러기능 테스트
CLCD MCU없이 제어하기 (ADM1602) 3편 => DDRAM,CGROM,CGRAM,AC설명

 

 

회로

 

 

코드

코드를 작성하기전에 고려해야 할 사항이 있습니다. CLCD 타이밍입니다.

위의 파형과 비슷하게 MCU 포트를 제어하면 됩니다. MIN값으로 가장 큰게 500ns이므로 코드에서 1ms로 통일했습니다.

그리고 E신호 HIGH -> DATA세팅 -> E신호 LOW로 구현하면 됩니다.

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdio.h>
 
#define HIGH 1
#define LOW 0
 
/* HIGH : Data, LOW: Instruction*/
void lcd_setRS(unsigned char high_low)
{// PC5
    if(high_low)
    PORTC |= 0x20;
    else
    PORTC &= ~0x20;
    _delay_ms(1);
}
 
/* HIGH : Read, LOW: Write*/
void lcd_setRW(unsigned char high_low)
{ // PC6
    if(high_low)
    PORTC |= 0x40;
    else
    PORTC &= ~0x40;
    _delay_ms(1);
}
 
/* HIGH : Enable LOW : Disable*/
void lcd_setEnable(unsigned char high_low)
{ //PC7
    if(high_low)
    PORTC |= 0x80;
    else
    PORTC &= ~0x80;
    _delay_ms(1);
}
 
void lcd_set_8bit_data(unsigned char data)
{
    lcd_setEnable(HIGH);
    _delay_us(0.6);
    PORTA = data;
    _delay_ms(1);
    lcd_setEnable(LOW);
    _delay_ms(1);
    PORTA = 0x00;
}
 
 
void lcd_set_4bit_data(unsigned char data)
{
    lcd_setEnable(HIGH);
    _delay_us(0.6);
    PORTA = data;
    PORTA &= 0xf0;
    _delay_ms(1);
    lcd_setEnable(LOW);
    _delay_ms(1);
    PORTA = 0x00;
 
    lcd_setEnable(HIGH);
    _delay_us(0.6);
    PORTA = (data<<4);
    PORTA &= 0xf0;
    _delay_ms(1);
    lcd_setEnable(LOW);
    _delay_ms(1);
    PORTA = 0x00;
}
 
 
void lcd_init(void)
{
    DDRC = 0xff;
    DDRA = 0xff;
    lcd_setRS(LOW);
    lcd_setRW(LOW);
    lcd_setEnable(LOW);
    _delay_ms(1);
}
 
 
 
int main(void)
{
    lcd_init();
 
    lcd_setRS(LOW);
    lcd_set_8bit_data(0x20);
    lcd_set_4bit_data(0x01);
    lcd_set_4bit_data(0x0f);
    
    lcd_setRS(HIGH);
    lcd_set_4bit_data('W');
    lcd_set_4bit_data('O');
    lcd_set_4bit_data('W');
    lcd_set_4bit_data('O');
    lcd_set_4bit_data('N');
    lcd_set_4bit_data(' ');
    lcd_set_4bit_data('T');
    lcd_set_4bit_data('I');
    lcd_set_4bit_data('S');
    lcd_set_4bit_data('T');
    lcd_set_4bit_data('O');
    lcd_set_4bit_data('R');
    lcd_set_4bit_data('Y');
 
    while(1)
    {
    }
}

 

lcd_setRS => RS핀을 세팅함수
lcd_setRW => RW핀을 세팅함수
lcd_setEnable => E핀을 세팅함수
lcd_set_8bit_data => 8bit data 라인세팅함수
lcd_set_4bit_data => 4bit data 라인세팅함수
lcd_init => lcd 초기함수함수

 lcd_init(); - lcd를 초기화시킵니다
 lcd_setRS(LOW); - Instruction 모드 세팅합니다
 lcd_set_8bit_data(0x20);  - 4bit사용 세팅을 합니다
 lcd_set_4bit_data(0x01); - 화면을 클리어합니다
 lcd_set_4bit_data(0x0f); - display on+커서표시+커서깜박임세팅합니다

lcd_setRS(HIGH); - data 모드 세팅합니다
lcd_set_4bit_data('W'); ~lcd_set_4bit_data('Y');  - data를 입력합니다

위의 과정은 이전 "CLCD MCU없이 제어하기 (ADM1602) 2편"에서 모두 버튼으로 했던 과정입니다
그러나lcd_set_4bit_data(0x01); 화면을 클리어하는 행동은 안했었는데 이번에는 넣었습니다. 그 이유는 MCU랑 CLCD가 연결된 상태에서 전원을 넣을 때 위의 코드가 실행되는데, 이때 전원넣으면서 MCU의 포트가 약간 흔들리면서 의도치 않게 CLCD에 신호가 가므로 클리어하는 동작을 넣은 것입니다.

프로그램실행결과

 

96번째줄~109번째줄을 주석하고 89번째줄 ~ 94번째줄의 파형을 보겠습니다

enable 핀은 clock 역할을 하는 것처럼 보입니다

 
다음글에서는 함수들을 사용하기 편하게 수정해보겠습니다

 

CLCD MCU없이 제어하기 (ADM1602) 1편 => CLCD 기초설명
CLCD MCU없이 제어하기 (ADM1602) 2편 => 여러기능 테스트
CLCD MCU없이 제어하기 (ADM1602) 3편 => DDRAM,CGROM,CGRAM,AC설명
CLCD ATMEGA128로 제어하기 1편
CLCD ATMEGA128로 제어하기 2편
CLCD ATMEGA128로 제어하기 3편(I2C)