b. 임베디드/AVR

[ATmega328] Nokia 5110 LCD (GLCD) bmp파일 출력하기

로봇쟁이 2018. 8. 18. 14:55

저는 bmp파일을 직접 그림판을 통해 도트로 찍어서 만들었습니다. ^^;; (정확하게 확인하기 위해서..)

 

아래 홈페이지를 들어가면 만든 bmp파일로 hex 변환 코드를 만들어줍니다. ^^;;

https://www.riyas.org/2017/01/online-tool-to-convert-bitmap-to-hex-nokia-arduino.html

 

 

 

 

위 코드를 복사하여 아래처럼 작성해서 출력해주시면 됩니다. ^^;

 

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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#define F_CPU   16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define RST_SET         PORTB |= 0x10
#define RST_RESET       PORTB &= ~0x10
#define CE_SET          PORTB |= 0x08
#define CE_RESET        PORTB &= ~0x08
#define DC_SET          PORTB |= 0x04
#define DC_RESET        PORTB &= ~0x04
#define DIN_SET         PORTB |= 0x02
#define DIN_RESET       PORTB &= ~0x02
#define CLK_SET         PORTB |= (1<<0)
#define CLK_RESET       PORTB &= ~(1<<0)
#define BACKLIGHT_ON    PORTD |= (1<<7)
#define BACKLIGHT_OFF   PORTD &= ~(1<<7)
#define LCD_WIDTH   84
#define LCD_HEIGHT  48
unsigned char b[504];
 
//Created with online webtool from www.riyas.org
const unsigned char bitmapArray [] = {
0xff, 0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 
0x02, 0x02, 0x02, 0x02, 0xfe, 0x02, 0x02, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 
0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x04, 0x04, 
0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0xfc, 0xe0, 0xb0, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x04, 0x03, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x06, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 
0x07, 0x00, 0x01, 0x03, 0x06, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 
0xff, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xff, 
};
 
#ifdef enablePartialUpdate
static uint8_t xUpdateMin, xUpdateMax, yUpdateMin, yUpdateMax;
#endif
static void updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax) {
#ifdef enablePartialUpdate
    if (xmin < xUpdateMin) xUpdateMin = xmin;
    if (xmax > xUpdateMax) xUpdateMax = xmax;
    if (ymin < yUpdateMin) yUpdateMin = ymin;
    if (ymax > yUpdateMax) yUpdateMax = ymax;
#endif
}
/*
 * 원하는 위치에 픽셀 출력
 */
void LcdDrawPixel(int x, int y, int bw) {
    if ((x < 0) || (x >= LCD_WIDTH) || (y < 0) || (y >= LCD_HEIGHT))
        return;
    
    if (bw) {
        b[x+ (y/8)*LCD_WIDTH] |= 1<<(y%8);  
    }
    else {
        b[x+ (y/8)*LCD_WIDTH] &= ~(1<<(y%8)); 
    }
    updateBoundingBox(x,y,x,y);
}
void LcdWriteData(byte dat) {
    DC_SET;                             // 데이터 전송시 DC SET
    CE_RESET;
    shiftWrite(dat);
    CE_SET;
}
void LcdXY(int x, int y) {
    //128, 64 첫 포인트 위치
    LcdWriteCmd(0x80 | x); // 가로크기를 지정합니다.
    LcdWriteCmd(0x40 | y);  // 세로크기를 지정합니다.
}
void LcdWriteCmd(byte cmd) {
    DC_RESET;                           // 커맨드 전송시 DC RESET
    CE_RESET;
    shiftWrite(cmd);                    
    CE_SET;
}
void LcdClear(void) {
    memset(b, 0, 504);
    updateBoundingBox(0, 0, LCD_WIDTH-1, LCD_HEIGHT-1);
}
void LcdDisplay(void) {
    char col, maxcol, p;
    for(p=0; p<6; p++) {
        
        #ifdef enablePartialUpdate
        if ( yUpdateMin >= ((p+1)*8) ) {
            continue;   // nope, skip it!
        }
        if (yUpdateMax < p*8) {
            break;
        }
        #endif        
        
        LcdWriteCmd(0x40 | p);          //command(PCD8544_SETYADDR | p);
        
        #ifdef enablePartialUpdate
            col = xUpdateMin;
            maxcol = xUpdateMax;
        #else
            // start at the beginning of the row
            col = 0;
            maxcol = LCD_WIDTH-1;
        #endif   
        
        LcdWriteCmd(0x80 | col);        //command(PCD8544_SETXADDR | col);
        DC_SET;
        CE_RESET;
        for(; col <= maxcol; col++) {
            shiftWrite(b[(LCD_WIDTH*p)+col]);
        }
        CE_SET;
    }
    LcdWriteCmd(0x40);
#ifdef enablePartialUpdate
    xUpdateMin = LCD_WIDTH - 1;
    xUpdateMax = 0;
    yUpdateMin = LCD_HEIGHT-1;
    yUpdateMax = 0;
#endif
}
/*
 * SPI_WRITE 함수
 */
void shiftWrite(uint8_t val) {
    for (uint8_t i = 0; i < 8; i++)  {
        if(!!(val & (1 << (7 - i)))) {
            DIN_SET;
        }
        else {
            DIN_RESET;
        }
        CLK_SET;
        CLK_RESET;
    }
}
int main() {
    // 각각의 핀모드를 출력으로     설정합니다.
    DDRB |= ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<4));
    DDRD |= (1<<7);
    
    char contrast = 0x46;
    BACKLIGHT_ON;
    
    RST_RESET;
    RST_SET;
    
    LcdWriteCmd(0x21);  // LCD 확장 명령
    LcdWriteCmd(0x80 | contrast);  // LCD의 콘트라스트(명암을 결정합니다)
    LcdWriteCmd(0x04);  // TEMP
    LcdWriteCmd(0x14);  // BIAS (BA1, BA0 =  1: 48
    LcdWriteCmd(0x20);  // 확장명령 완료
    LcdWriteCmd(0x0C);  //
    
    for(int i=0; i<504; i++) {
        LcdWriteData(bitmapArray[i]);
    }
    while(1);
}
 
cs
 
참 쉽죠? 

 

반응형