Internal Voltage Reference: ATtiny24/44/84 features an internal bandgap reference. This reference is used for Brown-out Detection, and it can be used as an input to the Analog Comparator or the ADC. The bandgap voltage varies with supply voltage and temperature. Wie genau ist die Bandgap über Temperatur & Zeit? Atmel macht dazu keine weiteren Angaben im Datenblatt. Besser gleich eine externe Referenz nehmen?
Das dürfte alles stark von deinen Anforderungen abhängen. Insgesamt ist eine Bandgap-Referenz schon mal eine relativ stabile Spannungsquelle, wenn man sie mit Z-Dioden-basierten Lösungen vergleicht. Das größere Problem für die meisten praktischen Anwendungsfälle dürfte weniger die Temperaturdrift sein sondern mehr die Tatsache, dass Atmel nur die Eckwerte minimal 1,0 V und maximal 1,2 V spezifiziert, sodass man für Absolutwertmessungen irgendwie im EEPROM einen Kalibrierwert hinterlegen müsste. Auch wenn die benutzte Bandgap-Referenz nicht identisch ist, im Datenblatt des ATmega128RFA1 gibt's typische Werte für die Referenz sowohl bezüglich des Temperaturgangs als auch der Spannungs- abhängigkeit.
Danke für deinen Post. Denke ,dass mit nicht anderes übrig bleibt, als ein paar Messungen zu machen, um die Qualität der Bandgap des ATTiny24 "abzuschätzen". Die 1,6 V Referenz des ATmega128RFA1 sieht "ermutigend" aus.
Wenn du mir verrätst, was du gemessen haben willst, ich habe auch noch ATtiny44 oder 84 da liegen. Deren Bandgap-Referenz sollte ja identisch zum 24 sein. Dann hätte man zumindest noch ein paar Parameterstreuungen über verschiedene Scheiben-Lose als Vergleich. Messungen bei 0 °C sind ja derzeit kein großes Problem. ;-)
Die "Qualität" der Bandgap bestimmen. Messen werde ich die Abweichung bei: Spannung 1,8 - 3,4 V Temperatur 10 - 35 °C Jörg Wunsch schrieb: > Messungen bei 0 °C sind ja derzeit kein großes Problem. ;-) Hier ist Liegestuhlwetter (+5 °C) :)
Drobel schrieb: >> Messungen bei 0 °C sind ja derzeit kein großes Problem. ;-) > > Hier ist Liegestuhlwetter (+5 °C) :) Naja, nachts wird es sicher wieder kälter werden. Wenn man ein Flachbandkabel zum Rausführen des Messergebnisses benutzt, kann man ja auch im Tiefkühlfach messen. ;-) Letztlich genügt es vermutlich, neben +20 °C noch bei Kälte und erhöhter Temperatur (Umluft-Backofen auf 50 °C gestellt) zu messen, da sich die Zwischenwerte brauchbar interpolieren lassen. Die Spannungsabhängigkeit würde ich wohl der Einfachheit halber nur bei +20 °C messen.
Ach so, damit wir auch das gleiche messen:
1 | #include <avr/io.h> |
2 | |
3 | int
|
4 | main(void) |
5 | {
|
6 | ADMUX = 0xc0; |
7 | ADCSRA = (1 << ADEN); |
8 | for (;;) {} |
9 | }
|
Danach sollte sich an PA0 die interne Referenzspannung messen lassen. (Der Pin muss natürlich unbelastet sein.) Hab's aber noch nicht testen können jetzt.
Sollte laut Datenblatt [1] funktionieren, obwohl 0xC0 beim ATTiny24 als "Reserved" gekennzeichnet ist. [1] AREF: External Analog Reference for ADC. Pullup and output driver are disabled on PA0 when the pin is used as an external reference or Internal Voltage Reference with external capacitor at the AREF pin by setting (one) the bit REFS0 in the ADC Multiplexer Selection Register (ADMUX).
Ja, so habe ich das auch rausgelesen. Probieren wir's mal damit.
Ab 2,5 V wird's putzig. BODLEVEL 111 CKSEL 0010 SUT 10 CKDIV JA VCC [V] AREF [mV] 1,8 1103 1,9 1103 2,0 1103 2,1 1103 2,2 1102 2,3 1102 2,4 1101 2,5 1095 2,6 1089 2,7 1076 2,8 938 2,9 504 3,0 265 3,1 138 3,2 71 3,3 38 3,4 20 3,5 11 3,6 7
Hier anders schräg:
1 | U = 1.81 V I = 0.002 A |
2 | +1.09603E+0 |
3 | |
4 | U = 1.91 V I = 0.002 A |
5 | +1.09602E+0 |
6 | |
7 | U = 2.00 V I = 0.003 A |
8 | +1.09550E+0 |
9 | |
10 | U = 2.10 V I = 0.003 A |
11 | +1.09511E+0 |
12 | |
13 | U = 2.20 V I = 0.003 A |
14 | +1.09471E+0 |
15 | |
16 | U = 2.30 V I = 0.004 A |
17 | +1.09416E+0 |
18 | |
19 | U = 2.41 V I = 0.004 A |
20 | +1.09276E+0 |
21 | |
22 | U = 2.51 V I = 0.004 A |
23 | +1.08347E+0 |
24 | |
25 | U = 2.61 V I = 0.004 A |
26 | +1.01387E+0 |
27 | |
28 | U = 2.71 V I = 0.004 A |
29 | +0.89148E+0 |
30 | |
31 | U = 2.80 V I = 0.004 A |
32 | +0.78616E+0 |
33 | |
34 | U = 2.90 V I = 0.004 A |
35 | +0.71030E+0 |
36 | |
37 | U = 3.00 V I = 0.004 A |
38 | +0.66875E+0 |
39 | |
40 | U = 3.10 V I = 0.004 A |
41 | +0.65021E+0 |
42 | |
43 | U = 3.20 V I = 0.004 A |
44 | +0.64299E+0 |
45 | |
46 | U = 3.31 V I = 0.004 A |
47 | +0.64081E+0 |
48 | |
49 | U = 3.41 V I = 0.005 A |
50 | +0.64045E+0 |
51 | |
52 | U = 3.51 V I = 0.005 A |
53 | +0.64096E+0 |
54 | |
55 | U = 3.60 V I = 0.005 A |
56 | +0.64212E+0 |
57 | |
58 | U = 3.70 V I = 0.005 A |
59 | +0.64534E+0 |
60 | |
61 | U = 3.80 V I = 0.005 A |
62 | +0.65331E+0 |
63 | |
64 | U = 3.90 V I = 0.005 A |
65 | +0.65494E+0 |
66 | |
67 | U = 4.00 V I = 0.005 A |
68 | +0.66891E+0 |
69 | |
70 | U = 4.11 V I = 0.006 A |
71 | +0.67953E+0 |
72 | |
73 | U = 4.21 V I = 0.006 A |
74 | +0.69940E+0 |
75 | |
76 | U = 4.31 V I = 0.006 A |
77 | +0.70838E+0 |
78 | |
79 | U = 4.41 V I = 0.006 A |
80 | +0.72988E+0 |
81 | |
82 | U = 4.50 V I = 0.006 A |
83 | +0.74887E+0 |
84 | |
85 | U = 4.60 V I = 0.007 A |
86 | +0.76403E+0 |
87 | |
88 | U = 4.70 V I = 0.007 A |
89 | +0.78987E+0 |
90 | |
91 | U = 4.80 V I = 0.007 A |
92 | +0.80483E+0 |
93 | |
94 | U = 4.91 V I = 0.007 A |
95 | +0.82793E+0 |
96 | |
97 | U = 5.01 V I = 0.008 A |
98 | +0.84366E+0 |
Dabei ist die obere Zeile jeweils der am Netzteil gemessene Wert von Spannung und Strom (wobei da noch ein AT86RF212 mit drauf ist, hüstel, der mit 5 V ein wenig überfahren wird), darunter dann der gemessene Spannungswert an PA0. Pause zwischen den Messungen war 0,1 s. Deckt sich zumindest dahingehend mit deinen Werten, dass bis ca. Vcc = 2,5 V offenbar tatsächlich Vbg ausgegeben wird, danach dann "irgendwas". Nun, da müssen wir wohl doch den ADC selbst bemühen und Vbg gegen Vcc messen lassen. Heute nicht mehr …
Jörg Wunsch schrieb: > Nun, da müssen wir wohl doch den ADC selbst bemühen und Vbg gegen Vcc > messen lassen. OK, hier dann also. Erstmal die Firmware:
1 | #include <avr/io.h> |
2 | #include <avr/interrupt.h> |
3 | |
4 | #define F_CPU 8000000ul
|
5 | #include <util/delay.h> |
6 | |
7 | volatile uint16_t adcval; |
8 | |
9 | static void |
10 | send_data(uint16_t data) |
11 | {
|
12 | uint8_t i; |
13 | uint16_t mask; |
14 | |
15 | for (i = 0, mask = 0x200; |
16 | i < 10; |
17 | i++, mask >>= 1) |
18 | {
|
19 | PORTA |= _BV(0); |
20 | if (data & mask) |
21 | {
|
22 | _delay_us(10); |
23 | PORTA &= ~_BV(0); |
24 | }
|
25 | else
|
26 | {
|
27 | _delay_us(1); |
28 | PORTA &= ~_BV(0); |
29 | _delay_us(9); |
30 | }
|
31 | }
|
32 | }
|
33 | |
34 | |
35 | ISR(ADC_vect) |
36 | {
|
37 | adcval = ADC; |
38 | }
|
39 | |
40 | EMPTY_INTERRUPT(TIM1_COMPB_vect); |
41 | |
42 | |
43 | int
|
44 | main(void) |
45 | {
|
46 | DDRA = _BV(0); /* PA0 as output */ |
47 | |
48 | /* Vcc reference, Vbg source */
|
49 | ADMUX = 0b100001; |
50 | /* divisor 64 => 125 kHz, auto-trigger by TC1 compare match B */
|
51 | ADCSRB = _BV(ADTS2) | _BV(ADTS0); |
52 | ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIE) | |
53 | _BV(ADPS2) | _BV(ADPS1); |
54 | |
55 | /* prescaler 1024 => 7812.5 Hz, CTC/OCR1A, 2 Hz */
|
56 | TCCR1B = _BV(WGM12) | _BV(CS12) | _BV(CS10); |
57 | OCR1A = (F_CPU / 1024 / 2) - 1; |
58 | OCR1B = 0; |
59 | TIMSK1 = _BV(OCIE1B); |
60 | sei(); |
61 | |
62 | for (;;) |
63 | {
|
64 | if (adcval != 0) |
65 | {
|
66 | send_data(adcval); |
67 | adcval = 0; |
68 | }
|
69 | }
|
70 | }
|
Der ADC misst, getriggert durch Timer 1 ca. aller 500 ms, die interne Bandgap gegen Vcc als Referenz. Der Wert wird an PA0 herausgetaktet (0-bit ca. 1 µs lang, 1-bit ca. 9 µs lang high), da ich die USI-Pins in dieser Schaltung bereits anderweitig belegt hatte und ohnehin keinen RS-232-Pegelwandler zur Hand habe, der von 1,8 bis 5 V Betriebsspannung geht. Die seriellen Daten habe ich mit dem LA aufgezeichnet und dann ausgewertet. Hier die Daten, links Vcc, rechts der ADC-Messwert:
1 | 1.81 626 |
2 | 1.91 593 |
3 | 2.00 566 |
4 | 2.10 539 |
5 | 2.20 514 |
6 | 2.30 491 |
7 | 2.40 470 |
8 | 2.51 450 |
9 | 2.61 433 |
10 | 2.71 416 |
11 | 2.80 403 |
12 | 2.90 388 |
13 | 3.00 375 |
14 | 3.10 363 |
15 | 3.20 351 |
16 | 3.31 340 |
17 | 3.41 330 |
18 | 3.51 320 |
19 | 3.60 312 |
20 | 3.70 303 |
21 | 3.80 295 |
22 | 3.90 287 |
23 | 4.00 279 |
24 | 4.10 272 |
25 | 4.21 265 |
26 | 4.31 259 |
27 | 4.41 253 |
28 | 4.50 248 |
29 | 4.60 242 |
30 | 4.70 236 |
31 | 4.80 231 |
32 | 4.90 226 |
33 | 5.01 221 |
Oben noch eine gnuplot-Darstellung des Ergebnisses. Für den Temperaturgang könnte man ja wieder die Ausgabe von Vbg an PA0 benutzen, solange man mit Vcc im Bereich von etwa 2 V bleibt.
Hier die von mir ermittelten Werte. Die Spalte Bandgap ist berechnet und kaufmännisch gerundet. Die max. Abweichung der Bandgap im Bereich von 1,8 - 3,6 V liegt bei rund 1,25 Prozent. VCC ADC Bandgap [V] [mV] 1,8 0274 1105 1,9 0253 1105 2,0 0235 1105 2,1 021A 1104 2,2 0201 1103 2,3 01EB 1104 2,4 01D5 1100 2,5 01C3 1102 2,6 01B1 1104 2,7 01A1 1105 2,8 0191 1098 2,9 0183 1097 3,0 0176 1097 3,1 016A 1097 3,2 015E 1095 3,3 0153 1094 3,4 0149 1093 3,5 0140 1095 3,6 0136 1091
Drobel schrieb: > Das Diagramm der Daten (Kurve geglättet). Bis auf einige 10 mV statischer Differenz sieht das ziemlich so aus wie bei mir auch (nur dass ich bis 5 V weitergemessen habe).
Jörg Wunsch schrieb: > Bis auf einige 10 mV statischer Differenz sieht das ziemlich so aus > wie bei mir auch (nur dass ich bis 5 V weitergemessen habe). Sieht schon recht gut aus. Die Genauigkeit lässt sich zudem per Programm noch verbessern. Hier ein paar Werte in Abhängigkeit von der Temperatur: VCC 2.0 V Bandgap [mV] Temperatur [°C] 1103 23,3 (DS18B20) 1102 20,3 (DS18B20) 1102 11,0 (SHT15)
Drobel schrieb: > 1103 23,3 (DS18B20) > 1102 20,3 (DS18B20) > 1102 11,0 (SHT15) Naja, da muss man wohl den Temperaturbereich vergrößern. ;-) Das ist ja so noch gar keine Aussage.
Jörg Wunsch schrieb: > Naja, da muss man wohl den Temperaturbereich vergrößern. ;-) Das ist > ja so noch gar keine Aussage. Ich habe hier und da etwas über Bandgaps quergelesen. Es sieht so aus, dass die Abhängigkeit von der Temperatur nicht so groß ist. Die Messreihe werde ich noch auf 0 bis 60 °C erweitern.
Hier der Rest meiner Messungen. 60 °C wurden nicht erreicht, da meine Kiste plus Glühlampe nicht mehr erlaubte. Für 0 °C war es draußen einfach nicht kalt genug. Die Daten sind aber auch so aussagekräftig. Vorsichtiges Fazit aus den Messungen: die Bandgap ist brauchbar. VCC 2.0 V Bandgap [mV] Temperatur [°C] 1101 48.0 (DS18B20) 1101 47.8 (DS18B20) 1101 47.3 (DS18B20) 1101 47.0 (DS18B20) 1101 46.7 (DS18B20) 1101 46.4 (DS18B20) 1101 45.8 (DS18B20) 1101 45.4 (DS18B20) 1101 45.0 (DS18B20) 1101 44.6 (DS18B20) 1101 44.3 (DS18B20) 1101 43.9 (DS18B20) 1102 43.5 (DS18B20) 1102 43.1 (DS18B20) 1102 42.8 (DS18B20) 1102 42.4 (DS18B20) 1102 42.0 (DS18B20) 1102 41.5 (DS18B20) 1102 41.0 (DS18B20) 1102 38.9 (DS18B20) 1102 38.9 (DS18B20) 1102 38.2 (DS18B20) 1102 37.5 (DS18B20) 1102 36.8 (DS18B20) 1102 36.1 (DS18B20) 1102 35.4 (DS18B20) 1102 34.7 (DS18B20) 1102 34.0 (DS18B20) 1102 33.2 (DS18B20) 1102 32.5 (DS18B20) 1102 31.8 (DS18B20) 1102 29.8 (DS18B20) 1102 28.5 (DS18B20) 1103 27.0 (DS18B20) 1103 25.5 (DS18B20) 1103 24.7 (DS18B20) 1103 23,3 (DS18B20) 1102 20,3 (DS18B20) 1102 11,0 (SHT) 1102 6,7 (SHT) 1102 2,1 (SHT)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.