Forum: Mikrocontroller und Digitale Elektronik 68HC908 Timer Problem


von Holger K. (zaldo)


Lesenswert?

Hallo zusammen!

Ich bastele gerade an meinem ersten "Projekt" mit einem Freescale 
MC68HC908 - einer Schrittmotorsteuerung für einen Drehteller - und hänge 
dabei nun an einem Problem mit dem TIM. Vorweg möchte ich sagen, dass 
meine Kenntnisse in C eher auf Anfängerniveau liegen, und ich bin 
überrascht und gleichzeitig ermutigt, weil das Ding überhaupt schon mal 
ansatzweise das tut was es soll.

Mein Problem ist folgendes: Da ich zum sanften beschleunigen und 
abbremsen des Motors ja noch einen Algorithmus benötige, habe ich 
begonnen mit unterschiedlichen Motor-Timings herumzuprobieren. Dazu habe 
ich ein stück Code geschrieben, welches den Motor zunächst 360° mit 
einer höheren Geschwindigkeit, und ohne Unterbrechung 360° mit einer 
mittleren Geschwindigkeit drehen soll. Das funktioniert soweit. Der Code 
schaut so aus:
1
TSC_TRST=1;
2
TSC_PS0=0;
3
TSC_PS1=1;
4
TSC_PS2=1;
5
6
TMODH=0x00;
7
TMODL=0x40;
8
            
9
for(test=0; test<3350; test++){
10
  TSC_TSTOP=0;
11
  MOTclk = !MOTclk;
12
  while (TSC_TOF == 0);
13
14
  TSC_TSTOP=1;
15
  TSC_TOF = 0;
16
}
17
18
TMODH=0x00;
19
TMODL=0x70;
20
            
21
for(test=0; test<3350; test++){
22
  TSC_TSTOP=0;
23
  MOTclk = !MOTclk;
24
  while (TSC_TOF == 0);
25
26
  TSC_TSTOP=1;
27
  TSC_TOF = 0;
28
}

Versuche ich es aber umgedreht, zuerst eine Drehung mit langsamer 
Geschwindigkeit (TMODL=0x90) und danach eine mit mittlerer 
Geschwindigkeit (TMODL=0X70) macht der Motor die erste Drehung, bleibt 
dann eine Sekunde stehen und führt dann erst die zweite Drehung aus. Die 
eine Sekunde hängt er dann in der zweiten for() Schleife bei der Zeile
1
while (TSC_TOF == 0);

Aber warum?
Und warum nur wenn er von einem längeren Timer zu einem kürzeren 
wechseln soll?

Vielleicht kennt sich jemand mit dem TIM aus, und kann mir das 
erklären?!

Danke im Voraus und beste Grüße
Holger

von Freescale (Gast)


Lesenswert?

Welchen Wert hat das Zählregister vorder zweiten for Schleife? ;-)

von Holger K. (zaldo)


Lesenswert?

Ausgehend von der Beschreibung, $0000

TIM Overflow Flag Bit
This read/write flag is set when the TIM counter resets to $0000 after 
reaching the modulo value programmed in the tin counter modulo 
registers.

von Holger K. (zaldo)


Lesenswert?

Es ist zum Mäuse melken, ich finde den Fehler einfach nicht. Ich hab das 
jetzt nochmal durchgerechnet (man möge mich korrigieren)

Fosc=12 MHz
Busclk=Fosc/4 = 3 MHz
Prescaler auf /64 = 46875 Hz
Entspricht 0,021333333334 ms

Wenn der Timer von $0090 bis $FFFF weiterläuft sind das 1,395 Sekunden, 
das würde in etwa mit der Stillstandzeit übereinstimmen. Es sieht so aus 
als ob das Zählregister einfach bis $FFFF durchrauschen würde, und dann 
erst das TOF-Flag setzt. Aber warum nur in diesem Fall? Innerhalb der 
Schleife funktioniert es doch auch.

