PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Frequenzwandlung - ich weiß nciht weiter



Powell
21.06.2008, 18:45
Hallo zusammen.

Habe folgendes Problem: Ich habe ein Eingangssignal, das ein Rechtecksignal mit einer Tastrate von 50% ist und eine Pulsbreite von ca. 2ms bis 0,1ms aufweist (Signal kommt von einem Sensor der die Drehzahl einer Welle erfasst)
Nun möchte ich dieses Programm mithilfe eines MEGA8 modifizieren, genauergesagt soll die Pulsbreite 10% breiter sein als die des Eingangssignals, d.H. wenn das Eingangssignal eine Pulsbreite von 1ms hat, hat das Ausgangssignal eine Pulsbreite von 1,1ms.

Das Soweit zur Theorie. In der Umsetzung ist es mir bisher zwar gelungen, das Eingangssignal einzulesen, jedoch hapert es noch an der Ausgabe.
Ich habe hier bisher immer eine Variable bekommen und diese in das COMPARE1A register geschrieben. (OC1A an PB1)
Es hat wunderbar funktioniert, jedoch passiert es etwa alle 5 Sekunden, dass das Ausgangssignal einfach abreißt, d.h. ich ein konstantes Low Signal rausbekomme, das dauert etwa 1 sekunde, dann funktioniert es wieder, nach 5 Sekunden wieder das selbe... Das Eingangssignal ist nicht schuld, das liegt dauerhaft an.

woran kann das liegen? Ich hoffe jemand hat Rat....

Grüße Paul

wkrug
22.06.2008, 01:26
Wie liest Du denn dein Eingangssignal ein ?
Per Input Capture, per INTx oder per Polling ?
Der PWM Generator läuft ja in Hardware und sollte deshalb eigentlich keine Probleme machen.

Powell
22.06.2008, 13:25
Hi,

beim ersten Versuch habe ich den Eingang mit PULSEIN ausgelesen.
Beim Zweiten Versuch mit INTx. Bei beiden Wegen zeigt sich das Selbe Symptom - das Ausgangssignal reißt für einige Sekunden einfach ab.

geronet
22.06.2008, 13:54
5 Sekunden?
Watchdog an?
Overflow einer Variable?
Timer richtig eingestellt (vielleicht läuft der über)?
Alle globalen Variablen in den Interrupts mit volatile deklariert?

Grüsse, Stefan

Powell
22.06.2008, 14:54
Hi,

ich habe noch mal weiterversucht und ein Display angehängt was mir direkt den Wert von compare1a ausgibt.
Ich habe den Eingang mit einer sich alle 100ms verändernden Frequenz beaufschlagt, und konnte beobachten, dass sich der compare1a-Wert auch ganz brav alle 100ms mitverändert (variiert zwischen 10 und 45)

@ Stefan: ich habe meine 5 sekunden schätzung noch mal genau ermittelt, und folgendes ergebnis bekommen:

4 sekunden Frequenzausgabe, 18 sekunden low signal, 2,5 sekunden Frequenzausgabe, 20 sekunden hi signal, 40 sekunden Frequenzausgabe, 14 sekunden hi signal.... usw.
Es lässt sich also absolut keine regelmäßigkeit erkennen, sowohl die Unterbrechungsdauer scheint zufällig, als auch das Unterbrechungssignal (hi oder lo). (P.S.: Es liegt definitiv kein Wackelkontakt vor)

Watchdog ist nicht an. Overflow einer Variable sollte es auch nicht sein. Ob ich die Timer richtig eingestellt habe weiß ich nicht (siehe code). Globale Variablen in den Interrupts mit volatile deklarieren? Ich weiß leider nicht was das bedeutet... :oops:




$regfile = "m8def.dat"
$crystal = 1000000 'Quarz: 1,000 MHz Intern


'---------------------------------------------------------

Tccr1a = &B01000000
Tccr1b = &B00001100




Dim Pulsbreite As Long

Dim Faktor As Word







Dim ___lcdno As Bit
Config Lcdpin = Pin , E = Portc.3 , E2 = Portd.7 , Rs = Portc.2 , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , Db7 = Portd.5
Config Lcd = 20 * 4a , Chipset = Ks077
Config Lcdbus = 4
Config Pind.6 = Output 'RW=0
Portd.6 = 0
Config Pind.7 = Output
Portd.7 = 1 'LCD Licht ein
Initlcd
Cursor Off
Cls









Config Pinc.0 = Input
Config Pinb.1 = Output
Config Pinb.0 = Input

Portb.0 = 1








Enable Interrupts



Do


Pulsein Pulsbreite , Pinb , 0 , 0







Pulsbreite = Pulsbreite * 255 'Umrechnungsfaktor 2,55
Pulsbreite = Pulsbreite / 400
Pulsbreite = Pulsbreite * 512

