1 | #include <inttypes.h> //Datentypen wie z.B. uint8_t
|
2 | #include <avr/io.h> //Definitionen fuer Ports und Register
|
3 | #include <util/delay.h> //Verzoegerungsschleifen
|
4 | #include "lcd.h" //eigene Header-Datei mit Definitionen fuer das Display
|
5 |
|
6 |
|
7 |
|
8 | static void lcdEnable(void){ //nach RS und R/W muss Enable zuerst auf High und dann auf LOW gezogen werden
|
9 | LCD_CONTROL_PORT |= (1<<LCD_ENABLE); //Enable-Bit auf 1
|
10 | _delay_us(LCD_ENABLE_TIME_MS); //Enable-Pulse-Width (High Level) abwarten
|
11 | LCD_CONTROL_PORT &= ~(1<<LCD_ENABLE); //Enable-Bit auf 0
|
12 | }
|
13 |
|
14 | // Sendet eine 4-bit Ausgabeoperation an das LCD
|
15 | static void lcdOut( uint8_t data ){
|
16 | data &= 0xF0; // obere 4 Bit maskieren
|
17 | LCD_DATA_PORT &= ~(0xF0>>(4-LCD_FIRST_DATA_PIN)); // Port-Pins mit Datenleitungen auf 0 setzen
|
18 | LCD_DATA_PORT |= (data>>(4-LCD_FIRST_DATA_PIN)); // Bits setzen
|
19 | lcdEnable();
|
20 | }
|
21 |
|
22 | static void lcdCommand(uint8_t data){
|
23 | LCD_CONTROL_PORT &= ~(1<<LCD_REGISTER_SELECT); //keine Daten ins Register schreiben, sondern command ausfuehren!
|
24 |
|
25 | lcdOut(data); //erst die linken 4 Bits schicken
|
26 | lcdOut(data<<4); //danach die anderen 4 Bits nach links schieben und schicken
|
27 | _delay_us(LCD_COMMAND_TIME_US);
|
28 | }
|
29 |
|
30 |
|
31 | static void lcdData(uint8_t data){ //Schreibt was auf dem Display...
|
32 | LCD_CONTROL_PORT |= (1<<LCD_REGISTER_SELECT); //Daten ins Register
|
33 |
|
34 | lcdOut(data); // zuerst die oberen,
|
35 | lcdOut(data<<4); // dann die unteren 4 Bit senden
|
36 |
|
37 | _delay_us( LCD_WRITEDATA_US );
|
38 |
|
39 | }
|
40 |
|
41 | void lcdClear(void){
|
42 | lcdCommand(LCD_CLEAR_DISPLAY);
|
43 | _delay_ms(LCD_CLEAR_DISPLAY_MS);
|
44 | }
|
45 |
|
46 | void lcdInit(void){
|
47 | uint8_t lcdPins = (1<<LCD_REGISTER_SELECT | 1<<LCD_ENABLE | 1<<LCD_READ_WRITE); //Alle verwendeten Pins
|
48 | uint8_t dataPins = 0x0F<<LCD_FIRST_DATA_PIN;
|
49 |
|
50 | LCD_CONTROL_DDR |= lcdPins; //Alle verwendeten Pins als Ausgang
|
51 | LCD_CONTROL_PORT &= ~lcdPins; //Alle verwendeten Pins mit 0 initialisieren, (Tilde ~ negiert)
|
52 |
|
53 | LCD_DATA_DDR |= dataPins;
|
54 | LCD_DATA_PORT &= dataPins;
|
55 |
|
56 | _delay_ms(LCD_INTERNAL_RESET_TIME_MS); //Auf das Ende des internen Reset warten A
|
57 | lcdOut(LCD_8_BIT); //Interface auf 8-Bit setzen C
|
58 | _delay_ms(LCD_INIT_TIME_1_MS); //mindestens 4.1 ms warten D
|
59 |
|
60 | lcdEnable();
|
61 | _delay_ms(LCD_INIT_TIME_2_MS); //mindestens 100 us warten
|
62 |
|
63 | lcdEnable();
|
64 | _delay_ms(LCD_INIT_TIME_3_MS); //mindestens 100 us warten
|
65 |
|
66 | lcdOut( LCD_SET_FUNCTION | LCD_FUNCTION_4BIT ); //Interface auf 4-Bit setzen H
|
67 | _delay_ms(LCD_4_BIT_TIME_MS);
|
68 |
|
69 |
|
70 |
|
71 | //Ab hier muss mit lcdCommand gearbeitet werden, da das Interface auf 4-Bit eingestellt ist
|
72 | lcdCommand(LCD_SET_FUNCTION | LCD_FUNCTION_4BIT | LCD_FUNCTION_2LINE | LCD_FUNCTION_5X7 ); //2-zeilig, 5x7-Punkt-Matrix
|
73 | lcdCommand(LCD_SET_DISPLAY | LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINKING_OFF); //Display an, Cursor aus, Blinken aus
|
74 | lcdCommand(LCD_SET_ENTRY | LCD_ENTRY_INCREASE | LCD_ENTRY_NOSHIFT); //Cursor Bewegungsrichtung: Inkrement, Display Shift aus (kein Scrollen)
|
75 |
|
76 | lcdClear();
|
77 | }
|
78 |
|
79 | // Setzt den Cursor in Spalte x (0..15) Zeile y (1..4)
|
80 | void lcdSetCursor(uint8_t x, uint8_t y){
|
81 | uint8_t data;
|
82 |
|
83 | switch (y)
|
84 | {
|
85 | case 1: // 1. Zeile
|
86 | data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;
|
87 | break;
|
88 |
|
89 | case 2: // 2. Zeile
|
90 | data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;
|
91 | break;
|
92 |
|
93 | case 3: // 3. Zeile
|
94 | data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;
|
95 | break;
|
96 |
|
97 | case 4: // 4. Zeile
|
98 | data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;
|
99 | break;
|
100 |
|
101 | default:
|
102 | return; // für den Fall einer falschen Zeile
|
103 | }
|
104 |
|
105 | lcdCommand(data);
|
106 | }
|
107 |
|
108 | //Schreibt einen String auf das Display
|
109 | void lcdString( const char *data ){
|
110 | while(*data != '\0')
|
111 | lcdData(*data++);
|
112 | }
|
113 |
|
114 | int main(void){
|
115 | lcdInit();
|
116 |
|
117 | lcdString("Gleich gibts");
|
118 | lcdSetCursor(5,2);
|
119 | lcdString("Essen");
|
120 | while(1){
|
121 |
|
122 | }
|
123 | return 0;
|
124 | }
|