D0, D1이 RX, TX에 꽂혀있어서 업로드가 잘 안되는 듯함. rx tx 뽑아서 업로드 하고 꽂고 다시 업로드 하면 될때도 있고. 이렇게 여러번 해도 안될때도 있고. 꼽힌채로 업로드 해서 될 때 도 있음
-> rx tx를 C 포트에 꼽으면 되는가? 해서 아래 코드를 시도해봄
/*
* 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", "pin23"};
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;
//unsigned char c_data = 0b00000011 & data;
//PORTC = c_data;
//unsigned char d_data = 0b11111100 & data;
//PORTD = d_data;
//Busy Flag(LCD의D7)를 읽기 위해 PORTD를 입력핀으로 설정
DDRD = 0x0;
DDRC = 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포트를 출력으로 설정
DDRC = 0xFF;
unsigned char c_data = 0b00000011 & data;
unsigned char d_data = 0b11111100 & data;
PORTD = d_data; // 명령어 전달. data 출력
PORTC = c_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;
DDRC = 0xFF;
unsigned char c_data = 0b00000011 & data;
unsigned char d_data = 0b11111100 & data;
PORTD = d_data;
PORTC = c_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 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);
}
'임베디드 > Atmega328p' 카테고리의 다른 글
16x2 8핀제어 데이터시트 그대로 적은 코드 (0) | 2020.11.09 |
---|---|
16x2 lcd 4핀제어. 코드설명 필기 (0) | 2020.11.09 |
16x2 LCD (LC1621-SMLYH6) (0) | 2020.11.06 |
interrupt 2개 사용 LED 2개 제어 (0) | 2020.11.06 |
interrupt 하나 사용 ,LED 하나 (0) | 2020.11.05 |