Forum: Mikrocontroller und Digitale Elektronik M16C timerA0 mit Interrupt


von luke (Gast)


Lesenswert?

Nabend.

Versuche den TimerA0 zu initialisieren samt seines Interrupts, doch 
irgendwie sehe ich nicht das erwartete Resultat..

Vielleicht fällt einem etwas auf..
Vielleicht habe ich etwas vergessen oder falsch gemacht.

Hier ein Ausschnitt:



#include "sfr245.h"
#pragma INTERRUPT /B TimerA0int


void initPort( void);
void initTimerA0( void);
void setTimerA0int( void);
void startTimerA0( void);
void blink( void);
void TimerA0int( void);

int x = 0;



void main(void)
{
  initPort();
  initTimerA0();
  setTimerA0int();
  startTimerA0();

  while(1){ asm("NOP"); }
}

void initPort( void)
{
  pd7 = 0xff;    // outputs
  p7  = 0xff;    // aus
}
void initTimerA0( void)
{
  ta0mr = 0x80;
  ta0   = 0xFFFF;
}
void setTimerA0int( void)
{
  asm("fclr i");
  ta0ic = 0x07;
  ir_ta0ic = 0;      // Interrupt request flag clear.
  asm("fset i");
}
void startTimerA0( void)
{

//  tabsr |= 0x01;
  ta0s = 1;        // start timer

}
void TimerA0int( void)
{
...
}
}


Zusätzlich steht in der sect30.inc:

.
...
  .glb  _TimerA0int
  .lword  _TimerA0int    ; vector 21  (for user) timer A0
...
.

von crazy horse (Gast)


Lesenswert?

ta0s = 1;      /* start flag     */

von crazy horse (Gast)


Lesenswert?

sorry, steht ja doch schon da.

von luke (Gast)


Lesenswert?

Jo, nixe zu entschuldigen..

Danke fürs Lesen.

Apropos..
Habe gelesen, dass sich ein Timer nicht simulieren lässt. Zum Beispiel 
mit dem Simulator der in HEW integriert ist..
Ist da was wahres dran?
Leider bin ich noch zu frisch in der Materie um das "alles" überblicken 
zu können und habs deswegen auch nicht ausprobiert.

Vielleicht fällt anderen Lesern noch was auf.

Grüße

von luke (Gast)


Lesenswert?

Aaach. Immer diese Eile.

Vielleicht sollte ich noch hinzufügen, dass der µC mit 16MHz läuft.
Mit tamr0 = 0x80; sollte der Timer alle 2µs runterzählen.
Wenn er also ein "volles" 16bit register "runterzählt" von 0xFFFF auf 
0x0, dann müsste es doch ca. 131ms dauern..
Es dürfte wohl nicht an meiner Ungeduld liegen, dass sich nichts tut.. 
Oder?

von Emil (Gast)


Lesenswert?

Hi,

also bei mir (M16C24 aka M30245) ist der Timer A0 auf Vector 20.
Laut Handbuch ist das bei allen M16C/20/60/Tiny gleich.

Hier mein Code - allerdings für A2:
ta2mr   = 0x80;        // use divider f/32
i    = TIMER_TICK_uS(1000);  //get interrupt each ms
ta2    = i;
ta2ic   = TIMER_TA2_PRIO;    // Interrupt priority
cpsrf  = 0;
ta2s   = 1;        // Start Timer

Ansonsten sieht dein Code richtig aus. Einzige Möglichkeiten aus meiner 
Sicht:
1. Int Vector falsch
2. Interrupts disabled (prüf mal das I flag vor deinem "ta0s = 1")
3. definition der Funktionsregister (ta2, ta2ic...) falsch

von luke (Gast)


Lesenswert?

Jetzt wo Du es erwähnst..
Ich bin heut schon auf einen Code gestoßen indem tatsächlich der TimerA0 
Interrupt der Nummer 20 zugeordnet war..

Hmm. Ich muss das testen, danke erstmal.

von luke (Gast)


Lesenswert?

Vielen Dank Emil.

Es lag zwar gleichzeitig noch an etwas anderem, aber Du hattest auch 
Recht.

Was mich wundert ist folgendes: (dieses .if 0) Nachdem ich es gelöscht 
habe läuft es, natürlich in Verbindung mit der Korrektur auf Vector 20. 
(danke nochmal)

    .section  vector,ROMDATA
    .org    _VECTOR_ADR_




.if 0
    .lword  dummy_int    ; vector  0  BRK
    .lword  dummy_int    ; vector  1
    .lword  dummy_int    ; vector  2
..
..
..

.endif


Was sollte dieses .if 0 da? Habt Ihr ne Ahnung?

Guten Abend

von crazy horse (Gast)


Lesenswert?

.glb    _uart1recint
.lword  _uart1recint  ; uart1 receive(for user)(vector 20)
.glb  _ta0int
.lword  _ta0int      ; TIMER A0 (for user)

hm, das hat funktioniert, muss also schon 21 sein

von luke (Gast)


Lesenswert?

Das ist eigenartig..

So sieht es aus bei mir:

..
..
.lword  dummy_int    ; vector 18  (for user) uart0 receive;;
.lword  dummy_int    ; vector 19  (for user) uart1 transmit
.glb  _TimerA0int
.lword  _TimerA0int    ; vector 20  (for user) uart1 receive
.lword  dummy_int    ; vector 21  (for user) timer A0
.lword  dummy_int    ; vector 22  (for user) timer A1
..
..

Und so klappt es auch, der Interrupt löst aus.


Wenn ich es wie folgt ändere: (gehts nicht)
..
..
.lword  dummy_int    ; vector 18  (for user) uart0 receive;;
.lword  dummy_int    ; vector 19  (for user) uart1 transmit
.lword  dummy_int               ; vector 20  (for user) uart1 receive
.glb  _TimerA0int
.lword  _TimerA0int    ; vector 21  (for user) timer A0
.lword  dummy_int    ; vector 22  (for user) timer A1
..
..

Schaut Euch mal die Kommentare an. Da ist doch was nicht konsistent..
Ich bin verwirrt, das File hat doch HEW erzeugt.
Habe ich womöglich einen falschen µC angegeben?

von luke (Gast)


Lesenswert?

Habe jetzt mit Hilfe des Datenblattes für die M30245 Group verifizieren 
können, dass unter anderem folgende Beziehungen bestehen:


TimerA0    20
TimerA1    5
TimerA2    7
TimerA3    23
TimerA4    25

Nun wird auch klar wieso mein Debugger nicht funktioniert hat :)

Guten Abend.

von ArthurDent (Gast)


Lesenswert?

Hallo *,

Das /B in #pragma INTERRUPT /B TimerA0int schaltet auf den 2. 
Registersatz im Controller um. Ich hoffe Du hast in Deiner ISR daran 
gedacht, das wieder abzuschalten. Soweit ich weiss, macht der Compiler 
das naemlich nicht selbststaendig.

von Walter F. (mrhanky)


Lesenswert?

Beim Verlassen der ISR wird unter anderem auch das Flag Register 
zurückgesichert. (Bit B wählt hier Bank0 oder 1 aus). Dadurch wird 
automatisch auf die vorherige (normalerweise Bank0) zurückgeschaltet.

Gruß,
Walter.

von ArthurDent (Gast)


Lesenswert?

@Walter Freywald

Jau, das habe ich jetzt auch kapiert :-)

So genau hatte ich mich mit dem REIT Befehl noch nicht 
auseinandergesetzt.

Danke !

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.