lcd-routines.c


1
// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
2
// http://www.mikrocontroller.net/articles/HD44780
3
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
4
//
5
// Die Pinbelegung ist über defines in lcd-routines.h einstellbar
6
 
7
#include <avr/io.h>
8
#include "lcd-routines.h"
9
#include <util/delay.h>
10
 
11
////////////////////////////////////////////////////////////////////////////////
12
// Erzeugt einen Enable-Puls
13
static void lcd_enable( void )
14
{
15
    LCD_PORT |= (1<<LCD_EN);     // Enable auf 1 setzen
16
    _delay_us( LCD_ENABLE_US );  // kurze Pause
17
    LCD_PORT &= ~(1<<LCD_EN);    // Enable auf 0 setzen
18
}
19
 
20
////////////////////////////////////////////////////////////////////////////////
21
// Sendet eine 4-bit Ausgabeoperation an das LCD
22
static void lcd_out( uint8_t data )
23
{
24
    data &= 0xF0;                       // obere 4 Bit maskieren
25
 
26
    LCD_PORT &= ~(0xF0>>(4-LCD_DB));    // Maske löschen
27
    LCD_PORT |= (data>>(4-LCD_DB));     // Bits setzen
28
    lcd_enable();
29
}
30
 
31
////////////////////////////////////////////////////////////////////////////////
32
// Initialisierung: muss ganz am Anfang des Programms aufgerufen werden.
33
void lcd_init( void )
34
{
35
    // verwendete Pins auf Ausgang schalten
36
    uint8_t pins = (0x0F << LCD_DB) |           // 4 Datenleitungen
37
                   (1<<LCD_RS) |                // R/S Leitung
38
                   (1<<LCD_EN);                 // Enable Leitung
39
    LCD_DDR |= pins;
40
 
41
    // initial alle Ausgänge auf Null
42
   
43
  LCD_PORT &= ~pins;
44
  
45
    // warten auf die Bereitschaft des LCD
46
    _delay_ms( LCD_BOOTUP_MS );
47
    
48
    // Soft-Reset muss 3mal hintereinander gesendet werden zur Initialisierung
49
    lcd_out( LCD_SOFT_RESET );
50
    _delay_ms( LCD_SOFT_RESET_MS1 );
51
 
52
    lcd_enable();
53
    _delay_ms( LCD_SOFT_RESET_MS2 );
54
 
55
    lcd_enable();
56
    _delay_ms( LCD_SOFT_RESET_MS3 );
57
 
58
    // 4-bit Modus aktivieren 
59
    lcd_out( LCD_SET_FUNCTION |
60
             LCD_FUNCTION_4BIT );
61
    _delay_ms( LCD_SET_4BITMODE_MS );
62
 
63
    // 4-bit Modus / 2 Zeilen / 5x7
64
    lcd_command( LCD_SET_FUNCTION |
65
                 LCD_FUNCTION_4BIT |
66
                 LCD_FUNCTION_2LINE |
67
                 LCD_FUNCTION_5X7 );
68
 
69
    // Display ein / Cursor aus / Blinken aus
70
    lcd_command( LCD_SET_DISPLAY |
71
                 LCD_DISPLAY_ON |
72
                 LCD_CURSOR_OFF |
73
                 LCD_BLINKING_OFF); 
74
 
75
    // Cursor inkrement / kein Scrollen
76
    lcd_command( LCD_SET_ENTRY |
77
                 LCD_ENTRY_INCREASE |
78
                 LCD_ENTRY_NOSHIFT );
79
 
80
    lcd_clear();
81
}
82
  
83
////////////////////////////////////////////////////////////////////////////////
84
// Sendet ein Datenbyte an das LCD
85
void lcd_data( uint8_t data )
86
{
87
    LCD_PORT |= (1<<LCD_RS);    // RS auf 1 setzen
88
 
89
    lcd_out( data );            // zuerst die oberen, 
90
    lcd_out( data<<4 );         // dann die unteren 4 Bit senden
91
 
92
    _delay_us( LCD_WRITEDATA_US );
93
}
94
 
95
////////////////////////////////////////////////////////////////////////////////
96
///Funktion für Umlaute
97
void lcd_char( char c )
98
{
99
  switch(c)
100
  {
101
   case 'ä' : c = 0xE1; break;
102
   case 'ö' : c = 0xEF; break;
103
   case 'ü' : c = 0xF5; break;
104
   case 'ß' : c = 0xE2; break;
105
   case '°' : c = 0xDF; break;
106
   case 'µ' : c = 0xE4; break;
107
  }
108
}
109
////////////////////////////////////////////////////////////////////////////////
110
// Sendet einen Befehl an das LCD
111
void lcd_command( uint8_t data )
112
{
113
    LCD_PORT &= ~(1<<LCD_RS);    // RS auf 0 setzen
114
 
115
    lcd_out( data );             // zuerst die oberen, 
116
    lcd_out( data<<4 );           // dann die unteren 4 Bit senden
117
 
118
    _delay_us( LCD_COMMAND_US );
119
}
120
 
121
////////////////////////////////////////////////////////////////////////////////
122
// Sendet den Befehl zur Löschung des Displays
123
void lcd_clear( void )
124
{
125
    lcd_command( LCD_CLEAR_DISPLAY );
126
    _delay_ms( LCD_CLEAR_DISPLAY_MS );
127
}
128
 
129
////////////////////////////////////////////////////////////////////////////////
130
// Sendet den Befehl: Cursor Home
131
void lcd_home( void )
132
{
133
    lcd_command( LCD_CURSOR_HOME );
134
    _delay_ms( LCD_CURSOR_HOME_MS );
135
}
136
 
137
////////////////////////////////////////////////////////////////////////////////
138
// Setzt den Cursor in Spalte x (0..15) Zeile y (1..4) 
139
 
140
void lcd_setcursor( uint8_t x, uint8_t y )
141
{
142
    uint8_t data;
143
 
144
    switch (y)
145
    {
146
        case 1:    // 1. Zeile
147
            data = LCD_SET_DDADR + LCD_DDADR_LINE1 + x;
148
            break;
149
 
150
        case 2:    // 2. Zeile
151
            data = LCD_SET_DDADR + LCD_DDADR_LINE2 + x;
152
            break;
153
 
154
        case 3:    // 3. Zeile
155
            data = LCD_SET_DDADR + LCD_DDADR_LINE3 + x;
156
            break;
157
 
158
        case 4:    // 4. Zeile
159
            data = LCD_SET_DDADR + LCD_DDADR_LINE4 + x;
160
            break;
161
 
162
        default:
163
            return;                                   // für den Fall einer falschen Zeile
164
    }
165
 
166
    lcd_command( data );
167
}
168
 
169
////////////////////////////////////////////////////////////////////////////////
170
// Schreibt einen String auf das LCD
171
 
172
void lcd_string( const char *data )
173
{
174
    while( *data != '\0' )
175
        lcd_data( *data++ );
176
}
177
 
178
////////////////////////////////////////////////////////////////////////////////
179
// Schreibt ein Zeichen in den Character Generator RAM
180
 
181
void lcd_generatechar( uint8_t code, const uint8_t *data )
182
{
183
    // Startposition des Zeichens einstellen
184
    lcd_command( LCD_SET_CGADR | (code<<3) );
185
 
186
    // Bitmuster übertragen
187
    for ( uint8_t i=0; i<8; i++ )
188
    {
189
        lcd_data( data[i] );
190
    }
191
}