Hallo Leute,
ich hab da eine Frage, leider keinen Quellcode, bin gerade in der Schule
und kann den nicht aufrufen.
Also folgendes Problem:
Ich hab mir einen Timer0 programmiert, mit 1ms Overflowzeit. Ich hab in
dem Projekt nichts anderes drin als dem Timer0 sprich keine
deklarationen, keine unterprogramme nichts.
was der Timer0 macht ist folgendes: er Taktet mit 1ms und invertiert
eine LED.
Das funktioniert auch wunderbar. gestern abend lief er locker 1 std und
blinke vor sich hin. und auf einmal blieb er stehen.
hat jemand schonmal ein solches phänomen gehabt? gibt es da einen timer
"durchlauf" limit, welches man irgendwie zurücksetzen müsste?
edit die bitinvertierung rufe ich im ISR Timer0_ovf_vect
gruß
sven
Sven Weinmann schrieb:> leider keinen Quellcode, bin gerade in der Schule> und kann den nicht aufrufen.
Die Kristallkugeln sind auch gerade alle in der Wartung.
Sven Weinmann schrieb:> witzbold....>> einfacher timer0 aufruf....
Offenbar nicht, sonst würde es ja funktionieren.
Wie wird der Controller getaktet? Quarz, Oszillator, intern?
Sven Weinmann schrieb:> was der Timer0 macht ist folgendes: er Taktet mit 1ms und invertiert> eine LED.>> Das funktioniert auch wunderbar. gestern abend lief er locker 1 std und> blinke vor sich hin. und auf einmal blieb er stehen.
Du kannst ein mit 1 ms getaktetes Blinken als solches erkennen?
> hat jemand schonmal ein solches phänomen gehabt? gibt es da einen timer> "durchlauf" limit, welches man irgendwie zurücksetzen müsste?
Nein. Ich würde jetzt auf ein Schaltungsproblem tippen, z.B. fehlende
Abblockkondensatoren, Reset-Pullup, instabile Versorung oder irgendwas
derartiges.
natürlich kann ich das nicht sehen, hab mit einer laufvariable I bis 100
zählen lassen und beim überlauf invertiert und I auf 0 gesetzt.
ich poste später den quellcode.
# ->
TCCR0 |= (1<<CS01) | (1<<CS00)
TCNT0 = 198
so hab ich übrigends die 1ms realisiert
Sven Weinmann schrieb:> TCCR0 |= (1<<CS01) | (1<<CS00)
^---- gefährlich! Was passiert, wenn CS02 schon vorher gesetzt
war? Richtig, es bleibt nach der Zuweisung noch immer gesetzt
>> TCNT0 = 198>> so hab ich übrigends die 1ms realisiert
Also mal wieder Salamitaktik: Nur nicht zu viel auf einmal verraten,
sonst könnte die Lösung ja zu schnell gefunden werden.
Immerhin kann man aus den Registernamen schon mal erahnen, daß es sich
vermutlich um einen AVR handelt. Aber jegliche Informationen darüber,
wie der verschaltet ist, fehlen. Das Programm (vermutlich in C?) fehlt
ebenso, bis auf zwei Zeilen, die nicht viel aussagen. Keine der
angegebenen Informationen geben irgendeinen Anhaltspunkt, warum es nicht
funktionieren sollte.
Das einzige, was einen vagen Hinweis geben könnte, ist, daß es erst nach
einer Stunde auftritt. Das läßt - wie ich schon geschrieben habe - eher
ein Hardwareproblem vermuten als ein Softwareproblem. Oder gibt es
irgendwas in deinem Programm, das nach einer Stunde etwas anders macht
als davor?
Martin Kreiner schrieb:> Sven Weinmann schrieb:>>> TCCR0 |= (1<<CS01) | (1<<CS00)>> ^---- gefährlich! Was passiert, wenn CS02 schon vorher gesetzt>> war? Richtig, es bleibt nach der Zuweisung noch immer gesetzt
Das ist ja nun an den Haaren herbeigezogen. Nach Reset ist das 0.
Rolf Magnus schrieb:> Also mal wieder Salamitaktik:
Das ist das Smartphone-Problem:
Sven Weinmann schrieb:> ich hab da eine Frage, leider keinen Quellcode, bin gerade in der Schule> und kann den nicht aufrufen.
...und schon dreimal meine Emails gecheckt und immer noch Langeweile.
mfg.
Sven Weinmann schrieb:> Das funktioniert auch wunderbar. gestern abend lief er locker 1 std und> blinke vor sich hin. und auf einmal blieb er stehen.
Hatte ich auch. Mit Feinöl aus der Apotheke laufen jetzt alle Timer wie
geschmiert.
so, entgegen der ganzen dummen kommentare dann hier mal der angekündigte
quellcode. (dumm deshalb, weil man diese frage, oder dieses phänomen vll
ja mal beobachtet hätte haben können)
1
#define F_CPU 3686400UL // CPU Takt, externer Quarz
2
#define BAUD 9600 // Baudrate = 9600
3
#include<avr/io.h> // Einbinden der Bib In/Out
4
#include<util/delay.h> // Einbinden der Bib Delay
5
#include<stdint.h> // Einbinden der Bib StandardInteger
6
#include<avr/interrupt.h> // Einbinden der Bib Interrupt
Sven Weinmann schrieb:> /*> Gewünschte Zeit: 0.001 s = 1ms> Verwendeter Prescaler: 64> -> 3,6864 MHz / 64 -> 57,6kHz = 0 - 256 Schritte> Wunschfrequenz = 1kHz -> 58 Schritte abziehen> Preload folglich: 198 (256-58)> */
Ist dir bewußt, daß sich das nur auf den ersten Timer-Durchlauf
auswirkt?
Sven Weinmann schrieb:> so, entgegen der ganzen dummen kommentare dann hier mal der angekündigte> quellcode. (dumm deshalb, weil man diese frage, oder dieses phänomen vll> ja mal beobachtet hätte haben können)
Diese Frage habe ich dir gleich zu Anfang beantwortet. Die Antwort
lautete: Nein. Ich denke aber, daß du eigentlich wissen willst, warum es
bei dir auftritt, und um das zu beantworten, hast du einfach nicht die
nötigen Infos gebracht. In so einem Fall mußt du halt auch mit Antworten
rechnen, die eher weniger hilfreich sind.
Nachdem ich mir deinen Code angeschaut habe, kann ich übrigens nur
bestätigen, was ich schon zweimal geschrieben habe: Es handelt sich
anscheinend um ein Hardware-Problem.
Der Variablen solltest du noch ein volatile spendieren.
oder in der ISR static deklarieren.
Solche Sachen kann man nicht per Ferndiagnose und "Rate mal mit
Rosenthal" finden.
UCSRB=0b10011000;// Empfänger, Sender ein UCR = UCSRB
wenn du eine Komponente nicht benutzt, hier die UART, dann lässt du sie
in Ruhe. Schmeiss dein Code raus!
Gratuliere, die hast mit der kryptischen Zuweisung den Receive Complete
Interrupt enabled und keine ISR dafür.
Sobald sich der µC auf den UART Pins genügend elektromagnetische Felder
eingesammelt hat, kommt es irgendwann zum Interrupt und alles geht den
Bach runter.
Man lässt unbenutzten bzw. unnötigen Code nicht im Programm stehen!
Niemals! Und schon gar nicht aktiviert man Interrupts für nicht benutzte
Komponenten.
STK500-Besitzer schrieb:> Wieder ein dummer Kommentar meinerseits:>> Sven Weinmann schrieb: int I = 0;>> Der Variablen solltest du noch ein volatile spendieren.> oder in der ISR static deklarieren.
Solange er nur von dieser ISR aus drauf zugreift, spielt das keine
Rolle. Aber prinzipiell hast du recht. Sowas schießt einem dann später
ins Knie, wenn man das Programm dann erweitert und nicht mehr daran
denkt.
Am besten man legt solche Variablen da an, wo man sie benötigt und macht
solche normalen Zählvariablen nicht global sondern static und lokal in
der Funktion wo man sie braucht...
Karl Heinz Buchegger schrieb:> Gratuliere, die hast mit der kryptischen Zuweisung den Receive Complete> Interrupt enabled und keine ISR dafür.
Peinlich! Da waren die ganzen dummen Kommentare aber wirklich
berechtigt!
hallo leute!
ich hab mal alles so eingestellt, wie ihr es vorgeschlagen habt, bzw
parts gelöscht, die nicht benötigt wurden!
der quellcode sieht nun so aus und funktioniert auch wie erwartet, OHNE
hängenbleiben des timers. (er blinkt seit gestern mittag vor sich hin).
und dann habe ich einen teil eingefügt, aus meiner
schrittmotorsteuerung:
ich möchte bgerne mit einem taster eine anzahl an schritten aufrufen,
die dann durch den timer als taktgenerator bei jedem overflow ein bit
invertiert. hier hab ich einfach eine LED genommen um dies darzustellen.
aber die "blinkt" nicht, sie leuchtet, mal glimmt sie.
ich mache doch nichts anderes, als beim "drücken" des tasters die
interupts zu deaktivieren, gebe der variable schritte einen wert und
aktiviere dann wieder die interupts. warum geht dass denn nicht? was hab
ich schon wieder nicht beachtet?
1
#define F_CPU 3686400UL // CPU Takt, externer Quarz
2
#define BAUD 9600 // Baudrate = 9600
3
#include<avr/io.h> // Einbinden der Bib In/Out
4
#include<util/delay.h> // Einbinden der Bib Delay
5
#include<stdint.h> // Einbinden der Bib StandardInteger
6
#include<avr/interrupt.h> // Einbinden der Bib Interrupt
Sven Weinmann schrieb:> ich mache doch nichts anderes, als beim "drücken" des tasters die> interupts zu deaktivieren, gebe der variable schritte einen wert und> aktiviere dann wieder die interupts. warum geht dass denn nicht?> was hab ich schon wieder nicht beachtet?
1. auch nach dem Weltuntergang erhöht die Benutzung der Shift-Taste die
Lesbarkeit eines Textes ;)
2. Du solltest dich mit dem Entprellen von Tasten beschäftigen.
3. Statt eines Timer-Preload solltest du dir lieber die verschiedenen
Timer-Modi deines AVR mal ansehen. Um eine konstante Frequenz zu
erzeugen benutzt man besser den CTC-Mode.
1
DDRC|=(1<<4);// Taster
sicher, dass das das macht, was du gerne hättest?
Das Beispiel aus dem hiesigen AVR-Tutotium:
uiuiui ja das mit dem taster hab ich korrigiert.
ob ich da nun eine tasterentprellung bruache für diese eine anwendung
bezweifel ich mal. natürlich ist das immer wichtig. abver was passiert
denn schon wenn er nicht entprellt ist?
der wert 1000 wird halt wieder und wieder in die variable geladen, aber
irgendwann sollte dann trotzdem die 1000 herunter gezählt werden und die
LED blinken.
was den CTC modus angeht, ich benutze doch den TIMER0 und im Tutorial
steht, dass es den nur beim TIMER1 gibt.
Sven Weinmann schrieb:> ob ich da nun eine tasterentprellung bruache für diese eine anwendung> bezweifel ich mal. natürlich ist das immer wichtig. abver was passiert> denn schon wenn er nicht entprellt ist?
in deinem Fall?
Bei jedem Prellen wird deine Variable um 1 erhöht.
Und das können schon mal ein paar mehr Welchselvorgänge sein.
Sven Weinmann schrieb:> was den CTC modus angeht, ich benutze doch den TIMER0 und im Tutorial> steht, dass es den nur beim TIMER1 gibt.
Das Tutorium arbeit beispielhaft. Wenn du etwas über die Fähigkeiten
deines Controllers herausfinden willst, bringt es mehr, ins Datenblatt
zu schauen ( nicht die summary-Version!)
Sven Weinmann schrieb:> der wert 1000 wird halt wieder und wieder in die variable geladen, aber> irgendwann sollte dann trotzdem die 1000 herunter gezählt werden und die> LED blinken.
Für einen ersten Test ist das ok.
Aber für ein richtiges Programm ist das nicht zu gebrauchen.
Wenn 1000 Schritte gefragt sind, dann sollten es auch tatsächlich 1000
Schritte sein und nicht ein paar mehr, weil ich mal etwas länger auf der
Taste geblieben bin und die Timer-ISR schon angefangen hat mit
runterzählen.
> was den CTC modus angeht, ich benutze doch den TIMER0 und im Tutorial> steht, dass es den nur beim TIMER1 gibt.
Jau. Ist beim Mega8 so.
Die Frage ist, ob das nicht ein Grund wäre auf den Timer 1 auszuweichen.
Denn ob der jetzt rumlungert und nichts zu tun hat, oder dir deine
Zeitbasis liefert ist dem Mega ja prinzipiell wurscht.
Karl Heinz Buchegger schrieb:> Wenn 1000 Schritte gefragt sind, dann sollten es auch tatsächlich 1000> Schritte sein und nicht ein paar mehr, weil ich mal etwas länger auf der> Taste geblieben bin und die Timer-ISR schon angefangen hat mit> runterzählen.
Man kann natürlich auch die Aufgabenstellung umdefinieren :-)
Definier einfach:
Dein Programm soll folgendes machen:
Sobald du die Taste drückst, fängt der Schrittmotor zu laufen an.
Und sobald du loslässt, läuft er noch 500 Schritte nach.
Denn genau das macht dein jetziges Programm :-)
(Aber ewig kann man das natürlich nicht machen. Auf längere Sicht sollte
sich schon das Programm an die Vorgabe halten und nicht hintennach die
Aufgabenstellung so angepasst werden, dass sie zu dem passt was man
programmiert hat :-))
Karl Heinz Buchegger schrieb:> Die Frage ist, ob das nicht ein Grund wäre auf den Timer 1 auszuweichen.> Denn ob der jetzt rumlungert und nichts zu tun hat, oder dir deine> Zeitbasis liefert ist dem Mega ja prinzipiell wurscht.
Bisher war der Plan:
TIMER0 -> 1ms Takt für den Schrittmotor und einen PI Regler zu nutzen.
Wollte von dem Takt Laufvariablen steuern im Takt von 1ms
TIMER1 -> Entfernungssensor, zur steuerung eines sensors eben^^
allerdings wenn ich wirklich einen takt von 1ms habe kann ich
theoretisch auch alle darüber laufen lassen und alles mit laufvariablen
machen, so hab ich dann EINEN timer, und alle werte wären synchron
Karl Heinz Buchegger schrieb:> Man kann natürlich auch die Aufgabenstellung umdefinieren :-)
ich hab eben gesagt ich bruache keine entprellung eben genau aus dem
grund dass es nur zum test ist! im programm selbst kommt später nur ein
taster zum starten vor, welcher eine variable auf 1 setzt. es war nun
einfach mal als test, wie ich denn den wert der schritte, also die 1000
in die ISR reinbringe.
Sven Weinmann schrieb:> Karl Heinz Buchegger schrieb:>> Die Frage ist, ob das nicht ein Grund wäre auf den Timer 1 auszuweichen.>> Denn ob der jetzt rumlungert und nichts zu tun hat, oder dir deine>> Zeitbasis liefert ist dem Mega ja prinzipiell wurscht.>> Bisher war der Plan:>> TIMER0 -> 1ms Takt für den Schrittmotor und einen PI Regler zu nutzen.> Wollte von dem Takt Laufvariablen steuern im Takt von 1ms>> TIMER1 -> Entfernungssensor, zur steuerung eines sensors eben^^
OK.
Datenblatt rausgeholt.
Der Timer 2 kann ebenfalls CTC
Problem gelöst :-)
> taster zum starten vor, welcher eine variable auf 1 setzt. es war nun> einfach mal als test,
Das hab ich auch so verstanden, dass das nur ein Test war - keine Sorge.
so, ein kleines update:
TIMER1 benutzt mit CTC.
Taster semiprofessionell entprellt,
LED 1 blinkt im takt von 1ms/100 (siehe ISR)
LED 2 schritte blinkt nicht! Gleicher Effekt wie eben. Woran kann das
liegen?
1
#define F_CPU 3686400UL // CPU Takt, externer Quarz
2
#define BAUD 9600 // Baudrate = 9600
3
#include<avr/io.h> // Einbinden der Bib In/Out
4
#include<util/delay.h> // Einbinden der Bib Delay
5
#include<stdint.h> // Einbinden der Bib StandardInteger
6
#include<avr/interrupt.h> // Einbinden der Bib Interrupt
einen Portpin, den du auf Ausgang stellst, wirst du eher selten mit
einem Taster beeinflussen können. OK. Du erzeugst mit dem Taster einen
Kurzschluss, wenn du den Ausgangstreiber gegen GND schaltest. Und was
dann alles passiert hängt auch davon ab, wie stark dein Netzteil ist
bzw. wie lange der Mega den Kurzschluss überlebt. Bei dir scheint das
Netzteil aufzugeben, was sehr vernünftig ist.
LOL
1
for(x=0;x<=500;x++)
2
{;}
Ob du, oder der Optimizer diese 2 Zeilen rauslöscht schenkt sich nix :-)
mist sry vergess das! das hatte ich eben schon geändert! ich hab nur
meinen quellcode von oben "nachgebessert"
hatte das nicht mit geändert. im quellcode im AVR studio ist es aber
korrekt!
ohne quatsch! das entprellen wird so an meiner schule gele"e"rt
Sven Weinmann schrieb:> ohne quatsch! das entprellen wird so an meiner schule gele"e"rt
Das Problem ist, dass die meisten EDV-Lehrer (und auch Unis bzw. FHs
sind keine Ausnahme) nicht wirklich gute Programmierer sind. Drum sind
sie auch in den Schulen und nicht in der Industrie.
Karl Heinz Buchegger schrieb:> Das Problem ist, dass die meisten EDV-Lehrer (und auch Unis bzw. FHs> sind keine Ausnahme) nicht wirklich gute Programmierer sind. Drum sind> sie auch in den Schulen und nicht in der Industrie.
danke, endlich mal bestätigung von aussen!!
back to topic.
die LED schaltet Ein und bleibt dauerhaft an, bzw flackert ab und an
mal, im gesamten ist sie aber immer an,
Vergiss es einfach für den Moment.
Ob die Taste jetzt entprellt ist oder nicht, ist doch für den Test
wurscht. Es geht um den Timer.
Und für ein reales Programm kopierst du dir den ISR Teil aus der PeDa
Entprellung in deine 1ms-ISR rein, nimmt noch die Abfragefunktionen mit
dazu und du hast eine 1A erstklassige Tastenabfrage und Entprellung.
ich bekomms nicht hin. die LED leuchtet sobald ich einschalte und blinkt
nicht -.-
nochmal zum verständnis:
der timer läuft bis zum compare und dann wieder unendlich sozusagen. und
jedesmal führt er beim compare erreichen den interupt aus und arbeitet
meinen programmcode ab.
d.h. wenn ich schritte z.b. mit 1000 belege und runterzähle, sollte er
bei jedem interupt 1 abziehen.
der ist in diesem beispiel nicht mit drin, ich sagte in irgendeinem
vorherigen beispiel dass ich den pin des schrittmotortreibers für die
clock hier symbolisch als LED genommen habe!
deshalb sagte ich ja, dass der nicht blinkt
folgendes update! ich hab einen übertragungsfehler gemacht.
das programm aktualisiert und neu aufgespielt!
der effekt ist nun, dass die LED nur einmal aufleuchtet, erlicht udn
wieder aufleuchtet!
und jetzt ohne die zeit zu stoppen glaube ich, dass es sich dabei um die
2s des delays handelt.
eigentlich sollte die led bei jedem CMPMatch invertiert werden!?
Sven Weinmann schrieb:> das programm aktualisiert und neu aufgespielt!> der effekt ist nun, dass die LED nur einmal aufleuchtet, erlicht udn> wieder aufleuchtet!
Räusper.
Dir ist aber schon klar, dass du bei einer LED, die alle 1ms
umgeschaltet wird, die einzelnen Blinker nicht sehen wirst?
Für dich als Mensch zeigt sich die LED als "mit etwas weniger als halber
Helligkeit". Erst wenn du ein Oszi anhängen würdest, könntest du sehen,
dass die Schritt-LED tatsächlich 1 Sekunde lang Pulse abgibt.
Und da in der Hauptschleife alle 2 Sekunden das ganze erneut "gestartet"
wird, weil an Schritte etwas zugewiesen wird, beginnt alles nach 2
Sekunden erneut.
Sven Weinmann schrieb:> der effekt ist nun, dass die LED nur einmal aufleuchtet, erlicht udn> wieder aufleuchtet!
Pack doch mal ein 2-Sekunden-Delay ins Programm, bevor der timer
initialisiert und gestartet wird.
Oder besser 2 Delays: Bei dem einen schaltest du die LEDs ein, beim
anderen aus.
Dann kannst du die Schaltrichtung besser als bei einem Blinken erkennen
(das STK500 bspw. invertiert die LED-Funktion)
das war der grund, warum ich die andere LED, welche nun über Cnt
getaktet ist bis 100 hab zählen lassen, das ist nun wirklich mal wieder
extrem high IQ gewesen....
-> bild
LED 1 PB5 -> ( cnt -> 100 ) ist nur beispielhaft dass ich sehe, dass der
TIMER funktioniert.
LED 2 PB4 -> Schrittmotor CLOCK PIN der eine Anzahl zugeordnet bekommt
die er takten soll
anhand der Auflösung des Rasters kann man übrigends gut erkennen, dass
der Timer mit 1ms läuft!
die Zeit steht auf 2ms pro kästchen. bei 1ms schaltet der Pin um.
Danke Karl-Heinz