Forum: Mikrocontroller und Digitale Elektronik Probleme mit dem SAAB 80C535


von Andy (Gast)


Lesenswert?

      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

von Joe (Gast)


Lesenswert?

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.

von Andy (Gast)


Angehängte Dateien:

Lesenswert?

           Sorry, hier ist das programm das ich geschrieben habe.

von Peter D. (peda)


Lesenswert?

Ohgottogottogottogott,

Sourcen speichert man als *.C und nicht als *.DOC !!!!


Peter

von Andy (Gast)


Lesenswert?

    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.

von Peter D. (peda)


Lesenswert?

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

von Joe (Gast)


Lesenswert?

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

von Andy (Gast)


Angehängte Dateien:

Lesenswert?


     Hallo Leute,

jetzt habe ich geschafft das Programm zu kürzen und zu kompilieren. Ihr 
habt Recht wegen der Zeitopferung. Danke

von Andy (Gast)


Lesenswert?

      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

von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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.


von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

Ja, der 80535 ist abweichend, d.h. T2 kann keine Baudrate.

Aber da sollte ein extra Baudratengenerator drin sein, schau mal ins 
Datenblatt.


Peter

von Andy (Gast)


Lesenswert?

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.

................. :-((

von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Angehängte Dateien:

Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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.

von Andy (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.