Hallo Leute, ich habe mir mittels Codesammlung und eigenen Überlegungen ein Programm zusammengeschreiben, was am ICP (PD6 vom Atmega32) eine Zeitspanne messen soll und diese dann in eine Frequenz umrechnen soll. Die Frequenz wird dann in ein char Array umgewandelt und mittels UART zum PC gesendet. Die Kommunikation zwischen AVR und PC klappte bis jetzt eigentlich immer und ich habe auch nichts verändert. Leider sendet mein Programm immer nur komische Zeichen und keine Zahl:( Könnte mal jemand meinen Code angucken? Vieleicht seht ihr ja auf Anhieb einen Fehler?
Is denn soviel falsch, oder warum kann mir keiner helfen?
Nein, aus dem, was du geschickt hast, ist (zumindest für mich) kein Fehler ersichtlich, der den UART versauen würde... Vielleicht postest du noch ein bisschen mehr Code
Wie wärs wenn du erstmal den gemssen Wert ohne umrechung an den PC sendest? (und nicht 5x nachfragst ob dir jemand helfen kann...)
Hi, > ..... Die Kommunikation zwischen AVR und PC klappte bis jetzt > eigentlich immer und ich habe auch nichts verändert. "Eigentlich" klingt nicht so gut... Wenn Du nichts verändert hast, ist was kaputt oder hat sich spontan (?) verändert! > Leider sendet mein > Programm immer nur komische Zeichen und keine Zahl: Reduziert sieht Dein Programm so aus: int main() { uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); uart_puts("test"); } Also sollte es auch keine Zahlen senden. Wenn mit der Hardware + Initialisierung beidseits alles stimmt, sollte es "test" senden, sonst nichts! Die Overflows zu zählen, ist eine sehr grobe Methode, die allerdings für Deine Frequenzen durchaus adäquat sein kann. Gruß Fred
Ich wuerde die float Umrechnung aufm PC machen. Das bringt wenig aufm Mega32.
Also, habe den fehler gefunden, hatte irgendwas mit den header files verpeilt. Nun funktioniert es und ich bekomme mittels uart wunderbar die werte ausgegeben. leider bekomme ich alle 5-10 Werte einen Wert, der nicht stimmen kann, es ist in etwas das doppelte der Werte von davor...wie kann so etwas passieren, oder wie kann ich es vermeiden?
Lass dir doch mal die rohen Wert ausgeben. Also NrOverflows, Starttime, Stoptime Daraus kannst du dann deine Schlüsse ziehen.
Kann man aus einer InterruptRoutine eigentlich mit return wieder rausspringen?
Werner wrote: > Kann man aus einer InterruptRoutine eigentlich mit return wieder > rausspringen? Ja. Warum sollte das nicht gehen?
hmm, es sieht so aus, als würde teilweise eine Flanke übersprungen.Wo kann da der Fehler liegen?
Die Overflows können Probleme machen. Die Zahl der Overflows sollte muss in der ICP routine gemerkt werden. Siehe auch: Beitrag "sehr schnelle Signale messen"
Hmm, das Problem ist aber, dass der Feheler nur bei niedrigen Frequenzen auftriit, und zwar immer mehr, so tiefer die Frequenz:S Wie meinst du das mit dem Overflow?
In seltenen Fällen kann ein weiterer Timer-Overflow passieren zwischen dem 2 ten ICP und dem Ausgeben im Hauptprogramm. Ebenfalls eher selten kann der Überlauf und ICP praktisch gleichzeitig auftreten. Dann wird erst der ISR mit höherer Priorität abgearbeite, obwohl der andere eventuell ein paar Zyklen vorher darn sein sollte. Das kann passieren, weil einige Befehle mehr als einen Zyklus brauchen. Für den Stopp-Fall wird dieser Fehler durch den oberen gerade wieder berichtigt, aber beim Start kann es da zu einem extra Overflow kommen, der eigentlich vor dem Start war. Die oben beschrieben Fälle sind wirklich selten (ca. 1:10000) und sollten unabhängig von der Frequenz sein. Die Zeit kann dadurch gerade um jeweils einen Overflow zu lang sein. Wenn der Fehler bei sehr niedrigen Frequenzen auftritt, wird das aber eher ein anders Problem sein.
hmmm, hat da jemand vieleicht noch ne Idee, warum gerade bei den niedrigen Frequenzen dieser Fehler auftritt, dass all 10 bis 20 Messungen ein Wert dabei ist, der genau doppelt so hoch is wie die anderen?
Bezieht sich das genau doppelt so hoch auf de Frequenz oder die Perioden Zeit ? Das sollte dann eher ein Problem mit der Hardware sein: Entweder reicht der Pegel nicht ganz aus, und nur Überschwinger triggern meistens den ICP oder es gibt bei der anderen Flanke noch ein paar Überschwinger die dann auch bei der falschen Flanke triggern.
hmm, naja an hardware gibts bei mir eigentlich nich viel;) ich habe einen Tachoausgang eines Lüfters und dieser hängt über einen Pull-up Widerstand (10kOhm) an Vcc...kann man das noch anders lösen?
Man könnte versuchen im Controller den Noise Cnacler zu aktivieren. Dann werden ganz kurze Pulse Ignoriert. Da es für einen Lufter wohl nicht auf 5 Stellen ankommt, könnte man auch den Przessortakt etwas runter setzen, der Noise Cancler wird dann effectiver. Eventuell könnte man auch in der ICP routine noch mal controllieren, ob wirklich der erwartete Pegel am ICP Pin anliegt und ggf. das Signal Ignorieren. Wenn das Signal zu schwach ist, könnte man auch den analogen Komperator als Eingang nutzen. Es ist immer noch nicht klar, ob die Frequenz gelegentlich zu hoch oder zu niedrig angezeigt wird ?
Zeig doch endlich mal ein paar Messwerte her. Also: Anzahl Overflows, Start ICP, End ICP Ich wette fast, dass bei deinen falschen Werten immer ein Overflow beteiligt ist.
Hallo, die Werte werde ich heute Abend mal reinstellen. Die Frequenz is immer fast genau doppelt so hoch, als wenn eine Flanke übersehen wird. Wie aktiviert man denn diesen Noise Canceler?
Wenn die Frequenz doppelt so hoch ist, dann wird eine extra Flanke nach der halben Zeit erkannt. Abhilfe kömmte der noise Cancler bringen, oder auch ein kleiner Kondensator am Eingang. Noise Cancler wird im TCCR1B Register eingeschaltet. Außer für sehr kurze Pulse (< 4 Zyklen) gibt der fast keinen Nachteile. Auch die Software Lösung, den Zustand nach dem ICP abzufragen sollte helfen.
wo meinst du den kondensator am eingang? also wie soll ich ihn schaltungstechnisch einbauen? 100nF?
Hab das Problem jetzt gelöst, indem ich den aktuellen Wert immer mit dem vorherigen vergleiche und so keine groben Ausreißer zulasse. Nun habe ich aber noch eine Frage. Wenn keine Flanken mehr am ICP ankommen, wartet das Programm ja solange bis eine Flanke kommt. Wie kann ich es erreichen, dass nach einer gewissen Zeit, wo keine Flanke kommt ein bestimmtes Ereignis auslösen kann?
Die Überläufe des Timers zählen, und wenn diese Zahl groß genug ist, lässt du irgendwas passieren. Natürlich mußt du die Überlaufzählvariable bei Flanken zurücksetzen...
Hmm ok, das versteh ich schonmal, nur weiß ich nich ganz genau wie ich es im Code umsetzen soll. kannst du mir da nochmal nen Tip geben? Anbei nochmal mein aktueller Code
Cha_Ko wrote: > Hmm ok, das versteh ich schonmal, nur weiß ich nich ganz genau wie ich > es im Code umsetzen soll. Dann hast du es auch nicht verstanden. > kannst du mir da nochmal nen Tip geben? Was für einen Tip brauchst du noch? > Die Überläufe des Timers zählen, Das machst du ja schon. Genau das macht die Overflow ISR indem sie die NrOverflows Variable hochzählt > und wenn diese Zahl groß genug ist, D.h. du legst eine Obergrenze fest. > lässt du irgendwas passieren. In der Hauptschleife in main() vergleichst du NrOverflows mit deiner selbstgewählten Obergrenze und wenn beide gleich sind, hast du dein Ereignis
1 | #define MEINE_GRENZE 100
|
2 | |
3 | |
4 | ...
|
5 | |
6 | sei(); |
7 | while(1) |
8 | {
|
9 | // zu viele Overflows ?
|
10 | if( NrOverflows > MEINE_GRENZE ) |
11 | {
|
12 | ....
|
13 | }
|
14 | |
15 | //
|
16 | // liegt eine vollst�ndige Messung vor?
|
17 | //
|
18 | if( UpdateUart) |
19 | {
|
20 | ...
|
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.