Hi,
ich versuche seit zwei Tagen ein Grafik-LCD, Typ LMC84S042C13M
(Datenblatt:
http://www.mark-products.com/pdf/g122x32/84_042/84_042%20spec.pdf)
anzusteuern. Leider schaffe ich nicht einmal es zu initialisieren. Das
LCD bleibt leer. Man kann den Schatten der Pixel erkennen, die
Takterzeugung (2kHz) und die Kontrastspannung stimmen also schon mal.
Ich poste mal meinen Code, vielleicht findet ja jemand einen Fehler:
1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #include <avr/pgmspace.h>
|
4 |
|
5 | #define F_CPU 1000000
|
6 |
|
7 | #include <util/delay.h>
|
8 |
|
9 | #define DATA PORTA
|
10 | #define DATA_DDR DDRA
|
11 |
|
12 | #define CTRL PORTD
|
13 | #define CTRL_DDR DDRD
|
14 |
|
15 | #define A0 (1<<PD0)
|
16 | #define CS2 (1<<PD1)
|
17 | #define CS1 (1<<PD2)
|
18 | #define LCD_E (1<<PD3)
|
19 | #define RESET (1<<PD4)
|
20 |
|
21 | #define LCD_OFF 0xAE
|
22 | #define LCD_ON 0xAF
|
23 | #define LCD_RESET 0xE2
|
24 | #define LCD_STATIC 0xA4
|
25 | #define LCD_STARTLINE 0xC0
|
26 | #define LCD_COLUMNADDR 0x00
|
27 | #define LCD_DUTY32 0xA9
|
28 | #define LCD_ADC 0xA0
|
29 | #define LCD_PAGE1 0xBB
|
30 | #define LCD_RMW_END 0xEE
|
31 |
|
32 | void timer_init(void)
|
33 | {
|
34 | DDRB |= (1<<PB3); // enable OC0 pin
|
35 | TCCR0 |= (1<<WGM01) | (1<<COM00) | (1<<CS01); // CTC mode, toggle OC0 on compare match
|
36 | // prescaler = 8
|
37 | OCR0 = 31; // 2khz
|
38 | }
|
39 |
|
40 | void ports_init(void)
|
41 | {
|
42 | CTRL = 0xff;
|
43 | CTRL &= ~LCD_E;
|
44 | CTRL_DDR = 0xff;
|
45 | DATA = 0xff;
|
46 | DATA_DDR = 0xff;
|
47 | }
|
48 |
|
49 | void write_ctrl(unsigned char c)
|
50 | {
|
51 | DATA = c;
|
52 | CTRL &= ~A0; // A0 low -> command
|
53 | CTRL &= ~(CS1 | CS2); // send to both controllers
|
54 |
|
55 | CTRL |= LCD_E;
|
56 | _delay_us(100);
|
57 | CTRL &= ~LCD_E;
|
58 |
|
59 | CTRL |= (CS1 | CS2);
|
60 | CTRL |= A0;
|
61 | }
|
62 |
|
63 | void write_data(unsigned char c)
|
64 | {
|
65 | DATA = c;
|
66 | CTRL &= ~(CS1 | CS2); // send to both controllers
|
67 |
|
68 | CTRL |= LCD_E;
|
69 | _delay_us(100);
|
70 | CTRL &= ~LCD_E;
|
71 |
|
72 | CTRL |= (CS1 | CS2);
|
73 | }
|
74 |
|
75 | void lcd_reset(void)
|
76 | {
|
77 | CTRL &= ~LCD_RESET;
|
78 | _delay_us(100);
|
79 | CTRL |= LCD_RESET;
|
80 | _delay_ms(100);
|
81 | }
|
82 |
|
83 |
|
84 | int main(void)
|
85 | {
|
86 | timer_init();
|
87 | ports_init();
|
88 | lcd_reset();
|
89 |
|
90 | _delay_ms(100);
|
91 | write_ctrl(LCD_OFF);
|
92 | _delay_ms(10);
|
93 | write_ctrl(LCD_STARTLINE);
|
94 | _delay_ms(10);
|
95 | write_ctrl(LCD_STATIC);
|
96 | _delay_ms(10);
|
97 | write_ctrl(LCD_COLUMNADDR);
|
98 | _delay_ms(10);
|
99 | write_ctrl(LCD_PAGE1);
|
100 | _delay_ms(10);
|
101 | write_ctrl(LCD_DUTY32);
|
102 | _delay_ms(10);
|
103 | write_ctrl(LCD_ADC);
|
104 | _delay_ms(10);
|
105 | write_ctrl(LCD_RMW_END);
|
106 | _delay_ms(10);
|
107 | write_data(0x55);
|
108 | write_data(0x55);
|
109 |
|
110 | for(;;);
|
111 | }
|