1 | #include <avr/io.h>
|
2 | #include <avr/interrupt.h>
|
3 | #define F_CPU 1000000
|
4 | #include <util/delay.h>
|
5 |
|
6 | #define DB4 PD0 //Datenbit 5
|
7 | #define DB5 PD1
|
8 | #define DB6 PD2
|
9 | #define DB7 PD3
|
10 | #define RegSelect PD4
|
11 | #define RW PD5
|
12 | #define Enable PD6
|
13 | #define LCD_Port PORTD
|
14 | #define enableDelay 1000 //µs
|
15 |
|
16 | #define Poti1 PC0
|
17 | #define Backlight PC5
|
18 |
|
19 | //Variablen----------------------------------
|
20 | char AusgabeString[];
|
21 | uint8_t Interrupt0Zaehler =0 ;
|
22 | uint8_t sekunde = 0;
|
23 |
|
24 | uint16_t alterAdcWert =0;
|
25 | uint16_t aktuellerAdcWert=0;
|
26 |
|
27 | //Prototypen der Funktionen------------------
|
28 | void adcInit(void);
|
29 | void lcdInit(void);
|
30 | void enable(void);
|
31 | void lcdClear(void);
|
32 | void schreibeZeichen(unsigned char temp1);
|
33 | void lcdWriteString(char *data);
|
34 | void lcdWriteNumber(uint16_t z);
|
35 | uint16_t ADC_auslesen(uint8_t adcSource);
|
36 |
|
37 | //ISR-------------------------------------------
|
38 | ISR (TIMER0_COMPA_vect){
|
39 | Interrupt0Zaehler++;
|
40 | }
|
41 |
|
42 |
|
43 |
|
44 | int main (void) {
|
45 | DDRB = 0b00; // Taster
|
46 | DDRC = 0b00100000; // ADC und Backlight
|
47 | PORTC = 0x00;
|
48 | DDRD = 0xff; // LCD (Ausgang)
|
49 |
|
50 |
|
51 | //Timer für Sekunden
|
52 | TCCR0A |= (1<<WGM01); //löscht timer wert bei interrupt
|
53 | TCCR0B |= ((1<<CS01)|(1<<CS00)); // Prescaler 64
|
54 | OCR0A = 0x7D; //8 Bit Register mit Wert, bei dem der Compare Match etzeugt wird
|
55 | TIMSK0 |= (1<<OCIE0A); //Timer Interrupt Mask Register, Enable Compare Match Interrupt
|
56 | TIFR0 |= (1<<OCF1A); //Flag (durch setzen von 1!) löschen, damit nicht sofort in ISR(comp_vect) gesprungen wird
|
57 |
|
58 |
|
59 |
|
60 | //------------------
|
61 | adcInit();
|
62 | lcdInit();
|
63 | sei();
|
64 |
|
65 | while(1){
|
66 |
|
67 | aktuellerAdcWert = ADC_auslesen(0)*5;
|
68 |
|
69 | lcdClear();
|
70 | lcdWriteString("Wert: ");
|
71 | lcdWriteNumber(aktuellerAdcWert);
|
72 |
|
73 |
|
74 | if(aktuellerAdcWert != alterAdcWert){
|
75 | alterAdcWert = aktuellerAdcWert;
|
76 | }
|
77 |
|
78 |
|
79 | }//while..
|
80 | }//main
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 | //Funktionen------------------------------------
|
88 | void adcInit(void){
|
89 | //AD Wandler
|
90 | ADMUX = 0x00;
|
91 | ADMUX |= (1<<REFS0); //interne Referenz Vcc
|
92 | ADCSRA |= ((1<<ADEN)|(1<<ADSC)|(1<<ADPS0)|(1<<ADPS2)|(1<<ADPS1));//AD enable, AD Prescaler (ADC sollte zw. 50 und 100 kHz liegen, hier PSC=64)
|
93 | //ERGEBNIS STEHT IN ADCH und ADCL (10Bit)
|
94 |
|
95 | //Dummyreadout
|
96 | while ( ADCSRA & (1<<ADSC) ) {} // auf Abschluss der Konvertierung warten}
|
97 | uint16_t dummyResult = ADCW;
|
98 | }
|
99 |
|
100 |
|
101 | void lcdInit(void){
|
102 | LCD_Port = 0x00;
|
103 | _delay_ms(20); //Boot Zeit
|
104 |
|
105 | LCD_Port |= ((1<<DB4)|(1<<DB5));
|
106 | _delay_ms(5);
|
107 | enable();
|
108 |
|
109 | _delay_ms(5);
|
110 | enable();
|
111 |
|
112 | _delay_ms(5);
|
113 | enable();
|
114 |
|
115 | _delay_ms(5);
|
116 |
|
117 | //--------------------------------------------------------
|
118 | LCD_Port = 0x00;
|
119 | LCD_Port |= (1<<DB5); //4 Bit Ansteuerung
|
120 | _delay_ms(5);
|
121 | enable();
|
122 | //--------------------------------------------------------
|
123 | // LCD_Port |= (1<<DB5); //2-zeilig, 5x8
|
124 | _delay_ms(5);
|
125 | enable();
|
126 | LCD_Port |= (1<<DB7);
|
127 | _delay_ms(5);
|
128 | enable();
|
129 | //--------------------------------------------------------
|
130 |
|
131 |
|
132 |
|
133 | LCD_Port = 0x00;
|
134 | _delay_ms(5);
|
135 | enable();
|
136 | LCD_Port |= ((1<<DB7)|(1<<DB6));//|(1<<DB5)|(1<<DB4));
|
137 | _delay_ms(5);
|
138 | enable();
|
139 | _delay_ms(10);
|
140 |
|
141 | }
|
142 |
|
143 | void enable(void) {
|
144 |
|
145 | LCD_Port |= (1<<Enable);
|
146 | _delay_us(enableDelay);
|
147 | LCD_Port &= ~(1<<Enable);
|
148 | _delay_us(enableDelay);
|
149 | }
|
150 |
|
151 |
|
152 |
|
153 | void lcdClear(void){
|
154 | LCD_Port &=~(1<<RegSelect); //jetzt kommt Steuerbefehl
|
155 | _delay_us(10);
|
156 | LCD_Port = 0x00; //Display löschen
|
157 | enable();
|
158 | LCD_Port |= (1<<DB4);
|
159 | enable();
|
160 |
|
161 | }
|
162 |
|
163 |
|
164 |
|
165 |
|
166 |
|
167 | void schreibeZeichen(unsigned char temp1)
|
168 | {
|
169 | unsigned char temp2 = temp1;
|
170 |
|
171 | LCD_Port |= (1<<RegSelect); // RS auf 1 setzen
|
172 |
|
173 | temp1 = temp1 >> 4; // übergebenes Byte wird um 4 Stellen nach rechts verschoben, links 4 Nullen
|
174 | temp1 = temp1 & 0x0F; // Obere 4 Bit bleiben wie sie sind, untere werden gelöscht
|
175 | LCD_Port &= 0xF0; // Untere 4 Bit werden gesetzt zur Übertragung der ersten 4 Bit
|
176 | LCD_Port |= temp1; // setzen
|
177 | enable();
|
178 | //Das Selbe für die zweiten 4 Bit
|
179 | temp2 = temp2 & 0x0F;
|
180 | LCD_Port &= 0xF0;
|
181 | LCD_Port |= temp2; // setzen
|
182 | enable();
|
183 |
|
184 | _delay_us(5);
|
185 | }
|
186 |
|
187 |
|
188 | // Schreibt einen String auf das LCD
|
189 |
|
190 | void lcdWriteString(char *data){
|
191 | char *data_2;
|
192 | data_2=data;//String merken
|
193 |
|
194 | // Schreibt die ersten 16 zeichen des Strings
|
195 |
|
196 | while(*data){
|
197 | schreibeZeichen(*data);
|
198 | data++;
|
199 | }
|
200 | }
|
201 |
|
202 |
|
203 | void lcdWriteNumber(uint16_t z)
|
204 | {
|
205 | uint16_t i;
|
206 | uint16_t temp;
|
207 | uint16_t Dez;
|
208 | uint8_t k; // Merker ob vorne 0 ist
|
209 | k=0;
|
210 | Dez=100; // Dezimalstellen, z.B. bei 2 Stellen 10 eintragen
|
211 | while (Dez) // Solange Dezimalstelle nicht 0 ist
|
212 | {
|
213 | if(Dez==1) k=1; // Um ein einzige 0 anzeigen können
|
214 | i=z/Dez; // Wert der jeweilige Dezimalstelle bestimmen
|
215 | temp=i*Dez;
|
216 | z=z-temp;
|
217 | if(i||k) // Damit wir vorne keine Nullen stehen haben.
|
218 | {
|
219 | schreibeZeichen((char)i+0x30);
|
220 | k=1; // es gab schon eine Zahl die nicht 0 ist
|
221 | }
|
222 | else // wen 0 ist und vorne keine Zahl war, dann
|
223 | {
|
224 | schreibeZeichen(' '); // Leerzeichen ausgeben
|
225 | }
|
226 | Dez=Dez/10;
|
227 | }
|
228 | }
|
229 |
|
230 | uint16_t ADC_auslesen(uint8_t adcSource){
|
231 |
|
232 | uint16_t adcResult =0;
|
233 | ADMUX = (ADMUX & ~(0x1F)) | (adcSource & 0x1F);
|
234 |
|
235 | for (uint8_t i=0;i<8;i++){
|
236 | ADCSRA |= (1<<ADSC); //Start
|
237 | while ((ADCSRA & (1<<ADSC))==0){}
|
238 |
|
239 | adcResult += ADCW;}
|
240 | return (uint16_t)(adcResult/128);
|
241 |
|
242 |
|
243 | }
|