Hallo!
Ich hab teilweise beim messen mit meinem Programm festegestellt, dass
ich bei Spannungen nahe der Versorgungsspannung (Uref = AVcc) scheibar
meinen Mikrocontroller übertakte, auf jeden Fall arbeitet er dann alle
Befehle deutlich schneller ab. Andersherum: Nehme ich die Spannung
ruckartig weg, handelt er alle Befehle deutlich langsamer ab, ein
Neustart führt wieder zur gewünschten Geschwindigkeit. Wie kann soetwas
denn passieren??
Ich verwende einen ATmega2561 mit 14745600Hz, hier der Ausschnitt aus
dem Programm, falls ich dort irgendetwas vergessen habe/ falsch mache.
Ich erkenne, dass die ADC-wandlung sehr viel schneller geht, was allein
ja nicht gleich der gesamte Takt sein muss.
Verlangsamt sich der Takt nun aber, sehe ich gleichzeitig an einer
Echtzeituhr, die in Main angezeigt wird auch nur noch alle 4-5 Sekunden
eine Veränderung...hm wobei selbst das könnte daran liegen, dass die
AD-Wandlungen einfach so lange dauern, dass in der Zeit nichts anderes
mehr gemacht wird.
Kann auch sein, dass sich nur die AD-Wandler Frequenz ändert...Auf jeden
Fall werden alle Werte immernoch scheinbar "gleichzeitig" aktualisiert
nur seltener.
Also habs gerad nochmal bisschen genauer ausprobiert, es funktioniert
alles normal bis ich über 4,5V anlege (noch unter 1023), dann
aktualisieren sich die Werte joa vermutlich mit maximaler
Geschwindigkeit. Drehe ich die Spannung dann wieder unter 4,4 V
verlangsamt sich sämtliche Aktualisierung auf 4-5s -> ursprünglich
sollen alle 0,25s die Messwerte aktualisiert werden.
14,7MHz klingt nach Baudratenquarz, also nach Quarz, und dass ein
Quarzoszillator spürbar spannungsabhängig wäre, das darf man wohl
getrost ausschliessen. Es sei denn der Quarz wäre im Eimer oder total
falsch betrieben (Schaltung? Layout?).
Apropos Betrieb: Ich hoffe der Oszillator ist korrekt gefused, also als
full swing osc, nicht als Stromsparoszillator für langsamere Quarze. Und
hat seine Kondensatoren dran.
Wenn du dem nicht traust, dann häng einen autark ohne Interrupts
laufenden Hardware-Sekundentimer auf einen OCxy-Ausgang, dort eine LED
dran, und guck zu.
Du bist auch nicht der Erste, der mit dem ADC an einem 5V-AVR Eingänge
Spannungen im Bereich 4,5V misst. Es könnte sich also auch um einen
Schmutzeffekt des Programms handeln, wenn Messungen schneller oder
langsamer laufen.
Manuel schrieb:> Ich erkenne, dass die ADC-wandlung sehr viel schneller geht, was allein> ja nicht gleich der gesamte Takt sein muss.
Hast du vielleicht eine sehr hochohmige Quelle angeschlossen? Da können
sich meines Wissens Wandlungen evtl. verlängern.
> Verlangsamt sich der Takt nun aber, sehe ich gleichzeitig an einer> Echtzeituhr, die in Main angezeigt wird auch nur noch alle 4-5 Sekunden> eine Veränderung... hm wobei selbst das könnte daran liegen, dass die> AD-Wandlungen einfach so lange dauern, dass in der Zeit nichts anderes> mehr gemacht wird.
Ähm, wie machst du denn diese "Echtzeituhr". Ich hoffe doch, über einen
Timer-Interrupt? Alles andere wäre sowieso unbrauchbar. Eine Wandlung
dauert im Verhältnis zum Prozessortakt übrigens sehr lange.
Rolf Magnus schrieb:> Hast du vielleicht eine sehr hochohmige Quelle angeschlossen? Da können> sich meines Wissens Wandlungen evtl. verlängern.
Die Dauer der Wandlung hängt nicht vom Signal ab. Nur die Genauigkeit
vom Ergebnis leidet mit dem Innenwiderstand.
Manuel schrieb:> hier der Ausschnitt aus> dem Programm, falls ich dort irgendetwas vergessen habe/ falsch mache.
Wichtiger währen aber die Teile, mit denen Du feststellst, daß der ADC
den Quarz beeinflussen können soll.
Peter
Also ich hab von diesem Prozessor kein Datenblatt da, aber in dem vom
ATmega8 steht zumindest:
"The ADC is optimized for analog signals with an output impedance of
approximately 10 kΩ or less. If such a source is used, the sampling time
will be negligible. If a source with higher impedance is used, the
sampling time will depend on how long time the source needs to charge
the S/H capacitor, with can vary widely."
Die ADC-Wandelzeit ist fix: 25 Zyklen für die erste Konversion, danach
13|13,5|13..14 ADC-Zyklen (normal|Auto-Trigger|differentiell). Eine
Abhängigkeit vom Eingangssignal gibt es nicht.
Es muss sich also um einen Dreckeffekt an anderer Stelle handeln.
Rolf Magnus zitierte im Beitrag #1825210:
> will be negligible. If a source with higher impedance is used, the> sampling time will depend on how long time the source needs to charge> the S/H capacitor, with can vary widely."
Jo, aber das ist dein Problem, nicht das vom ADC. Woher soll der denn
das wissen? Was die damit sagen wollen ist: Warte nach der Umschaltung
vom Muxer gefälligst lange genug bis sich das Signal am S&H-C
stabilisiert hat. Bei einem Quellwiderstand bis 10K geschieht dies durch
das eingebaute starre Timing automatisch, darüber muss man selber dafür
sorgen.
hm also ich messe bisher einfach direkt am Netzgerät, welches ja schon
sehr hochohmig sein dürfte, da soll ja schließlich nicht wirklich Strom
fließen.
Ich muss allerdings auch zustimmen, dass ich nicht bei allen Programmen
dieses Problem habe, es also durchaus ganz gut an dem Quellcode liegen
kann...
Dass der Quarz nicht korrekt angeschlossen ist oder die Fuses falsch
sind kann ich im Prinzip ausschließen, da vom Hersteller
funktionstüchtig so geliefert.
Manuel schrieb:> hm also ich messe bisher einfach direkt am Netzgerät, welches ja schon> sehr hochohmig sein dürfte,
Du meinst sicher "niederohmig".
> Ich muss allerdings auch zustimmen, dass ich nicht bei allen Programmen> dieses Problem habe, es also durchaus ganz gut an dem Quellcode liegen> kann...
Darüber, wie deine "Echtzeituhr" funktioniert, hast du allerdings noch
nichts geschrieben.
Manuel schrieb:> es also durchaus ganz gut an dem Quellcode liegen> kann...
Da Du uns den relevanten Code ja nicht zeigst, wird es mit Sicherheit
daran liegen.
Peter
keine ahnung was der relevante code sein soll... die echtzeituhr dürfte
damit auf jeden fall nichts zu tun haben, die funktioniert über externen
32khz quarz mit lithiumbatterie und rufe ich über (bei mir timer 2) den
asynchronen timer auf.
Manuel schrieb:> keine ahnung was der relevante code sein soll... die echtzeituhr dürfte> damit auf jeden fall nichts zu tun haben,
Genau das ist die Vermutung der meisten hier, daß deine Echtzeituhr
nämlich je nachdem was Dein Controller zu tun hat falsch geht.
Nur um das zu sehen, müsste man exakt sehen wie Du diese Echtzeituhr
realisiert hast (Hard und Software).
Wenn die Uhr über einen Timerinterrupt ralisiert wurde müsste man sehen
ob Du evt. irgendwo im restlichen Code die Interrupts so lange
deaktivierst, daß welche verschluckt werden.
Manuel schrieb:> keine ahnung was der relevante code sein soll.
Na welcher wohl? Der Code, den du geschrieben hast, und der nun in einem
Controller läuft! Leute gibts....
folgende routinen beinhaltet mein programm:
void delay_ms(unsigned int period);
void ADC_Init (void);
uint16_t ADC_Read(uint8_t channel);
uint16_t ADC_Read_Avg(uint8_t channel, uint8_t average);
void PWM_Init(void);
uint16_t PWM_Set(uint16_t adc, uint8_t channel);
void Steuerung (uint8_t channel);
uint16_t Strommessung (void);
uint16_t Spannungsmessung(void);
void Tiefenmessung (void);
void Display_Dimm(uint8_t endwert);
void RTC (void);
in main rufe ich alles auf, Steuerung liest adc ein und gibt in
umgewandelter form an pwm weiter, Strommessung, spannungsmessung und
tiefenmessung lesen adc ein, verarbeitet den wert und geben etwas aufm
display aus.
display dimm steuert die helligkeit der lcd des displays
Manuel schrieb:> die uhr ist schon genau, ich frag sie nur nicht genau ab
?? Bahnhof?
In deinem Timer2-Interrupt setzt du nur eine Flag, welche irgendwann
(im schlechtesten Fall >250ms) mal abgearbeitet wird. Deine RTC wird
also nicht genau laufen - kann sie garnicht - da die Aktualisierung
immer irgendwann während der Programmlaufzeit passiert. Relativ genau
wäre sie, wenn sie in der ISR aktualisiert würde. Schau dir mal an, wie
das in dem oben verlinkten Artikel gemacht wurde.
- gerd
die uhr ist daher annähernd genau, da sie hardware-gesteuert ist und ich
sie nur über den asynchronen timer abfrage und dann durchaus starke
verzögerungen rein bekomme, bis ich sie in main aktualisiere, aber das
reicht mir momentan erstmal aus.
wollte ich das so machen, wie in dem beitrag den du gepostet hast,
müsste ich die uhr bei veränderung jedes mal neu stellen, ich will sie
aber erstma nur mit dem wert, den ich ihr über twi eingestellt habe so
weiter laufen lassen und aktualisiere mir ab und zu ma die uhrzeit, die
ich mir anzeigen lasse.
du hast timer 2 im asynchronen Modus mit nem Uhrenquarz dran?
Wenn ja, dann hat gerd recht.
Szenario:
Int2 löst aus.
Programm kommt zur Abfrage, passt.
Int2 löst aus.
Programm rädelt grad länger mit ADC und anderem.
Int2 löst aus.
Programm kommt zur Abfrage, ein Interrupt wurde aber nicht
berücksichtigt.
Vertstehst du das Problem?
Nebenbei: Wenn man den Timer asynchron betreibt, dann gibt es ein paar
Kleinigkeiten zu beachten. Die hängen damit zusammen, dass dann nicht
nur der Oszillator des Timers sondern der gesamte Timer asynchron läuft.
Steht alles fein säuberlich im Datasheet, muss man bloss lesen.
Es spricht übrigens nichts dagegen, den Zeitupdate in der Mainloop zu
lassen. Man muss das nur anders organisieren. Ohne programmiertem delay.
In deinem Fall könnte man beispielsweise den Timer auf 250ms statt
1000ms Interrupt konfigurieren und die Mainloop darauf warten lassen.
Und in jedem vierten Durchlauf die Uhr hochzählen, als erste Aktion in
der Mainloop. Solange der übrige Kram nicht länger dauert als 250ms geht
das in Ordnung.
jo das hab ich auch schon überlegt^^ so werd ich das wohl auch machen.
aber was meinst du mit dingen, die man noch beachten muss wenn man den
asynchronen timer betreibt? dass die delay-routine in meinem programm
keinen sinn ergibt sehe ich ein und hatte ich auch noch vor zu ändern.
Ich meine jene Dinge, für die das Datasheet des ATmega32 unter
"Asynchronous Operation of Timer/Counter2" ca. 1,5 Seiten verwendet.
Wird beim ATmega2561 wohl ähnlich aussehen.