/*
* Main2.c
*
* Created: 2020-11-09 오전 10:29:49
* Author: User
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define LCD_DATA PORTD
#define LCD_COMMAND PORTD
#define LCD_CTRL PORTB
#define LCD_RS 0
#define LCD_RW 1
#define LCD_EN 2
void lcdData(unsigned char data)
{
LCD_CTRL |= (1 << LCD_RS);
LCD_CTRL &= ~ (1 << LCD_RW);
LCD_DATA = data;
LCD_CTRL |= (1 << LCD_EN);
_delay_us(1); //micro second
LCD_CTRL &= ~(1 << LCD_EN);
_delay_ms(2); //mili second
}
void lcdComm(unsigned char cmd){
LCD_CTRL &= ~(1 << LCD_RS);
LCD_CTRL &= ~(1 << LCD_RW);
LCD_COMMAND = cmd;
LCD_CTRL |= (1 << LCD_EN);
_delay_us(1); // 데이터 시트엔 최소 230ns 이지만 넉넉하게 1us를 줬다. (maximum 시간은 정해져 있지 않으므로 시간 많이 줘도 상관없음) delay_ns 함수는 없으므로 0.23을 넣어야 되는데 부동소수 연산을 하면 시간이 너무 오래 걸림
LCD_CTRL &= ~(1 << LCD_EN);
_delay_ms(2); // 39μs+39μs+1.53ms 넉넉잡아 2ms 를 줬다
}
void lcdChar(unsigned char c){
lcdData(c);
}
void lcdStr(char *str){
while(*str !=0){
lcdChar(*str);
str++;
}
}
void lcdPos(char row, char col){
lcdComm(0x80 | (col + row * 0x40));
}
void lcdPosStr(char row, char col, char *str){
lcdPos(row, col);
lcdStr(str);
}
void lcdClear(){
lcdComm(0x01);
}
void setCursorHome(){
// sei(); // interrupt enable. 없어도 동작함
lcdComm(0x02);
}
void lcdInit(){
_delay_ms(30); // Wait for more than 30ms after VDD rises to 4.5V.
lcdComm(0x38); // Function Set 0011 10--
lcdComm(0x0F); // Display ON/OFF Control 0000 1111
lcdComm(0x01); // Display Clear
lcdComm(0x06); // Entry Mode Set
}
int main(){
DDRD = 0xFF; //d포트 출력
DDRB = (1 << LCD_RS | 1 << LCD_RW | 1<< LCD_EN);
lcdInit();
lcdPos(0, 0);
lcdStr("1st line");
#if 0 //feature 처리 . if 가 0이면 else로 들어감
lcdPos(1, 0);
lcdStr("Atmega328");
#else
lcdPosStr(1, 0, "2nd line ");
#endif
while (1);
return 0;
}
RX핀 뽑은상태로 업로드. 후 RX핀 다시 꼽고 아두이노에 리셋버튼 누르기
'임베디드 > Atmega328p' 카테고리의 다른 글
atmega328p 헤더파일 (0) | 2020.12.28 |
---|---|
ATmega328p datasheet (0) | 2020.12.17 |
16x2 lcd 4핀제어. 코드설명 필기 (0) | 2020.11.09 |
16x2 LCD D0, D1 -> C 포트에 꼽은 코드 (0) | 2020.11.07 |
16x2 LCD (LC1621-SMLYH6) (0) | 2020.11.06 |