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