Hallo Leute, ich habe festgestellt das ich ein kleines Problem habe. Ich habe die Aufgabe ein ADXL202JE Beschleunigungssensor mit einem 80C535 Mikroprozessor einzulessen. Das mache ich mit dem Timer 2 und dem Timer 1, weil de Timer 0 für die Baudrate der seriellen Schnittstelle schon benutzt wird. Und wenn ich die Achsen einzeln einlese (also nur die X Achse oder nur die Y Achse) geht das sehr gut. Aber jetzt wenn ich die zusammen einlessen will, dh erst die X Achse und dan die Y Achse gehts sehr schlecht da kommen immer die 3 oder 4 Werte als Unendlich raus. Könnte es sein das die zwei Timer zusammen nicht gehen können oder müssen?? Ich lese die werte mit der Capture Unit CC0 und CC1 ein und beim Timer 1 als "gated mode". Könnte mir vieleicht jemand helfen, ein Tipp oder eine Internet Seite, oder ein Beispielprogramm in C?? Bitte, bitte
Interrupts haben Prioritäten und da du kein Programm zur Verfügung stellst ist Hilfe nicht möglich. Beschreibe mal etwas ausführlicher was du wie machst.
Ohgottogottogottogott, Sourcen speichert man als *.C und nicht als *.DOC !!!! Peter
Das ist nur ein Teil des Programms. Nur das Teil mit dem einlesen und dem bearbeiten. Ich kann euch nicht das ganze geben. Das ist gegenüber meiner Firma wiederrechtlich. Und als *.C kann ich das nicht speichern weil das so nicht gehen kann.
Andy wrote: > > Das ist nur ein Teil des Programms. Nur das Teil mit dem einlesen > und dem bearbeiten. Ich kann euch nicht das ganze geben. Das ist > gegenüber meiner Firma wiederrechtlich. Und als *.C kann ich das nicht > speichern weil das so nicht gehen kann. Nun, ich will ja keine Hilfe, kann mir also völlig wurscht sein. Aber wenn Du Hilfe zu einer Software willst, mußt Du schon ein error- und warningfreies kompilierbares Programm schicken. Natürlich soll es nicht unnötig aufgebläht sein, sondern nur soviel Code, daß der Fehler immer noch auftritt. Die Firmengeheimnisse solltest Du daher rausnehmen, uns interessiert ja nur der Fehler. Und damit hast Du nämlich überhaupt erstmal die Gewißheit, daß der Fehler wirklich in dem geposteten Code liegt und nicht in den Firmengeheimnissen. Sehr oft wurde hier schon völlig unschuldiger Code gepostet und alle zerbrachen sich tagelang den Kopf, was daran wohl falsch sein könnte. Also den Code soweit wie möglich kürzen, dann nochmal testen, ob der Fehler immer noch drin ist und dann posten. Peter
> Ich kann euch nicht das ganze geben. Das ist gegenüber meiner Firma wiederrechtlich. Dafür habe ich vollstes Verständnis. > Und als *.C kann ich das nicht speichern weil das so nicht gehen kann. Den verstehe ich nicht. Aber mal im ernst, ab und zu nehme ich mir die Zeit hier Fragen zu beantworten und Hilfe zu leisten. Aber versetz dich mal in meine Lage, hättest du Lust bei diesem Ratespiel mitzumachen ?? Machs wie Peter es gesagt hat und dann sehen wir mal.
Hallo Leute, jetzt habe ich geschafft das Programm zu kürzen und zu kompilieren. Ihr habt Recht wegen der Zeitopferung. Danke
Der Fehler beim Programm ist jetzt das die Zwei Timer nicht zusammen gehen. Wenn ich die Achsen einzeln einlese (d.h die eine Achse wegkommentiere) gehts einwandfrei, aber sobald ich die zusammenstelle kommen die Werte entweder konstant oder verfälscht raus. Und bei einer Neigung von 180° oder 90° sind die Werte unendlich. Ich brauch Hilfe
Allgemein: Warumm nimmst Du int für Flags, da reicht doch dicke char oder noch besser bit. Wenn Du Variablen >1Byte in Interrupts und im Main zugreifst, mußt Du sie im Main atomar (unter Interruptsperre) zugreifen, sonst gibts Bytesalat. Wenn Du nen Timer schreibst, mußt Du ihn anhalten, sonst gibts Bytesalat. Wenn Du ihn liest, mußt Du ihn anhalten oder mit Trick 17 auslesen. Hast Du nen Ablaufplan für das Programm ? Oder erzähl mal was da und wie es gemessen wird (Zeiten, Frequenzen, welcher Wertbereich). Wenn Du was auskommentierst, mußt Du auch konkret sagen was. Üblicher Weise mit "#if 0" und "#endif" und Kommentar dazu, was es ändert. Peter
Was ich in diesem Programm mache ist nach dem Application Note vom Sensor beschrieben: http://www.analog.com/UploadedFiles/Application_Notes/320058905AN604.pdf Ich messe mit dem Timer 2 (CC0 und CC1) die X-Achse, und zwar mit dem CC1 (steigende Flanke) wird die Zeit T2 (das für beide Achsen gleich ist) gemessen und mit dem CC0 (zuerst steigende dann fallende Flanke) die Impulsbreite T1. Mit dem Timer 1 wird im "gated mode" automatisch die Impulsbreite gemessen. Wass im Programm abgeht ist folgendes: -beim drücken von "a" werden erstmal alle Register und Laufvariablen gelöscht und die Priorität der Interrupt erhöht -die Schleife " while (e <= 999) " ist da um 1000 Werte zu messen weil ich die ja als Array speichere und die sind nur 1000. -dan wird erst die Y-Achse gemessen mit dem Timer 1 -die 3 Schleifen "while (test_Y == 0)", "while (test_T2 == 0)" und "while (test_X == 0)" sind dazu da um zu überwachen das erst wenn die Interruptroutine zuende ist er die Schleife verlässt und nicht zwei Interrupt auf einmal kommen. -In den Interrupt Routinen werden erstmal die Timer gestoppt dan die Register eingelesen und dan die Routine verlassen. - als zweites wird die Periodendauer T2 für beide Achsen gemessen - als drittes wird die Impulsbreite T1 für dei X Achse gemessen - dann werden die Werte einfach in float umgewandelt : X = T1_X; // Dateikonvertierung in Gleitkommazahl Y = T1_Y; // für die Division Z = T2; weil sonst geht die Division nicht - dann werden die in den g Wert umgerechnet mit der Formel ausm Application Note : g = (T1/T2 - 50%)/12.5% - dann werden die ausgegeben Das Problem ist jetzt wenn ich beide Timer im Programm benutzte geht das nicht oder geht sehr schlecht (d.h Werte sind unkorekt), aber wenn ich eine Achse auskommentiere wie z.B: / //Mit dem Timer 1 wird die Impulsbreite für die Y-Achse gemessen. // while (test_Y == 0) { IE1 = 0; TMOD = TMOD | 0x90; TR1 = 1; EX1 = 1; } // //Timer 2 in "capture mode",bei CC1 wird die Zeit T2 für beide Achsen //messen. // while (test_T2 == 0) // Prüfen ob ISR nicht durchlaufen wurde { if (IEX4 == 1) // Wenn die positive Flanke erkannt wurde { IEX4 = 0; CCEN = 0x04; // CC1 capture on rising edge T2CON = 0x41; // startet der Timer 2 in "capture mode" //bei 1MHz EX4 = 1; // External interrupt enable for CC1 } } // // Timer 2 in "capture mode", bei CC0 wird die Impulsbreite für die X-Achse gemessen // /* while (test_X == 0) // Das ist auskommentiert { // d.h es wird nur die Y Achse eingelesen if (IEX3 == 1) { IEX3 = 0; CCEN = 0x01; // CC0 wird erst auf steigende Flanke gestellt T2CON = 0x01; // zur Impulserkennung und dann auf fallende um EX3 = 1; // den Impuls zu messen. } } */ // bis hier auskommentiert dann gehts einwandfrei aber nur eine Achse halt und ich muss beide messen wenn möglich im selben Lauf Der Prozessor läuft mit 12MHz d.h der Timer mit 1MHz Die Periodendauer der beiden Achsen ist (ungefähr) Konstant und hat den Wert um die 7230 (Dezimal) die anderen zwei Zeiten variiren von 1500 bis 4-5000 je nach Neigung. Dann kommt der BeschlWert so zwischen 2 und -2 g raus. Aber wenn die beiden Timer zusammmen funktioniren geht es nicht mehr , dann kommt nur Misst raus. Andy
Du hast da ne ziemlich verquere Logik zwischen den Interrupts und irgendwelchen Loops im Main. Versuch das mal aufzudröseln. Mach also die Messungen entweder nur in Interrupts oder nur im Main, aber nicht son Mischmasch. Ich seh da jedenfalls nicht durch. Und nimm für Flags bits und keine ints, das kostet nur unnötig Code und kann knirschen, wenns nicht atomar ist. Peter
Und wie macht man Bits deklarieren?? Das finde ich nirgends im Net Ich kann das nicht im main machen weil dieser Sensor eine zusatzoption ist an der Maschine. Der soll nicht immer eingelesen werden. Nur wenn man das will und wenn man "a" drückt. Die messungen sind doch in der Interruptroutine. Die werden im Programm dan nur noch verarbeitet.
Andy wrote: > Und wie macht man Bits deklarieren?? Das finde ich nirgends im Net Doch, auf der Keil-Webseite oder in Deine Keil C51 Handbuch. bit ist ein Typ wie char, int usw. > Ich kann das nicht im main machen weil dieser Sensor eine zusatzoption > ist an der Maschine. Der soll nicht immer eingelesen werden. Nur wenn > man das will und wenn man "a" drückt. > > Die messungen sind doch in der Interruptroutine. Die werden im Programm > dan nur noch verarbeitet. Ne, da wird irgendwie haufenweise enabled und disabled, gesetzt und gelöscht usw. Und dabei hast Du irgendwas verwuselt (sich widersprechende Sachen gemacht). Wenn Du mal ne Ablaufplan machst, könntest Du auch herausfinden was. Laß doch die Interrupts frei laufen und wennse was raushaben, wird das in ne Variable geschrieben und ein Flag gesetzt. Und solange das Flag gesetzt ist, wird kein neuer Wert geschrieben, damit die Werte konsistent bleiben. Und wenn das Main neue Werte haben will, löscht es das Flag, wartet, bis es wieder gesetzt ist und liest die Werte aus. Peter
Das mit dem Interrupts frei laufen lassen klappt irgendwie nicht. Der springt niemals in die Interruptroutine. Der macht das ganze Programm durchlaufen ohne einmal die Routine zu besuchen. Kann das mit der Priorität zusammenhängen ?? Danke für den Tipp mit dem bit, hab ein bisschen Platzt gespart.
Ich kenne mich mit dem T2 des 80535 nicht aus, da der abweichend zu sämtlichen anderen 8052-ern ist. Mein Vorschlag, den einen Eingang an INT0, den anderen an INT1 und dann abwechselnd mal T0 in Gate-Mode zur High-messsung und T1 zur Periodenmessung und dann umgekehrt. Peter
Timer 0 kann ich nicht nutzen der ist ja für die Baudrate der Schnittstelle. Sonst würde ich das schon längst gemacht haben. Aber ich finde nirgends ein Hinweiss über Timer 2 als Baudratengenerator, damit ich Timer davon erlöse. Aber wenn ich das noch richtig weis hat der Timer 2 keine interne Weiterleitung sondern wird nur als Prescaler für T1 und T0 benutzt, oder??
Ja, der 80535 ist abweichend, d.h. T2 kann keine Baudrate. Aber da sollte ein extra Baudratengenerator drin sein, schau mal ins Datenblatt. Peter
Ja hab den Baudratengenerator gefunden im Datenblatt. Aber wieder mal Pech, der Generator in sich ist der Timer 0, nur anders angesprochen. Habs versucht und wenn ich den Timer 0 dann anspreche geht gar nichts mehr. Das ist ja richtig Pech im Unglück. Da kommen Werte raus die kann man als Umsatzzahlen für Siemens annehmen. Und die Schnittstelle spinnt vollkommen. ................. :-((
Andy wrote: > Ja hab den Baudratengenerator gefunden im Datenblatt. Aber wieder mal > Pech, der Generator in sich ist der Timer 0, nur anders angesprochen. > Habs versucht und wenn ich den Timer 0 dann anspreche geht gar nichts > mehr. Ne, das glaub ich Dir nicht. Der Baudratengenerator ist definitiv extra. Da machst Du was in der Programmierung falsch. Wenn Du noch irgendwo nen Link zum Datenblatt dieses Oldies findest, könnt ich ja mal reingucken. Verwendet habe ich ihn noch nie. Peter
Link habe ich leider nicht ich habe die auch bekommen als pdf. Ich werde Dir den Dattenblatt als Anhang senden (oder brauchst Du den User's Manual ??) Aber ich werde wieter versuchen vieleicht habe ich ein Fehler im Code. Danke
Du könntest recht haben, ich sehe nirgends die Baudratenregister S0RELL (0AAh), S0RELH (0BAh). Ich hab nur ein 517 Manual, da stehen sie drin. Ist ja dann wirklich total blöd. Peter
Ich gebe Dir trotzdem noch den User's Manuall vieleicht steht da was drin was ich übersehen habe, oder nicht verstanden, aber der ist ganz kommisch, der Prozessor irgendwie. Die BAudratengenerator Kontrollbits sind nicht in diesem Seriell Channel control register sondern, eins im PCON und eins im ADCON. http://www.keil.com/dd/docs/datashts/infineon/80x515_um.pdf Andy
So, der Baudratengenerator is drin, aber nicht zugreifbar. Er ist fest auf 2500, d.h. bei 12MHz sind nur 4,8 oder 9,6kBaud möglich. Peter
D.h der ist unabhängig von dem Timer 0. Das ist egal weil ich brauch ja 9600. D.h ich kann jetzt en timer 0 erlössen. Aber ich habs versucht und der Spinnt einbischen. Ich versuche was anderes. Danke Andrei
Ohhh ich werde noch verückt mit diesem Sensor. Jetzt habe ich es endlich geschaft in zum laufen zu brigen und er misst mir nicht die Beschleunigung sondern die Drehung des Sensors zur Basisposition. Gibst da irgend so ein Trick das man anwenden muss oder eine Formel, oder muss man irgendwo 2 mal klopfen etc. Bitte rettet den Sensor den ich schmeiss in glich zum Fenster raus.
Ok ich hab jetzt die Strategie geandert. Ich habe jetzt die analogen Ausgänge eingelesen aber ich brauch jetzt ein Algoritmus um den digitalen Wert vom AD- Wandler in einem g-Wert umzuwandeln. Wer kann mir helfen. Google spuckt nur irrelevantz raus. Andy
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.