Hallo!! Vielleicht kann mir ja jemand weiterhelfen. Benutze einen C8051F020 meine Frequenz läuft auf 24 Mhz. So ich möchte mit einem Timer folgendes machen: Bei meinem 1. Extennen Interrupt positive Flanke möchte ich den Timer starte ( Signal 1) Bein meinem 2. Externen Interrupt an einem anderen Pin möchte ich bei postiver Flanke den Timer stoppen. Diese Zeit die dort Vergangen ist möchte ich gerne ausgeben über UART. ( Die ausgabe über UART funktioniert geht mir hier nur um den timer) der 1. _interrupt(0) void External0IntHandler (void){ soll den timer zum laufen Bringen. kann ich das einfach machen indem ich den TR1=1 setze? beim > _interrupt(2) void External1IntHandler (void){ soll der Timer gestoppt werden und die Werte gespeichert werden. also so : unsigned int wert1,wert2; TR1=0; wert1=TL1; wert2=TH1; geht es so vielleicht?
hört sich ja schomal gut an das es so funktioniert ;-) und wie kann ich den wert dann ausgeben? muss ich da was beachten. Arbeite mit EDE TASKING.
>> unsigned int wert1,wert2; >> TR1=0; >> wert1=TL1; >> wert2=TH1; Kannst hier unsigned char verwenden denn TH1, TL1 sind je 8 BIT und bilden gemeinsam z.B. einen 16 BIT Timerwert:
1 | uint16_t TimerVal; |
2 | |
3 | TimerVal = TH0 << 8 | TL0; |
Solltest du also diese Betriebsart verwenden (16 BIT) Timer dann mußt du den Integer Wert noch Stelle für Stelle nach ASCII umcodieren und kannst diesen dann ausgeben.
>> unsigned int wert1,wert2; >> TR1=0; >> wert1=TL1; >> wert2=TH1; also muss ich das gar nicht so schreiben sondern brauche ich nur dieses zu schreibe: uint16_t TimerVal; TimerVal = TH0 << 8 | TL0; und jetzt habe ich im TimerVAl meinen gemessenen Wert stehen?
sorry war ne blöde frage ;-) also timer arbeitet jetzt mit Interrupt und gibt auch den Wert im HyperTerminal aus. habe aber nun folgendes Problem. mache eine PrintF ausgabe des TimeVal. auf den beiden Pins die die Interrupts auslösen liegt jeweils ein 40kHz signal.kann es sein das das zu schnell ist? wenn ich ein signal auf 50Hz setzte gibt er mir schön immer den Wert im Terminal aus sobal das signal von der Frequenz her größer wird bekomme ich keine ausgabe mehr im Terminal der bleibt komplet stehen. kann mir da jemand helfen. sind die 40khz zu schnell? und deswegen bleibt der HyperTerminal stehen ?
Frank wrote: > kann mir da jemand helfen. sind die 40khz zu schnell? und deswegen > bleibt der HyperTerminal stehen ? HyperTerminal bleibt mit Sicherheit nicht stehen. Aber du hast mit Sicherheit einen Fehler im Programm, der dafür sorgt, dass ab irgendeiner Frequenz keine Ausgabe mehr erzeugt wird. Dein Programm schickt nichts mehr weg -> HyperTerminal zeigt daher auch nichts mehr an. Dein Fehler liegt in Zeile 42 (Soll heissen: Ohne Programmtext kann dir auch keiner helfen den Fehler zu suchen)
Habe aber mit dem Oszilloskop nach gesehen ob der Hyperterminal noch sendet das hat was angezeigt. obwohl er auf dem PC nicht mehr weiter angezeigt hat. und wenn ich die signale weggenommen habe ist das Signal am pin vom hyperterminal auch verschwunden. Was du meinst ist dann das ab einer gewissen Frequenz meine UART verückt spielt. Was dann auf einen Programmierfehler der UART zurückzuführen ist?
Mal 'ne andere Frage: benutzt du einen USB<=>Seriell-Adapter? Damit können solche Effekte auftreteten. Wenn möglich teste es mal mit einer onboard-RS232.
Frank wrote: > Habe aber mit dem Oszilloskop nach gesehen ob der Hyperterminal noch > sendet das hat was angezeigt. obwohl er auf dem PC nicht mehr weiter > angezeigt hat. und wenn ich die signale weggenommen habe ist das Signal > am pin vom hyperterminal auch verschwunden. Was du meinst ist dann das > ab einer gewissen Frequenz meine UART verückt spielt. > > Was dann auf einen Programmierfehler der UART zurückzuführen ist? Ähem, du weißt schon, dass lokal eingegebene Zeichen NICHT in dem unteren Teil angezeigt werden?! (Außer du stellst das lokale Echo ein, aber das vermute ich jetzt mal nicht)
Mein Prozessor ist ein C8051F020 Taktfrequenz auf 22Mhz. den Timer habe ich auf 16 bit mit sysclock /12 Eingestellt. Werde dann mal den Programmteil rein setzen. Denk mal es liegt dan wirklich an der UART. Danke schonmal klappt aber immerhin immer mehr mein Programm ;-))))
Das Programm zu sehen ist immer hilfreich ;-)) Wichtig wäre zu wissen wie deine UART Ausgabe aufgebaut ist (ebenfalls Interrupt oder Polling ? Interruptprioritäten ?). Über "printf" würde ich auch noch mal nachdenken, ganz schöner overhead für ne Integer Ausgabe, schau mal unter den Stichwörtern Modulo sowie ITOA nach. Nen kleiner Mehrzeiler könnte dein "printf" locker ersetzen. Das Timing deiner Signale würde mich ebenso interessieren, kann der Timer überlaufen ? wann wird der Timer zurückgesetzt ? Wieviel Zeit steht für die Ausgabe zur Verfügung ?
Zu den Signalen kann ich dir schonmal sagen das, das der Timer auf jedenfall unter 25µs ist. Der rest müsste sich aus dem Programm ergeben. ich versuch es mal rein zu setzen.
Wie meinst du das ?
>> das der Timer auf jedenfall unter 25µs ist
Signal 1, Timer startet, 25µs später Signal 2 und Timer stoppt ? und
dann ? in welcher Zeit findet das Ganze wieder statt.
Wieviel Zeit hast du für die Ausgabe ? Baudrate ? z.B. setze mal z.B.
9600 Baud in Beziehung zur Zeit die du zur Verfügung hast.
ja genau so siehts aus kann auch sein das es kürzer wird als 25µs ich glaube ich weiss wodran es liegt. kann es sein das es sich um einen Race handelt? also das befor der 1. Wert angezeigt werden kann schon der nächste kommt?
!!in welcher Zeit findet das Ganze wieder statt?? Leider hast du meine Frage nicht beantwortet daher sag ich mal ja ;-))
ja habe gemertk das das ganze sofort wieder stattfindet. also könnte ich doch mal versuchen z.B. durch ne while schleife in der main nicht jede messung auszugeben sonder nur alle 50 z.b.? j
>> durch ne while schleife in der main nicht jede messung auszugeben Was soll das werden ? heiteres code erraten ? Bis jetzt kenne ich immer noch nicht deinen Konstrukt geschweige das du irgendetwas zu >deiner< Problemlösung beiträgst. Wenn deine Messung im Interrupt läuft dann wirst du wohl nach erfolgter Messung deinen Interrupt mal abschalten müssen, dann Ausgabe des Meßwertes, und Interrupt wieder an. Ohne genaue Kenntnis der Abläufe kann man aber nur schwer einen Rat geben. Obwohl ich deine Fragen in 2 Threads lese gibtst du leider nicht die Informationen die man braucht um dir zu helfen. Schonmal über die anderen Tips nachgedacht ? wozu printf ? kostet auch Zeit und Code. Ansonsten: http://www.progforum.com/showthread.php?t=7571 Gruß, Joe Semmel ;-))
So hier mal der Code hoffe mir kann jemand weiterhelfen. also bis 100Hz funktioniert die Ausgabe mit Printf aber wenn die Frequenz höher ist nicht mehr dann bleibt das Terminal Fenster stehen. Die Variablen A und Z habe ich nur eingefügt damit ich sehe ob der timer arbeitet.
Aus meiner Sicht machst du schon auf Hardwareebene einen Fehler, später mehr dazu.
1 | _interrupt(2) void External1IntHandler (void){ |
2 | |
3 | EA = 0; //Interrupts sperren |
4 | TR0 =0; |
5 | Z++; |
6 | TimerVal = TH0 << 8 | TL0; |
7 | LED = 0; |
8 | TL0=0x00; |
9 | TH0=0x00; |
10 | printf("\n\rTimerwert: %u",TimerVal); |
11 | EA = 1; |
12 | }
|
Pack mal die Ausgabe in die 2te ISR und disable weitere Interrupts, hierdurch gehen zwar Messungen verloren allerdings sollte die gültige Messung sauber in die Ausgabe passen. Main anpassen!! Die elegantere Lösung wäre ein RS FlipFlop, für nen paar Cent baust du dir ein RS FlipFLop, der erste Impuls steuert SET, der 2te RESET. Am Ausgang des FF erhältst du ein sauberes Signal. ___ | | ---- -------- Die steigende Flanke läßt den Timer loslaufen, die neg. Flanke löst den Interrupt aus (Timer Torzeitsteuerung, siehe Datenblatt). Ein Timer reicht für die Ganze Messaufgabe, die Messung ist präzise, Ausgabe und dann Messung wiederholen. Das wäre aus meiner Sicht der richtige Ansatz.
Noch mal zum Verständnis, die Impulslänge am Ausgang des FF entspricht somit genau der Differenz der beiden Signale. Alles klar ? In Main dann nur noch nen while (1);
Danke dir. was meinst du nochmal genau mit main anpassen? das printf rausnehmen ? werde das morgen mal ausprobieren. ist ein gutes Forum hier. Der ansatz mit dem Flip Flop hört sich noch viel besser an. aber ich schaue mal ob ich von der genauigkeit vieleicht auch so hinkomme. ansonsten werde ich es mal ausprobieren. DAnke nochmal super Forum hier
Tja macht aber genau daselbe wenn ich das so mache wie vorher. noch nen tip? kann ich die werte zwischenspeichern im array und dann ausgeben?
Irgendwie ist es schwer dir zu helfen, leider sagst du nie genau was ist. Mach doch mal folgendes, schmeiß mal alle deine Interrupts raus und dann frag doch einfach den PIN ab und starte bzw. stop den Timer.
1 | if (meinEingangEins) TR0 = 1; |
2 | if (meinEingangZwei) TR0 = 0; |
3 | printf("\n\rTimerwert: %u",TimerVal); |
So, was bezeichnest du als 100 Hz ? Du hast einen Timer als 16 BIT Zähler. Bei einer Frequenz von 22,1184 MHz / 12 = 1,843200 MHz. Wenn deine Signale nun exakt 1µSec. auseinanderliegen würden dann wäre das Ergebnis 1 bzw. bei 10 µSec. 18, bei 100µSec. 184 usw. Bei ca. 100 gehts dann nicht mehr ? Bedenke, ich habe nicht deine Hardware auf meinem Tisch, sei mal nen bischen kreativ.
glaub wir reden aneinander vorbei. Also habe auf dem einen pin ein signal liegen das 40khz hat und meinen timer starten soll auf dem anderen pin der meinen timer stoppen soll kann ich max mal ein signal mit 100hz anlegen bis mein hyper terminal keine ausgabe mehr macht. wenn ich über 100 Hz signal anlege dann hält mein Hyper terminal sofort an mit der Ausgabe. müsste aber 40khz anlegen können weil mein eigentliches Signal was ich an diesen pin anlegen will ja 40khz hat aber halt phasenverschoben ist. also zum Verständniss nochmal. pin 1 = 40khz Signal pin 2 = 40khz Signal phasenverschoben keine Ausgabe im Hyperterminal pin 1=40kHz Signal pin 2 = unter 100´Hz timer funktioniert so wie er soll mit Ausgabe im Hyperterminal.
Hallo ich bins nochmal. Also ich habe jetzt mein Programm mal trastisch reduziert um den Fehler zu finden warum es anhält im HTerminal. Habe beide Interrupts rausgemacht und einfach mal einen Timer 2 definiert der einfach eine Variable hochzählt im HTerminal. Dann habe ich mein 1. 40khz signal auf meinen /INT0 gelegt alles noch ok jetzt das 2. Signal 40kHz an meinen /INT1 und das hyperterminal fenster hält an. Wie kann das sein? ich mache ja noch nichts mit den Signalen? die werden ja nur angelegt und sonst passiert ja nicht damit. Im Configuration Wizart sind die INT1 und INT0 über den XBR1 = 0x14; belegt. Also mein Timer wird angehalten sobald ich an den INT1 mein Signal lege warum? habe mein verändertes Programm mal dran gehängt. aber wie gesagt ist nur ein timer der ne Variable hochzählt und ausgibt sonst nicht wenn ich den XBR1 einfach weglasse läuft alles. Bitte um Hilfe oder kennt jemand das Problem?
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.