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?
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
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
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?
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.
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