1 | #include <avr\io.h> //AVR Register und Konstantendefinitionen
|
2 | #include <avr\interrupt.h> //AVR Interrupt Vektoren
|
3 | #include <stdlib.h>
|
4 | #include <inttypes.h>
|
5 | #include <util/delay.h>
|
6 | #include "main.h"
|
7 | #include "lcd_drv.h"
|
8 |
|
9 |
|
10 |
|
11 | // ************************************************************************************************
|
12 | // Initialisierung
|
13 | // ************************************************************************************************
|
14 | void initial(void)
|
15 | {
|
16 | // **** Einrichten von Ein- und Ausgängen *******************************************************
|
17 | DDRA = 0b11111000; // PortA
|
18 | DDRB = 0b11111111; // PortB
|
19 |
|
20 | lcd_init();
|
21 |
|
22 | sei() ;
|
23 |
|
24 | }
|
25 |
|
26 | void ADC_Init(void) {
|
27 |
|
28 | uint16_t result;
|
29 |
|
30 | ADMUX = 0b00000000; // AVCC als Referenzspannung nutzen
|
31 | ADCSRA = 0b10000111; // Frequenzvorteiler 8 ==> 1.000.000/8 = 125.000Hz
|
32 |
|
33 |
|
34 | /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
|
35 | also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
|
36 |
|
37 | ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
|
38 | while (ADCSRA & (1<<ADSC) ); // auf Abschluss der Konvertierung warten
|
39 | /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
|
40 | Wandlung nicht übernommen. */
|
41 | result = ADCW;
|
42 | }
|
43 | // ************************************************************************************************
|
44 |
|
45 |
|
46 | // *ADC Einzelmessung ******************************************************************************
|
47 | uint16_t ADC_Read( uint8_t channel )
|
48 | {
|
49 | // Kanal waehlen, ohne andere Bits zu beeinflußen
|
50 | ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
|
51 | ADCSRA |= (1<<ADSC); // eine Wandlung "single conversion"
|
52 | while (ADCSRA & (1<<ADSC) ) // auf Abschluss der Konvertierung warten
|
53 | ;
|
54 | return ADCW; // ADC auslesen und zurückgeben
|
55 | }
|
56 |
|
57 |
|
58 | /* ADC Mehrfachmessung mit Mittelwertbbildung */
|
59 | /* beachte: Wertebereich der Summenvariablen */
|
60 | uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )
|
61 | {
|
62 | uint32_t sum = 0;
|
63 |
|
64 | for (uint8_t i = 0; i < nsamples; ++i ) {
|
65 | sum += ADC_Read( channel );
|
66 | }
|
67 |
|
68 | return (uint16_t)( sum / nsamples );
|
69 | }
|
70 |
|
71 | // Hauptprogramm
|
72 | // **********************************************************************************
|
73 |
|
74 | int main(void)
|
75 | {
|
76 |
|
77 |
|
78 | //int variable = 0;
|
79 | int amp_offset = 514;
|
80 | int amp_adc = 0;
|
81 | long volt_adc = 0;
|
82 | long amp_diff = 0;
|
83 | long amp_u = 0;
|
84 | long volt_u = 0;
|
85 | long amp_real = 0;
|
86 | long volt_real = 0;
|
87 | int Vref = 5029;
|
88 | long power = 0;
|
89 | // ******** Initialisierung ********************************************************
|
90 |
|
91 | initial(); // Initialisierung Ports etc.
|
92 | ADC_Init();
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | // ******** Hauptschleife ***********************************************************
|
98 |
|
99 | while(1)
|
100 | {
|
101 |
|
102 | char s[sizeof("4294967295")]; //Buffer für Ausgabe über LCD
|
103 | char t[sizeof("4294967295")]; //Buffer für Ausgabe über LCD
|
104 | char u[sizeof("4294967295")]; //Buffer für Ausgabe über LCD
|
105 | char v[sizeof("4294967295")]; //Buffer für Ausgabe über LCD
|
106 |
|
107 |
|
108 | amp_adc = ADC_Read_Avg(0,4);
|
109 |
|
110 | amp_diff = amp_adc - amp_offset;
|
111 |
|
112 | amp_u = amp_diff * Vref/1023;
|
113 |
|
114 | amp_real = amp_u * 1515;
|
115 |
|
116 | amp_real = amp_real/100;
|
117 |
|
118 | if (amp_real < 0)
|
119 | {
|
120 | amp_real = 0;
|
121 | }
|
122 |
|
123 |
|
124 |
|
125 | volt_adc = ADC_Read_Avg(1,4);
|
126 |
|
127 | volt_u = volt_adc * Vref/1023;
|
128 |
|
129 | volt_real = volt_u * 730;
|
130 |
|
131 | volt_real = volt_real/100;
|
132 |
|
133 |
|
134 | power = volt_real * amp_real;
|
135 |
|
136 |
|
137 | power = power/1000;
|
138 |
|
139 |
|
140 | if (volt_real > 10000)
|
141 | {
|
142 | PORTB = 0b00000010;
|
143 | }
|
144 | else if (volt_real < 9000)
|
145 | {
|
146 | PORTB = 0b00000000;
|
147 | }
|
148 |
|
149 |
|
150 | lcd_init();
|
151 | lcd_xy( 0, 0 );
|
152 | lcd_puts( "mA:" );
|
153 |
|
154 | ultoa( amp_real, s, 10 );
|
155 | lcd_xy( 3, 0 );
|
156 | lcd_puts( s );
|
157 |
|
158 |
|
159 | lcd_xy( 8, 0 );
|
160 | lcd_puts( "mV:" );
|
161 |
|
162 | ultoa( volt_real, t, 10 );
|
163 | lcd_xy( 11, 0 );
|
164 | lcd_puts( t );
|
165 |
|
166 |
|
167 | lcd_xy( 0, 1 );
|
168 | lcd_puts( "mW:" );
|
169 |
|
170 | ultoa( power, u, 10 );
|
171 | lcd_xy( 3, 1 );
|
172 | lcd_puts( u );
|
173 |
|
174 |
|
175 | lcd_xy( 8, 1 );
|
176 | lcd_puts( "ADC:" );
|
177 |
|
178 | ultoa( volt_adc, v, 10 );
|
179 | lcd_xy( 12, 1 );
|
180 | lcd_puts( v );
|
181 |
|
182 |
|
183 | _delay_ms(2000);
|
184 |
|
185 | // ************************************************************************************************
|
186 | } // Ende while(1)Endlosschleife
|
187 | return 0;
|
188 | }// Ende Hauptprogramm
|