1 | #define F_CPU 2000000UL
|
2 | #include <avr/io.h>
|
3 | #include <util/delay.h>
|
4 | #include <avr/interrupt.h>
|
5 |
|
6 | // Makro zum setzen bestimmter Bits
|
7 | #define sbi(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
|
8 |
|
9 | int i = 0;
|
10 |
|
11 | uint8_t ADC_read(uint8_t kanalNr){
|
12 |
|
13 | //Messung starten
|
14 | sbi(ADCSRA,ADSC);
|
15 | //Warten bis Messung vorbei ist
|
16 | while(bit_is_set(ADCSRA,ADSC));
|
17 | return (ADCH); //die 8 höchstwertigen bits zurückgeben
|
18 | }
|
19 |
|
20 | // führt 100 Messungen durch und ermittelt den höchstwert.
|
21 | // Scheteilpunkt Messung des sinus förmigen Verlaufes
|
22 | uint8_t getADCmax(uint8_t kanalNr){
|
23 |
|
24 | //Kanal des Multiplexers wählen:
|
25 | //ADLAR um die höchsten 8 Bits auf ADCH zu schreiben, REFS0 für interne Refrenz von 5 V
|
26 |
|
27 | if(kanalNr == 1){
|
28 | //ADMUX |= (1 << MUX1) | (1 << REFS0) | (1 << ADLAR);
|
29 | ADMUX = 0x62;
|
30 | }
|
31 | //ADC03 für die strom
|
32 | if(kanalNr == 2){
|
33 | //ADMUX |= (1 << MUX1) | (1 << MUX0) | (1 << REFS0) | (1 << ADLAR);
|
34 | ADMUX = 0x63;
|
35 | }
|
36 | //ADC04 für die phase
|
37 | if(kanalNr == 3){
|
38 | //ADMUX |= (1 << MUX2) | (1 << REFS0) | (1 << ADLAR);
|
39 | ADMUX = 0x64;
|
40 | }
|
41 |
|
42 | //erste Messung nach wechseln des Kanals verwerfen
|
43 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
44 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten
|
45 | }
|
46 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
47 | Wandlung nicht übernommen. */
|
48 | (void) ADCW;
|
49 |
|
50 | //Peak speichern
|
51 | uint8_t peak=0;
|
52 | uint8_t tmpPeak;
|
53 | for(int i=0; i<190; i++){
|
54 | tmpPeak = ADC_read(kanalNr);
|
55 | if(tmpPeak > peak ){
|
56 | peak = tmpPeak;
|
57 | }
|
58 | }
|
59 | //peak zurückgeben
|
60 | return peak;
|
61 | }
|
62 |
|
63 | int main(void)
|
64 | {
|
65 | // Port C als ausgang & JTAG-Schnitstelle in Fuses deaktiviert um PortC ohne Probleme benutzen zu können
|
66 | DDRC = 0xFF;
|
67 | DDRB = 0xFF;
|
68 | DDRA = 0x00;
|
69 |
|
70 | // ADC initialisieren
|
71 | //ADSCRA Enablen und Teilungsfaktor von 16 ( da 2MHz/200kHz = 10)
|
72 | sbi(ADCSRA,ADEN); //ADC aktivieren
|
73 | sbi(ADCSRA,ADPS2);
|
74 |
|
75 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
76 | while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung warten
|
77 | }
|
78 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
79 | Wandlung nicht übernommen. */
|
80 | (void) ADCW;
|
81 |
|
82 | while(1)
|
83 | {
|
84 |
|
85 | //Phase ausgeben
|
86 | PORTC = 0x00;
|
87 | PORTC = getADCmax(3);
|
88 | _delay_ms(7);
|
89 | PORTB = 0x08;
|
90 | for(i = 0; i < 200; i++) _delay_ms(1);
|
91 |
|
92 | //Strom ausgeben
|
93 | PORTC = 0x00;
|
94 | PORTC = getADCmax(2);
|
95 | _delay_ms(7);
|
96 | PORTB = 0x04;
|
97 | for(i = 0; i < 200; i++) _delay_ms(1);
|
98 |
|
99 | //Spannung Ausgeben
|
100 | PORTC = 0x00;
|
101 | PORTC = getADCmax(1);
|
102 | _delay_ms(7);
|
103 | PORTB = 0x00;
|
104 | for(i = 0; i < 200; i++) _delay_ms(1);
|
105 |
|
106 |
|
107 |
|
108 | }
|
109 | }
|