BASIC4MCU | 질문게시판 | LCD 화면 문자출력이 안되요..
페이지 정보
작성자 chelsea 작성일2022-06-09 10:09 조회6,562회 댓글3건본문
16 X2 LCD의 LED는 켜지는데 문자 출력이 전혀 되지 않고 있습니다.
잘못된 코드가 있는지 확인 부탁드립니다.
첨부된 파일은 LCD와 보드 연결이미지입니다.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define F_CPU 8000000UL
#define LCD_RS PORTC4 //0값이면 instruction, 1값이면 data 전송
#define LCD_EN PORTC5 //하강엣지에서 데이터 전달
#define LCD_DIR DDRC
#define LCD_PORT PORTC
#define LCD_Clear 0x01
#define LCD_Cursor 0x03 //function set:4bit data, 2line display, 5*8 dots
#define LCD_Function_Set 0x28
#define LCD_On 0x0E //0000 11(set display)1(cursor)0(blink)
#define LCD_Entry 0x06 //Cursor increased, no shift
volatile float calibrationfactor = 4.5;
volatile float flowrate=0;
volatile float cal=0;
volatile int pulsecount=0;
volatile int millisec=0;
volatile char sec=0;
void init_port()
{
DDRD = 0xFB;
PORTD = 0x40;
}
void init_timer1()
{
TCCR1A = (0<<WGM10)|(0<<COM1A0);
TCCR1B = (1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);
OCR1A = 121; //OCA1A값을 십진값 121로 설정
TIMSK = (1<<OCIE1A);
/*TCCR0A = (1 << WGM01);
TIMSK0 |= (1 << OCIE0A);
TCCR0B |= (1 << CS02) | (1 << CS00);
OCR0A = 0x07;*/
}
// LCD
void Write_Command_LCD(char Command)
{
LCD_PORT = (LCD_PORT & 0xF0) | (Command & 0xF0); //상위 4BIT 출력
//LCD_PORT=Command; <- 8bit를 사용할 경우
LCD_PORT &= ~(1<<LCD_RS); // RS=0, command reg.
LCD_PORT |= (1<<LCD_EN); //LCD_E=1; //하강 Edge에서 데이터를 전달하기 때문에 High 상태 유지 후
_delay_ms(1);
LCD_PORT &= ~(1<<LCD_EN); //LCD_E=0; //low 상태로 전환하여 데이터를 전달.
_delay_ms(1);
LCD_PORT = (LCD_PORT & 0xF0) | (Command >> 4); //하위 4BIT 출력
LCD_PORT |= (1<<LCD_EN); //LCD_E=1; //하강 Edge에서 데이터를 전달하기 때문에 High 상태 유지 후
_delay_ms(1);
LCD_PORT &= ~(1<<LCD_EN); //LCD_E=0; //low 상태로 전환하여 데이터를 전달.
_delay_ms(10);
}
void PutsChar_LCD(int data)
{
LCD_PORT = (LCD_PORT & 0xF0) | (data & 0xF0); //상위 4BIT 출력
LCD_PORT &= ~(1<<LCD_RS); // RS=0, command reg.
LCD_PORT |= (1<<LCD_EN); //LCD_E=1; //하강 Edge에서 데이터를 전달하기 때문에 High 상태 유지 후
_delay_ms(1);
LCD_PORT &= ~(1<<LCD_EN); //LCD_E=0; //low 상태로 전환하여 데이터를 전달.
_delay_ms(1);
LCD_PORT = (LCD_PORT & 0xF0) | (data >> 4); //하위 4BIT 출력
LCD_PORT |= (1<<LCD_EN); //LCD_E=1; //하강 Edge에서 데이터를 전달하기 때문에 High 상태 유지 후
_delay_ms(1);
LCD_PORT &= ~(1<<LCD_EN); //LCD_E=0; //low 상태로 전환하여 데이터를 전달.
_delay_ms(10);
}
void String_LCD(char *s)
{
while(*s)
PutsChar_LCD(*s++);
}
//
void LCD_Init(void)
{
LCD_DIR = 0xFF;
_delay_ms(50);
Write_Command_LCD(LCD_Function_Set); _delay_ms(2);
Write_Command_LCD(LCD_On); _delay_ms(2);
Write_Command_LCD(LCD_Clear); _delay_ms(2);
Write_Command_LCD(LCD_Entry); _delay_ms(2);
Write_Command_LCD(0x02); _delay_ms(2); //Return Home
}
//
ISR (TIMER1_COMPA_vect)
{
if(++millisec>=1000)
{
millisec=0; // 1sec
if(sec<6)
{
if(++sec>=6)
PORTD=0x28; //6sec (PD6) Off, (PD5) on, (PD3) On
}
cal=pulsecount/calibrationfactor; //L/min
flowrate=cal*60; //L/hour
if(flowrate==0)
{
PORTD|= 2; //PD1 High Output (Water flow signal)
}
else PORTD&=~2; //PD1 Low Output
pulsecount = 0;
}
}
ISR (INT0_vect)
{
pulsecount++;
}
int main(void){
char water[20]={0};
init_port();
init_timer1();
MCUCR |= (0 << ISC00)|(1 << ISC01); //The falling edge of INT0 generates an interrupt request.
GICR |= (1 << INT0); //INT0 Enable
sei();
LCD_Init();
while (1)
{
sprintf(water,"WATERFLOW:%3f L/H",flowrate);
Write_Command_LCD(0x08);
String_LCD(water);
_delay_ms(10);
}
}
댓글 3
조회수 6,562master님의 댓글
master 작성일
#define LCD_RS PORTC4 //0값이면 instruction, 1값이면 data 전송
#define LCD_EN PORTC5 //하강엣지에서 데이터 전달
#define LCD_DIR DDRC
#define LCD_PORT PORTC
회로도하고 핀선언하고 맞지 않습니다.
chelsea님의 댓글
chelsea
답변 감사합니다. 이미지에 나와있는 핀번호를 잘 못 올렸습니다. PB0->PC4, PB1->PC5, PB4~PB7 ->PC0~PC3입니다.
올려주신 코드에 위 #define핀번호만 바꾸면 될 것 같은데.. 혹시 다른 내용도 변경되어야 하는 부분이 있을까요?
master님의 댓글
master 작성일
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#define LCD_RS 0x10 // PC4
#define LCD_EN 0x20 // PC5
#define LCD_DIR DDRC
#define LCD_PORT PORTC
//
#define LCD_Clear 0x01
#define LCD_Cursor 0x03 //function set:4bit data, 2line display, 5*8 dots
#define LCD_Function_Set 0x28
#define LCD_On 0x0E //0000 11(set display)1(cursor)0(blink)
#define LCD_Entry 0x06 //Cursor increased, no shift
//
volatile float calibrationfactor=4.5,flowrate=0,cal=0;
volatile int pulsecount=0,millisec=0;
volatile char sec=0;
//
void Write_Command_LCD(char Command){
LCD_PORT=(Command >> 4)|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_us(1);
LCD_PORT=(Command&0x0F)|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_ms(2);
}
//
void PutsChar_LCD(int data){
LCD_PORT=(Command >> 4)|LCD_RS|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_us(1);
LCD_PORT=(Command&0x0F)|LCD_RS|LCD_EN; _delay_us(1); LCD_PORT&=~LCD_EN; _delay_us(40);
}
//
void String_LCD(char *s){ while(*s)PutsChar_LCD(*s++); }
//
void LCD_Init(void){
LCD_DIR=0xFF;
_delay_ms(50);
Write_Command_LCD(LCD_Function_Set);
Write_Command_LCD(LCD_On);
Write_Command_LCD(LCD_Clear);
Write_Command_LCD(LCD_Entry);
Write_Command_LCD(0x02); //Return Home
}
//
void init_timer1(){
TCCR1A=(0<<WGM10)|(0<<COM1A0);
TCCR1B=(1<<WGM12)|(0<<CS12)|(1<<CS11)|(1<<CS10);
OCR1A=121; //OCA1A값을 십진값 121로 설정
TIMSK=(1<<OCIE1A);
/*TCCR0A=(1<<WGM01); TIMSK0|=(1<<OCIE0A); TCCR0B|=(1<<CS02)|(1<<CS00); OCR0A=0x07;*/
}
//
ISR(TIMER1_COMPA_vect){
if(++millisec>=1000){
millisec=0; // 1sec
if(sec<6){
if(++sec>=6)PORTD=0x28; //6sec (PD6)Off,(PD5)on,(PD3)On
}
cal=pulsecount/calibrationfactor; //L/min
flowrate=cal*60; //L/hour
if(flowrate==0){
PORTD|=2; //PD1 High Output(Water flow signal)
}
else PORTD&=~2; //PD1 Low Output
pulsecount=0;
}
}
//
ISR(INT0_vect){ pulsecount++; }
//
int main(void){
char water[20]={0};
init_timer1();
MCUCR|=(0<<ISC00)|(1<<ISC01); //The falling edge of INT0 generates an interrupt request.
GICR|=(1<<INT0); //INT0 Enable
sei();
LCD_Init();
while(1){
sprintf(water,"WATERFLOW:%3f L/H",flowrate);
Write_Command_LCD(0x80);
String_LCD(water);
_delay_ms(100);
}
}