C (Atmega128)

1. LCD

freeParksey 2022. 2. 26. 19:34

1. 회로

  • PORTA      : 데이터 처리용
  • PORTG (0~2) : 데이터 제어용
  • 나머지(전원) : VCC=0V, VDD=5V, VEE=저항

 

2. 프로그램 설계

  • 특정 상태 화면 : 초기 화면, 조도센서 값, 온도센서 값, 타이머 시작 시간, 예외 발생등 원하는 문자열을 주면 출력가능한 함수가 필요합니다.
  • 매개 변수 : 따라서 각 줄에 들어갈 내용과 몇초간 출력 할 것인지를 나타내는 변수 필요
외부 소통 함수(disp_some) 초기 화면
각종 예외 발생 상황 보여주기
각 센서 값 출력

 

3. 동작 방식

  • 회로 구성 대로 LCD는 PORTA를 통한 데이터를 처리하고 PORTG를 통해 제어를 합니다.
  • LCD의 위치를 선정하여 아스키코드를 통한 데이터를 출력하여 DDRAM만 사용합니다.
  • IR을 선택하여 제어 명령 쓰고 DDRAM을 선택하여 데이터 값을 출력해줍니다.
  • 전체 동작으로 LCD는 각 센서들의 값을 받아오기 위한 출력 역할, 현재 상황 및 예외 상황이 있을 경우 표시해주기 위하여 사용했습니다.

 

4. 프로그램 설계 전 필수 딜레이

(출처. HD44780 Datasheet )

5. 프로그램 ( lcd.c)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include "header.h" //delay
#include "lcd.h"
 
void init_lcd(void){
    lcd_comm(0x30);
    _delay_us(4100);
    lcd_comm(0x30);
    _delay_us(100);
    lcd_comm(0x30);
    _delay_us(100);
    lcd_comm(0x38); // 초기화, 8bit
    _delay_us(1000);
    lcd_comm(0x0e); // disp On, Cur On, Blink Off
    _delay_us(1000);
    lcd_comm(0x01); // LCD Clear
    _delay_us(2000);
    lcd_comm(0x06);
    _delay_us(1000);
}
 
void lcd_data(unsigned char ch){
    //DR 선택 후 DDRAM  
    LCD_CTRL |= (1 << LCD_RS);  // RS : 1  데이터
    LCD_CTRL &= ~(1 << LCD_RW); // RW : 0  쓰기
    LCD_CTRL |= (1 << LCD_EN);
    _delay_us(50);
    LCD_WDATA = ch;
    _delay_us(50);
    LCD_CTRL &= ~(1 << LCD_EN);
}
void lcd_comm(unsigned char ch){
    // IR 선택 제어 명령 
    LCD_CTRL &= ~(1 << LCD_RS); // RS : 0 명령어
    LCD_CTRL &= ~(1 << LCD_RW); // RW : 0 쓰기 
    LCD_CTRL |= (1 << LCD_EN);
    _delay_us(50);
    LCD_WINST = ch;
    _delay_us(50);
    LCD_CTRL &= ~(1 << LCD_EN);
}
void lcd_delay(double ms){
    while(ms>0){
        _delay_ms(1);
        ms--;    
    }
void lcd_char(unsigned char c){
    lcd_data(c);
    _delay_ms(1);
}
void lcd_str(unsigned char *str){
    while(*str != 0){
        lcd_char(*str);
        str++;
    }
}
void lcd_pos(unsigned char row, unsigned char col){
    lcd_comm(0x80 | ((row * 0x40+ col));
}
void lcd_clear(void){
    lcd_comm(0x01);
    lcd_delay(2);
}
void disp_some(char *disp, char *disp2, int ms){
    lcd_clear();
    lcd_pos(0,0);   //100us
    lcd_str(disp);  //100us
    lcd_pos(1,0);   //100us
    lcd_str(disp2); //100us
    
    if(ms != 0){
        lcd_delay(ms);
        lcd_clear();
    }
}

 

6. 결과