Ich möchte mit einem ATtiny45 eine Spannung messen und abhängig davon
eine LED ein- bzw. ausschalten. Programmiert wird er tiny mittels ISP.
Im Anhang ist die Schaltung zu finden.
Das Problem ist nun, dass am ADC-Eingang PB4 immer 0 gelesen wird.
Ich habe die Schaltung auch schon mit und ohne Kondensator an AREF
ausprobiert, und den ADC auch laut Datenblatt dementsprechend
konfiguriert. Jedoch ohne Erfolg.
Bei den ATmega war der ADC noch nie ein Problem, jedoch bereitet mir der
tiny nun etwas Kopfzerbrechen.
Bitte um Hilfe.
Edit: Den Schaltplan habe ich irrtümlich doppelt hochgeladen. Code
richtiggestellt
Hier nun der Code:
Karl M. schrieb:> Du weisst schon, dass an PB4 ADC2 liegt?> Dann solltest Du auch die richtigen ADC-Kanal auswählen.
Und an welcher Stelle hat er den falschen Kanal gewählt?
@TE: Was ist denn cell1 bei dir? Jedenfalls nicht dein Wandlerergebnis
;)
Hallo,
M. K. schrieb:> Karl M. schrieb:>> Du weisst schon, dass an PB4 ADC2 liegt?>> Dann solltest Du auch die richtigen ADC-Kanal auswählen.>> Und an welcher Stelle hat er den falschen Kanal gewählt?>> @TE: Was ist denn cell1 bei dir? Jedenfalls nicht dein Wandlerergebnis> ;)
Hier:
Georg G. schrieb:> Bei init setzt du ref2, bei read löscht du es wieder.> So gewollt?> ref0 ist implizit 0?
1
voidinit_adc(void){
2
uint16_tresult;
3
4
ADMUX=(1<<REFS2)|(1<<REFS1);//internal 2.56V Voltage Reference without external bypass capacitor, disconnected from PB0 (AREF)
5
6
ADCSRA=(1<<ADEN)|(1<<ADPS1)|(1<<ADPS0);
7
DIDR0=(1<<ADC1D)|(1<<ADC2D)|(1<<ADC3D);
8
9
ADCSRA|=(1<<ADSC);
10
while(ADCSRA&(1<<ADSC));// add
11
result=ADCW;
12
}
1
uint16_tadc_read(uint8_tchannel){
2
// add das 0x1F ist eine Maske, um die Bits in MUX[3:0] zu löschen. Ok!
3
ADMUX=(ADMUX&~(0x1F))|(channel&0x1F);
4
ADCSRA|=(1<<ADSC);
5
while(ADCSRA&(1<<ADSC));
6
returnADCW;
7
}
> "5" für Kanalwahl ist "Differenz zwischen ADC2 und ADC2, 20-fach> verstärkt. Macht imho wenig Sinn.
5 ist die Anzahl der Werte über die der Mittelwert gebildet wird.
Roland K. schrieb:> cell1 soll natürlich adc sein.> PB4 als Kanal sollte doch passen?
Dann mach erstmal deinen Code sauber, sprich: Mach ein ordentliches
Beispiel, dass den Fehler zeigt. Meist kommt man bei dieser Arbeit dann
ganz alleine auf den Fehler.
Aktuell passen da einige Dinge nicht. Das mit dem cell1 hab ich ja
angesprochen, das "Problem" mit den Referenzquellen Georg.
EDITH
Roland K. schrieb:> OK, habe den Fehler:> PB4 hat den Wert 4 im Headerfile.> Beim ADC muss ich aber den Wert 2 verwenden.> Dachte PB4 hat den Wert 2.
Ach, da wurd ja PB4 übergeben in der ADC-Routine, das war mir gar nicht
aufgefallen. Ist natürlich Quatsch, da muss das ADC2 rein, das Karl
angesprochen hatte ;)
Roland K. schrieb:> ADMUX &= 0b11111100;> ADMUX |= channel;
Du bist echt ein Held, aus soetwas schönem wie
// add 0x0F ist eine Maske, um die Bits in MUX[3:0] zu löschen.
ADMUX = (ADMUX & ~(0x0F)) | (channel & 0x0F);
kann nur durch Überheblichkeit deine Variante werden. Du kannst den
Compiler nicht überlisten, nur die Lesbarkeit deines Codes verringern.
Zudem hast du einen Fehler eingebracht. In der originalen Schreibweise
wird das höherwertige Nibble von channel maskiert. In deiner Variante
brettert es volle Acht in ADMUX, auch noch als OR, du kannst mithin nur
Bits hinzufügen, keine Löschen. Sei dir versichert: das kannst du nicht
wollen.
Boris hat recht. Der avr-gcc ist richtig richtig gut inzwischen. Da muss
man schon was richtig Komplexes haben und richtig Kniffe kennen, um
etwas besser als der gcc zu sein. Und eins kann ich euch sagen: viele
Chancen gibt euch der gcc nicht besser zu sein. Die kann man an einer
Hand abzählen.
Eine eigene Frage?
Dieser Thread ist über 8 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.