1 | /****************************************************************
|
2 | * LCD Ausgabe für Hitachi HD44780 kompatible LCD Controller *
|
3 | * *
|
4 | * Mikroontroller: AT90PWM316 *
|
5 | * Clock: 8MHz intern *
|
6 | * LCD-Display: Displaytech 162B *
|
7 | * LCD-Controller: KS0070B *
|
8 | * *
|
9 | * Konfiguration: PORT D7 = LCD D7 *
|
10 | * PORT D6 = LCD D6 *
|
11 | * PORT D5 = LCD D5 *
|
12 | * PORT D4 = LCD D4 *
|
13 | * PORT D3 = LCD E *
|
14 | * PORT D2 = LCD RS *
|
15 | * GND = LCD Vss + LCD R/W + LCD K *
|
16 | * +5V = LCD Vdd *
|
17 | * Poti = LCD V0 *
|
18 | * +5V (über R = 1kOhm) = LCD A *
|
19 | ****************************************************************/
|
20 |
|
21 | #define F_CPU 8000000
|
22 |
|
23 | #include <avr/io.h>
|
24 | #include <util/delay.h>
|
25 |
|
26 | #define LCDPORT PORTD
|
27 | #define LCDDDR DDRD
|
28 | #define LCD_PIN_RS 2
|
29 | #define LCD_PIN_E 3
|
30 | #define LCD_PIN_D4 4
|
31 | #define LCD_PIN_D5 5
|
32 | #define LCD_PIN_D6 6
|
33 | #define LCD_PIN_D7 7
|
34 |
|
35 |
|
36 | /***** LCD STEUERBEFEHLE *****/
|
37 |
|
38 | #define LCD_CLEAR 0x01 // Display löschen
|
39 | #define LCD_HOME 0x02 // Cursor an den Anfang zurück
|
40 | #define LCD_ON 0x0C // 0x0C = LCD ON, Cursor OFF
|
41 | //#define LCD_ON 0x0E // 0x0E = LCD ON, Cursor ON
|
42 | #define LCD_OFF 0x08 // Display OFF
|
43 |
|
44 | /***** HILFSDEFINITIONEN *****/
|
45 |
|
46 | #define BEFEHL 0
|
47 | #define DATEN 1
|
48 | #define sbi(sfr, bit) (sfr |= (1<<bit))
|
49 | #define cbi(sfr, bit) (sfr &= ~(1<<bit))
|
50 |
|
51 |
|
52 | /****** Sendet ein Byte an den LCD Controller ******/
|
53 | void lcd_send(unsigned char type, unsigned char c)
|
54 | {
|
55 | if (type==BEFEHL)
|
56 | cbi(LCDPORT, LCD_PIN_RS); /* RS=0: Befehl folgt ... ******/
|
57 | else
|
58 | sbi(LCDPORT, LCD_PIN_RS); /* RS=1: Daten folgen ... ******/
|
59 |
|
60 | /* (1) HIGH NIBBLE wird gesendet ******/
|
61 | if (bit_is_set(c, 7))
|
62 | sbi(LCDPORT, LCD_PIN_D7);
|
63 | else cbi(LCDPORT, LCD_PIN_D7);
|
64 |
|
65 | if (bit_is_set(c, 6))
|
66 | sbi(LCDPORT, LCD_PIN_D6);
|
67 | else cbi(LCDPORT, LCD_PIN_D6);
|
68 |
|
69 | if (bit_is_set(c, 5))
|
70 | sbi(LCDPORT, LCD_PIN_D5);
|
71 | else cbi(LCDPORT, LCD_PIN_D5);
|
72 |
|
73 | if (bit_is_set(c, 4))
|
74 | sbi(LCDPORT, LCD_PIN_D4);
|
75 | else cbi(LCDPORT, LCD_PIN_D4);
|
76 |
|
77 | /* Flanke zur Übernahme der Daten senden ... ******/
|
78 | sbi(LCDPORT, LCD_PIN_E);
|
79 | _delay_ms(1);
|
80 | cbi(LCDPORT, LCD_PIN_E);
|
81 |
|
82 |
|
83 | /* (2) LOW NIBBLE wird gesendet ******/
|
84 | if (bit_is_set(c, 3))
|
85 | sbi(LCDPORT, LCD_PIN_D7);
|
86 | else cbi(LCDPORT, LCD_PIN_D7);
|
87 |
|
88 | if (bit_is_set(c, 2))
|
89 | sbi(LCDPORT, LCD_PIN_D6);
|
90 | else cbi(LCDPORT, LCD_PIN_D6);
|
91 |
|
92 | if (bit_is_set(c, 1))
|
93 | sbi(LCDPORT, LCD_PIN_D5);
|
94 | else cbi(LCDPORT, LCD_PIN_D5);
|
95 |
|
96 | if (bit_is_set(c, 0))
|
97 | sbi(LCDPORT, LCD_PIN_D4);
|
98 | else cbi(LCDPORT, LCD_PIN_D4);
|
99 |
|
100 | /* Flanke zur Übernahme der Daten senden ... ******/
|
101 | sbi(LCDPORT, LCD_PIN_E);
|
102 | _delay_ms(1);
|
103 | cbi(LCDPORT, LCD_PIN_E);
|
104 |
|
105 | /* (3) Auf den LCD Controller warten ...******/
|
106 | _delay_ms(5);
|
107 | }
|
108 |
|
109 |
|
110 | /****** Stellt eine Zeichenkette am LCD dar ******/
|
111 | void lcd_write_zeile1(char *t)
|
112 | {
|
113 | unsigned char i;
|
114 | for (i=0;i<255;i++)
|
115 | {
|
116 | if (t[i]==0) // String-Ende? Dann raus hier ...
|
117 | return;
|
118 | else
|
119 | lcd_send(DATEN, t[i]);
|
120 | }
|
121 | }
|
122 |
|
123 | /****** Initialisierung des LCD Controllers *****/
|
124 | void lcd_init()
|
125 | {
|
126 | /* Port auf Ausgang schalten */
|
127 | LCDPORT = 0x00;
|
128 | LCDDDR = 0xFF;
|
129 |
|
130 | _delay_ms(40); // Warten bis LCD bereit ...
|
131 |
|
132 | /* 4-bit Modus konfigurieren ------Function-Set 1*/
|
133 | sbi(LCDPORT, LCD_PIN_D5);
|
134 | cbi(LCDPORT, LCD_PIN_D4);
|
135 |
|
136 | _delay_ms(40);
|
137 | /* 4-bit Modus konfigurieren ------Function-Set 2*/
|
138 | sbi(LCDPORT, LCD_PIN_D5);
|
139 | cbi(LCDPORT, LCD_PIN_D4);
|
140 |
|
141 | _delay_ms(5);
|
142 | /* 4-bit Modus konfigurieren ------Function-Set 3*/
|
143 | sbi(LCDPORT, LCD_PIN_D5);
|
144 | cbi(LCDPORT, LCD_PIN_D4);
|
145 |
|
146 | /* 4-Bit Modus starten ... */
|
147 | sbi(PORTD, LCD_PIN_E);
|
148 | cbi(PORTD, LCD_PIN_E);
|
149 | _delay_ms(5);
|
150 |
|
151 | /* 2 Zeilen, 4-Bit Modus */
|
152 | lcd_send(BEFEHL, 0x28);
|
153 | //lcd_send(BEFEHL, 0x14);
|
154 |
|
155 | lcd_send(BEFEHL, LCD_OFF);
|
156 | lcd_send(BEFEHL, LCD_CLEAR);
|
157 |
|
158 | lcd_send(BEFEHL, 0x06);
|
159 | lcd_send(BEFEHL, LCD_ON);
|
160 | }
|
161 |
|
162 |
|
163 | /****** Hilfsfunktion: Warte i Sekunden ******/
|
164 | void sekunde(char i)
|
165 | {
|
166 | unsigned char k;
|
167 | for (;i>0;i--)
|
168 | {
|
169 | for (k=0;k<10;k++)
|
170 | _delay_ms(50);
|
171 | }
|
172 | }
|
173 |
|
174 | /***** HAUPTPROGRAMM *****/
|
175 |
|
176 | int main(void)
|
177 | {
|
178 | _delay_ms(50);
|
179 | lcd_init();
|
180 | lcd_write_zeile1("Starting LCD...");
|
181 |
|
182 | while (1)
|
183 | {
|
184 | sekunde(5);
|
185 | lcd_send(BEFEHL, LCD_CLEAR);
|
186 | lcd_write_zeile1("LCD-Test");
|
187 |
|
188 | sekunde(5);
|
189 | lcd_send(BEFEHL, LCD_CLEAR);
|
190 | lcd_write_zeile1("LCD-Test Zeile2");
|
191 | }
|
192 | }
|