1 | /*Testdatei aus dem AVR-Tutorial*/
|
2 |
|
3 | //Pinbelegung über defines einstellbar
|
4 | #include <avr/io.h>
|
5 | #include <util/delay.h>
|
6 | #include "lcd-routines.h"
|
7 |
|
8 | //LCD-Befehle
|
9 | #define CLEAR_DISPLAY 0x01
|
10 | #define CURSOR_HOME 0x02
|
11 |
|
12 | //Pinbelegung für das LCD
|
13 | #define LCD_PORT PORTD
|
14 | #define LCD_DDR DDRD
|
15 | #define LCD_RS 4
|
16 | #define LCD_EN 5
|
17 |
|
18 |
|
19 | //Sendet ein Datenbyte an das LCD
|
20 |
|
21 | void lcd_data(unsigned char temp1){
|
22 |
|
23 | unsigned char temp2 = temp1;
|
24 |
|
25 | LCD_PORT |= (1<<LCD_RS); //RS auf 1 setzen Operator |= sagt: Das Ergebnis des Ausdruckes auf der
|
26 | // rechten Seite nach links schieben
|
27 | // |= ist ein Zuweisungsoperator!
|
28 | temp1 = temp1 >> 4;
|
29 | temp1 = temp1 & 0x0F; // &= AND
|
30 | LCD_PORT &= 0XF0;
|
31 | LCD_PORT |= temp1;
|
32 | lcd_enable();
|
33 |
|
34 | temp2 = temp2 & 0x0F;
|
35 | LCD_PORT &= 0xF0;
|
36 | LCD_PORT |= temp2;
|
37 | lcd_enable();
|
38 |
|
39 | _delay_ms(42);
|
40 | }
|
41 |
|
42 | //sendet einen Befehl an das LCD
|
43 |
|
44 | void lcd_command(unsigned char temp1){
|
45 |
|
46 | unsigned char temp2 = temp1;
|
47 |
|
48 | LCD_PORT &= ~ (1 << LCD_RS); //RS Setzen
|
49 | temp1 = temp1 >> 4; //oberes Nibble holen
|
50 | temp1 = temp1 & 0x0F; //maskieren
|
51 | LCD_PORT &= 0xF0;
|
52 | LCD_PORT |= temp1; //setzen
|
53 | lcd_enable();
|
54 |
|
55 | temp2 = temp2 & 0x0F; //unteres Nibble holen und maskieren
|
56 | LCD_PORT &= 0xF0;
|
57 | LCD_PORT |= temp2; //setzen
|
58 | lcd_enable();
|
59 |
|
60 | _delay_ms(42);
|
61 |
|
62 | }
|
63 |
|
64 | //Den enable Puls erzeugen
|
65 |
|
66 | void lcd_enable(void){
|
67 |
|
68 | LCD_PORT |= (1<<LCD_EN);
|
69 | _delay_ms(10); //kurze Pause machen
|
70 | LCD_PORT &= ~ (1<<LCD_EN);
|
71 |
|
72 | }
|
73 |
|
74 |
|
75 | //Initialisierung
|
76 | //Die Initialisierung muss am Anfang jedes LCD-Porgramms stattfinden
|
77 |
|
78 | void lcd_init(void){
|
79 |
|
80 | LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN); //Port auf Ausgang schalten
|
81 |
|
82 | //muss 3 mal hintereinander gesendet werden zur Initialisierung
|
83 |
|
84 | _delay_ms(15);
|
85 | LCD_PORT &= 0xF0;
|
86 | LCD_PORT |= 0x03;
|
87 | LCD_PORT &= ~ (1<<LCD_RS); //RS auf 0
|
88 | lcd_enable();
|
89 |
|
90 | _delay_ms(20);
|
91 | lcd_enable();
|
92 |
|
93 | _delay_ms(10);
|
94 | lcd_enable();
|
95 |
|
96 | //4-Bit Modus aktivieren
|
97 | LCD_PORT &= 0xF0;
|
98 | LCD_PORT |= 0x02;
|
99 | lcd_enable();
|
100 |
|
101 | //Der Befehlssatz kann im Datenblatt des LCD nachgelesen werden
|
102 | //4-Bit / 2 Zeilen / 5x7
|
103 | lcd_command(0x28);
|
104 |
|
105 | //Display ein / Cursor aus / kein Blinken
|
106 | lcd_command(0x0C);
|
107 |
|
108 | //inkrement / kein scrollen
|
109 | lcd_command(0x06);
|
110 |
|
111 | //alle bisherigen Zeichen vom LCD löschen
|
112 | lcd_clear();
|
113 |
|
114 | }
|
115 |
|
116 | //Sendet den Befehl zur Löschung des Displays
|
117 |
|
118 | void lcd_clear(void){
|
119 |
|
120 | lcd_command(CLEAR_DISPLAY);
|
121 | _delay_ms(20);
|
122 |
|
123 | }
|
124 |
|
125 |
|
126 | //Sendet den Befehl Cursor auf Homeposition
|
127 |
|
128 | void lcd_home(void){
|
129 |
|
130 | lcd_command(CURSOR_HOME);
|
131 | _delay_us(20);
|
132 |
|
133 | }
|
134 |
|
135 |
|
136 | //Setzt den Cursor in Zeile y 1...4 Spalte 0...15
|
137 |
|
138 | void set_cursor(uint8_t x , uint8_t y){
|
139 |
|
140 | switch (y){
|
141 | case 1: lcd_command(0x80 + 0x00 + x); //1.Zeile
|
142 | case 2: lcd_command(0x80 + 0x40 + x); //2.Zeile
|
143 | case 3: lcd_command(0x80 + 0x10 + x); //3.Zeile
|
144 | case 4: lcd_command(0x80 + 0x50 + x); //4.Zeile
|
145 | }
|
146 |
|
147 | }
|
148 |
|
149 |
|
150 | //Schreibt einen String aufs Display
|
151 |
|
152 | void lcd_string(char *data){
|
153 |
|
154 | while(*data){
|
155 |
|
156 | lcd_data(*data);
|
157 | data++;
|
158 |
|
159 | }
|
160 |
|
161 | }
|