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