Faktor = 490

Pulsbreite = Pulsbreite / Faktor





If Pulsbreite = 0 Then
Pulsbreite = 65535
End If


Compare1a = Pulsbreite










Waitms 100

Locate 1 , 3
lcd " "
Locate 1 , 1
Lcd "c=" ; Compare1a


Loop




End

Gock
22.06.2008, 15:52
Mit Elektronik hat das meiner Meinung nach nichts zu tun, das ist ein reines Softwareproblem. Daher sollte dieser Thread in die Bascom Abteilung verschoben werden, da kann man Dir wahrscheinlich besser helfen.
Ich kenn' mich nicht aus in Bascom, aber für mich sieht es klar nach fehlender Rechnleistung aus. Solche zeitkritischen Dinge in Bascom zu lösen ist keine Option, denke ich.
Und dann auch noch mit diesem geringen Takt!!!
Bei Pulsbreiten von 0,1-2ms und davon 10% bist du im Bereich 10-x00µs. 10µs halbwegs reproduzierbar ist auch in C schon nicht einfach und wenn es dann auch noch Messwerte sind, die genau sein sollen, kommst Du meiner Meinung nach an Assembler nicht vorbei.
Hast Du mal verglichen, wie genau Deine Pulse verlängert werden? Und ob sie überhaupt alle verlängert werden? Vielleicht fehlt auch ab und zu mal einer, das ist schwer zu erkennen ohne gute Oszis.

Was da passiert ist folgendes: Bevor ein kompletter Rechenablauf für einen Puls beendet wird, kommt bereits der nächste Puls und die nächste Rechnung wird begonnen. Das geht dann solange gut, bis entweder der Stack überläuft und/oder bis ein kompletter Impuls nicht registriert wird, weil nur max 1 weiterer IRQ gespeichert werden kann.
Die Unregelmäßigkeit hängt vermutlich auch mit der Eingangspulsbreite zusammen. Mit einem niedrigen Eingangstakt wird es möglicherweise funktionieren.
Was Du machen kannst, ist, den Takt auf 16MHz zu erhöhen.
Das wird aber vermutlich nicht reichen. Also solltest Du alles aus dem Program nehmen, was nicht unbedingt gebraucht wird.
Division durch 400 ist kontraproduktiv. Daher solltest Du lieber mit einer Zahl multiplizieren, die ungleich 2^x ist, anstatt zu dividieren, wenn es unbedingt sein muss. Das könnte auch helfen, aber ich weiß nicht, wie Bascom das intern handhabt.
Wenn es einen "ShiftRight oder-Left" Befehl gibt, dann benutze den anstatt * oder / 256 usw.
Zeitmessungen macht man am elegantesten mit dem ICP Pin!
Vielleicht hilft es ja...

Powell
22.06.2008, 16:17
Hi,

ich habe daraufhin mal schnell folgendes probiert:

- Eingangspulsbreite auf 10-15ms erhöht -> keine Veränderung
- sämtliche Rechenoperationen aus dem Code genommen (compare1a ist gleich dem pulsein wert) -> keine Veränderung

die Sache ist ja die, dass ich extra noch das LCD angehängt habe um mir den Wert von compare1a ausgeben zu lassen. Dieser Wert springt auch nie, sondern hat immer die erwartete Größe (auch wenn das Signal mal wieder abreißt).
Ich erkläre mir dadurch, dass bis zu diesem Punkt alles in Ordnung sein muss (das Eingangssignal wird also zuverlässig eingelesen), nur die Ausgabe stimmt dann einfach nicht.

Was mir weiterhin aufgefallen ist ist, dass es vorwiegend probleme gibt wenn die Frequenz des eingangssignal verändert wird. Bleibt sie konstant, reißt das Ausgangssignal nie oder fast nie ab.

Gock
22.06.2008, 17:14
Was machen eigentlich diese wait 100ms?
Ich habe mal gelesen, dass eine Bascom 16Bit / 8Bit Division 283 Takte braucht. Du hast 2 16Bit / 16Bit Divisionen drinnen und 2 16Bit Multiplikationen. Du solltest mal herausfinden, wieviel Takte dazu notwendig sind, denn alleine ohne die 16Bit Divisionen komme ich nur durch diese eine Rechnung auf vielleicht 600-1000Takte. Das sind alleine 0,6-1ms!
Dann noch das LCD, die ISRs, die ganzen Sprünge und wer weiß, was Bascom sonst noch macht.
Die angestrebten 10µs erreichst Du jedenfalls nicht.
Aber ohne den gesamten Code kann Dir hier eh niemand helfen.
Und wie gesagt, ich kenn mich nicht aus in Bascom, vielleicht weiß es wer anders.