Und von der Logik her erscheint mir der Ablauf richtig zu sein. In der 
letzten Schleife wurde der Timer gestoppt, das TOF zurückgesetzt. Das 
Zählregister sollte also bei $0000 stehen. Dann wird $0070 in das Modulo 
Register geladen und in der nächsten Schleife der Timer gestartet. Warum 
läuft er dann über die $0070 drüber ohne das TOF zu setzen, und warum 
nur dann, wenn im Modulo Register vorher ein größerer Wert als $0070 
stand? Hab ich da irgendwo einen groben Denkfehler?

von Holger K. (zaldo)


Lesenswert?

Hallöle,

ich habe das Timerproblem dahingehend "gelöst" das ich nun einen anderen 
Ansatz verwende. Das funktioniert soweit recht gut. Die Funktion 
delayus(parameter) wartet nun [parameter] µsek lang ab.
1
void delayus(delay){
2
  TSC_TRST=1;
3
  TMOD=(delay*3);
4
  TSC_TSTOP=0;
5
  while (TSC_TOF == 0);
6
  TSC_TSTOP=1;
7
  TSC_TOF = 0;
8
}


Nun wollte ich noch eine zweite Funktion schreiben, delayfrq(parameter). 
Diese sollte anhand einer übergebenen Frequenz (Parameter) die 
entsprechende Periodenlänge abwarten. Die Formel ist klar, t=1/f. Das 
Problem ist, dass hierbei naturgemäß meißt eine Zahl mit Nachkommastelle 
rauskommt. Ich bin nun ertsmal davon ausgegangen, das er beim Datentyp 
int die Nachkommastelle einfach fallen lässt. Zumindest warnt der 
Compiler davor C2705: Possible loss of data
1
void delayfrq(frq){
2
  int time;
3
  time=(1/frq)*1000000;
4
5
  TSC_TRST=1;
6
  TMOD=(time*3);
7
  TSC_TSTOP=0;
8
  while (TSC_TOF == 0);
9
  TSC_TSTOP=1;
10
  TSC_TOF = 0;
11
}

Allerdings stürzt der µC dann bei
1
TMOD=(time*3)
 stumpf ab (Ich habe probeweise einen statischen Wert verwendet (
1
TMOD=(3000*3);
), damit geht es, reagiert dann natürlich nicht auf den errechneten 
Wert, jedoch der Timer arbeitet korrekt.

Letztlich wollte ich time dann als float deklarieren und per round() 
runden. Ohne jetzt im Detail auf round() einzugehen habe ich bemerkt, 
dass sobald ich in der Funktion irgendeine beliebige float Variable 
definiere, das ganze versagt; der Timer anscheinend mit TMOD=1 abläuft, 
selbst wenn ich wie zuvor
1
TMOD=(3000*3);
 hart kodiert habe, und auch wenn die Variable nur deklariert, aber in 
der Funktion garnicht weiter genutzt wird.

Also bei folgendem Beispiel dreht sich der Motor:
1
void delayfrq(frq){
2
  int time;
3
  time=(1/frq)*1000000;
4
5
  TSC_TRST=1;
6
  TMOD=(3000*3);
7
  TSC_TSTOP=0;
8
  while (TSC_TOF == 0);
9
  TSC_TSTOP=1;
10
  TSC_TOF = 0;
11
}
12
13
for (test=0; test<1000; test++){
14
  delayfrq(440);
15
  MOTclk = !MOTclk;
16
}


während er bei diesem Code nur einen Wimpernschlag lang summt:

1
void delayfrq(frq){
2
  float time;
3
  time=(1/frq)*1000000;
4
5
  TSC_TRST=1;
6
  TMOD=(3000*3);
7
  TSC_TSTOP=0;
8
  while (TSC_TOF == 0);
9
  TSC_TSTOP=1;
10
  TSC_TOF = 0;
11
}
12
13
for (test=0; test<1000; test++){
14
  delayfrq(440);
15
  MOTclk = !MOTclk;
16
}

obwohl ich in beiden fällen einen statischen, hardcodierten Wert in TMOD 
lade, und nur die Deklaration von time eine andere ist.


Ich versteh's nicht?!

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.