1 | #include <avr/io.h>
|
2 | #define F_CPU 8000000UL
|
3 | #include <util/delay.h>
|
4 | #include <stdlib.h>
|
5 | #include <avr/interrupt.h>
|
6 | #include "lcd-routines.h"
|
7 |
|
8 |
|
9 |
|
10 | // sendet ein Datenbyte an das LCD
|
11 |
|
12 | void lcd_data(unsigned char temp1)
|
13 | {
|
14 | unsigned char temp2 = temp1;
|
15 |
|
16 | LCD_PORT |= (1<<LCD_RS); // RS auf 1 setzen
|
17 |
|
18 | temp1 = temp1 >> 4;
|
19 | temp1 = temp1 & 0x0F;
|
20 | LCD_PORT &= 0xF0;
|
21 | LCD_PORT |= temp1; // setzen
|
22 | lcd_enable();
|
23 |
|
24 | temp2 = temp2 & 0x0F;
|
25 | LCD_PORT &= 0xF0;
|
26 | LCD_PORT |= temp2; // setzen
|
27 | lcd_enable();
|
28 |
|
29 | _delay_us(42);
|
30 | }
|
31 |
|
32 | // sendet einen Befehl an das LCD
|
33 |
|
34 | void lcd_command(unsigned char temp1)
|
35 | {
|
36 | unsigned char temp2 = temp1;
|
37 |
|
38 | LCD_PORT &= ~(1<<LCD_RS); // RS auf 0 setzen
|
39 |
|
40 | temp1 = temp1 >> 4; // oberes Nibble holen
|
41 | temp1 = temp1 & 0x0F; // maskieren
|
42 | LCD_PORT &= 0xF0;
|
43 | LCD_PORT |= temp1; // setzen
|
44 | lcd_enable();
|
45 |
|
46 | temp2 = temp2 & 0x0F; // unteres Nibble holen und maskieren
|
47 | LCD_PORT &= 0xF0;
|
48 | LCD_PORT |= temp2; // setzen
|
49 | lcd_enable();
|
50 |
|
51 | _delay_us(42);
|
52 | }
|
53 |
|
54 | // erzeugt den Enable-Puls
|
55 | void lcd_enable(void)
|
56 | {
|
57 | // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen
|
58 | // http://www.mikrocontroller.net/topic/81974#685882
|
59 | LCD_PORT |= (1<<LCD_EN);
|
60 | _delay_us(1); // kurze Pause
|
61 | // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
|
62 | // http://www.mikrocontroller.net/topic/80900
|
63 | LCD_PORT &= ~(1<<LCD_EN);
|
64 | }
|
65 |
|
66 | // Initialisierung:
|
67 | // Muss ganz am Anfang des Programms aufgerufen werden.
|
68 |
|
69 | void lcd_init(void)
|
70 | {
|
71 | LCD_DDR = LCD_DDR | 0x0F | (1<<LCD_RS) | (1<<LCD_EN); // Port auf Ausgang schalten
|
72 |
|
73 | // muss 3mal hintereinander gesendet werden zur Initialisierung
|
74 |
|
75 | _delay_ms(15);
|
76 | LCD_PORT &= 0xF0;
|
77 | LCD_PORT |= 0x03;
|
78 | LCD_PORT &= ~(1<<LCD_RS); // RS auf 0
|
79 | lcd_enable();
|
80 |
|
81 | _delay_ms(5);
|
82 | lcd_enable();
|
83 |
|
84 | _delay_ms(1);
|
85 | lcd_enable();
|
86 | _delay_ms(1);
|
87 |
|
88 | // 4 Bit Modus aktivieren
|
89 | LCD_PORT &= 0xF0;
|
90 | LCD_PORT |= 0x02;
|
91 | lcd_enable();
|
92 | _delay_ms(1);
|
93 |
|
94 | // 4Bit / 2 Zeilen / 5x7
|
95 | lcd_command(0x28);
|
96 |
|
97 | // Display ein / Cursor aus / kein Blinken
|
98 | lcd_command(0x0C);
|
99 |
|
100 | // inkrement / kein Scrollen
|
101 | lcd_command(0x06);
|
102 |
|
103 | lcd_clear();
|
104 | }
|
105 |
|
106 | // Sendet den Befehl zur Löschung des Displays
|
107 |
|
108 | void lcd_clear(void)
|
109 | {
|
110 | lcd_command(CLEAR_DISPLAY);
|
111 | _delay_ms(5);
|
112 | }
|
113 |
|
114 | // Sendet den Befehl: Cursor Home
|
115 |
|
116 | void lcd_home(void)
|
117 | {
|
118 | lcd_command(CURSOR_HOME);
|
119 | _delay_ms(5);
|
120 | }
|
121 |
|
122 | // setzt den Cursor in Zeile y (1..4) Spalte x (0..15)
|
123 |
|
124 | void set_cursor(uint8_t x, uint8_t y)
|
125 | {
|
126 | uint8_t tmp;
|
127 |
|
128 | switch (y) {
|
129 | case 1: tmp=0x80+0x00+x; break; // 1. Zeile
|
130 | case 2: tmp=0x80+0x40+x; break; // 2. Zeile
|
131 | case 3: tmp=0x80+0x10+x; break; // 3. Zeile
|
132 | case 4: tmp=0x80+0x50+x; break; // 4. Zeile
|
133 | default: return; // für den Fall einer falschen Zeile
|
134 | }
|
135 | lcd_command(tmp);
|
136 | }
|
137 |
|
138 | // Schreibt einen String auf das LCD
|
139 |
|
140 | void lcd_string(char *data)
|
141 | {
|
142 | while(*data) {
|
143 | lcd_data(*data);
|
144 | data++;
|
145 | }
|
146 | }
|
147 |
|
148 | //*****************************************************
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 | volatile unsigned char a;
|
155 | volatile unsigned char az;
|
156 | volatile unsigned char Empfang1 = 0, Empfang2 = 0;
|
157 | volatile unsigned char x;
|
158 | //volatile unsigned char i[]= "AZ180.6 EL39.5";
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 | //UART-Interruptroutine
|
166 |
|
167 | ISR(USART_RXC_vect){
|
168 |
|
169 | //für LEDs
|
170 | a = UDR;
|
171 | Empfang1 = 1;
|
172 |
|
173 | //für LCD
|
174 | az = UDR;
|
175 | Empfang2 = 1;
|
176 |
|
177 | }
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 | int main(void){
|
184 |
|
185 | //global Interrupt Enable
|
186 | SREG |= (1<<7); //sei();
|
187 | //Schnittstelle parametrisieren
|
188 | UBRRH = 0; // Baudrate auf 9600
|
189 | UBRRL = 51;
|
190 | //Empfang, Senden, Empfangsinterrupt
|
191 | UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<RXCIE);
|
192 | //Defaultwerte zementieren, 8N1
|
193 | UCSRC |= (1<<URSEL) | (3<<UCSZ0);
|
194 |
|
195 | DDRC = 0xFF;
|
196 | //PORTC = 0xff; // wenn auskommentiert leuchen die LEDs nicht am Beginn
|
197 |
|
198 |
|
199 |
|
200 | lcd_init();
|
201 |
|
202 | lcd_data('T');
|
203 | lcd_data('e');
|
204 | lcd_data('s');
|
205 | lcd_data('t');
|
206 |
|
207 | set_cursor(0,2);
|
208 |
|
209 |
|
210 |
|
211 | while(1){
|
212 |
|
213 | if(Empfang1){
|
214 | PORTC = ~a;
|
215 | Empfang1 = 0;
|
216 | }
|
217 |
|
218 | if(Empfang2){
|
219 | lcd_string(az);
|
220 | Empfang2 = 0;
|
221 | }
|
222 |
|
223 |
|
224 | }
|
225 | }
|