BASIC4MCU | 질문게시판 | atmega128을 이용한 LCD 사용에 문제가 발생했습니다.
페이지 정보
작성자 네넴 작성일2024-06-05 12:38 조회1,618회 댓글3건본문
//tpk_lcd8.h
void lcd_busy(void)
{
/*
DDRA = 0x00;
do
{
PORTC &= 0b00000110;
PORTC |= 0b00000010;
PORTC |= 0b00000100;
} while (PINA & 0x80);
DDRA = 0xff;
*/
_delay_us(50);
}
void lcd_command(unsigned char cmd)
{
lcd_busy();
PORTA = cmd;
PORTC &= 0b00000110; //RS = 0
PORTC &= 0b00000101; //RW = 0
PORTC |= 0b00000100; //E = 1
PORTC &= 0b00000011; //E = 0, LCD 라이트 타이밍에 따라 E = 1 -> 0
_delay_us(1); //일정시간 시간지연
}
void lcd_init()
{
DDRA = 0xff;
DDRC = DDRC | 0x0f;
_delay_us(15); //15ms 이상 대기
PORTA = 0b00110000;
PORTC &= 0b00000000; //E, RW, RS = 0, 0, 0
_delay_us(4100); //4.1ms 이상 대기
PORTC &= 0b00000000; //E, RW, RS = 0, 0, 0
_delay_us(100); //100us 이상 대기
PORTC &= 0b00000000; //E, RW, RS = 0, 0, 0
lcd_command(0b00111000); //평션 셋 : 8bit 모드
lcd_command(0b00001000); //디스플레이 오프
lcd_command(0b00000001); //디스플레이 클리어
lcd_command(0b00000110); //엔트리 모드
lcd_command(0b00001111); //디스플레이 온, 커서 온, 커서 깜빡임
}
void lcd_data(unsigned char byte)
{
lcd_busy();
PORTC |= 0b00000001; //RS=1
PORTC &= 0b00000101; //RW=0
PORTC |= 0b00000100; //E=1
_delay_us(50); //일정시간 시간지연
PORTA = byte;
_delay_us(50); //일정시간 시간지연
PORTC &= 0b00000011; //E=0, LCD 라이트 타이밍에 따라 E=1 -> 0
}
void lcd_string(char *str)
{
int i = 0;
while(1){
if(str[i] == '\0') break;
lcd_data(str[i++]);
}
}
void lcd_display_clear()
{
lcd_command(0b00000001);
}
void lcd_cursor_home()
{
lcd_command(0b00000010);
}
void lcd_entry_mode(int ID, int S)
{
unsigned char cmd;
cmd = 0b00001000;
if(ID == 1) cmd = cmd | 0b00000010;
if(S == 1) cmd = cmd | 0b00000001;
lcd_command(cmd);
}
void lcd_display_ONOFF(int D, int C, int B)
{
unsigned cmd;
cmd = 0b00001000;
if (D == 1) cmd = cmd | 0b00000100;
if (C == 1) cmd = cmd | 0b00000010;
if (B == 1) cmd = cmd | 0b00000001;
lcd_command(cmd);
}
void lcd_cursordisplay_shift(int SC, int RL)
{
unsigned cmd;
cmd = 0b00010000;
if (SC == 1) cmd = cmd | 0b00001000;
if (RL == 1) cmd = cmd | 0b00000100;
lcd_command(cmd);
}
void lcd_display_position(unsigned char row, unsigned char col)
{
unsigned cmd;
cmd = 0b10000000 | ((row-1)*0x40+(col-1));
lcd_command(cmd);
}
위와 같은 LCD헤더 파일을 작성해서 사용하고 있습니다.
이제 메인코드에 따라 LCD가 동작했다가 안했다가 합니다
일단 실행 되는 코드는 아래와 같습니다.
#include
#include
#include
#include "tpk_lcd8.h"
volatile unsigned int time_cnt = 0;
unsigned int j, m_sec, sec, min, hour, day, mm, yy = 0;
unsigned char x = 0;
int months[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
ISR(TIMER0_OVF_vect)
{
TCNT0 = 0x06;
time_cnt++;
if(time_cnt>10){m_sec++;time_cnt=0;
if(m_sec>=99){sec++;m_sec=0;
if(sec>=60){min++;sec=0;
if(min>=60){hour++;min=0;
if(hour>23){day++;hour=0;
if(day>months[mm]){mm++;day=1;
if(mm>12){yy++;mm=1;
if(((yy% 4 == 0) && (yy % 100 != 0)) || (yy % 400 == 0)){months[2]=29;}
else {months[2]=28;}}}}}}}
}
}
int main(void)
{
lcd_init();
TCNT0 = 0x06;
TCCR0 = 0x04;
TIMSK = 0x01;
SREG = 0x80;
day=1, mm=1, yy= 1;
while(1)
{
lcd_display_ONOFF(1,0,0);
if(m_sec<50){lcd_display_position(2,5); lcd_data(0x3A);
lcd_display_position(2,8); lcd_data(0x3A);
lcd_display_position(2,11); lcd_data(0x3A);}
else if ((m_sec>50)&&(m_sec<99)){lcd_display_position(2,5); lcd_data(0x20);
lcd_display_position(2,8); lcd_data(0x20);
lcd_display_position(2,11); lcd_data(0x20);}
lcd_display_position(1,4);
lcd_data(0x30+(yy/1000));
x=yy%1000;
lcd_data(0x30+(x/100));
x%=100;
lcd_data(0x30+(x/10));
x%=10;
lcd_data(0x30+(x));
lcd_display_position(1,8);lcd_data(0x2D);
lcd_display_position(1,9);lcd_data(0x30+(mm/10));lcd_data(0x30+(mm%10));
lcd_display_position(1,11);lcd_data(0x2D);
lcd_display_position(1,12);lcd_data(0x30+(day/10));lcd_data(0x30+(day%10));
lcd_display_position(2,3);lcd_data(0x30+(hour/10));lcd_data(0x30+(hour%10));
lcd_display_position(2,6);lcd_data(0x30+(min/10));lcd_data(0x30+(min%10));
lcd_display_position(2,9);lcd_data(0x30+(sec/10));lcd_data(0x30+(sec%10));
lcd_display_position(2,12);lcd_data(0x30+(m_sec/10));lcd_data(0x30+(m_sec%10));
}
}
아래는 동작하지 않는 코드 입니다.
#include
#include
#include "tpk_lcd8.h"
int main()
{
lcd_init();
while (1)
{
lcd_data('0');
_delay_ms(1000);
lcd_data('1');
_delay_ms(1000);
lcd_data('2');
_delay_ms(1000);
lcd_data(0x33);
_delay_ms(1000);
lcd_data(0x34);
_delay_ms(1000);
}
}
간단하게 동작확인을 하기 위해 작성했는데 LCD화면자체가 뜨질 않습니다.다른 함수인 lcd_string또한 위와 같이 작동하지 않습니다.
문제가 무엇인지 알 수 있을까요?
댓글 3
조회수 1,618master님의 댓글
master 작성일
//
void lcd_init(){
DDRA=0xff;
DDRC=0x0f;
_delay_us(15); //15ms 이상 대기
주석에는 15ms 이상이라고 적어놓고 15us 딜레이를 주고 있습니다.
30ms나 50ms로 변경하세요
_delay_ms(50);
네넴님의 댓글
네넴 작성일그래도 동작하지 않는다면 헤더파일을 다시 작성해보는게 좋을까요?
master님의 댓글
master 작성일
https://cafe.naver.com/circuitsmanual/64388
이 회로에서 세그먼트 연결은 하지말고 LCD만 연결해서 돌려보세요
가급적 사용하지 않는 모든 포트의 연결선은 떼어서 영향을 받지 않도록 합니다.