www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik M16C62P Timer Interrupt


Autor: Lunarfur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bin absoluter Neuling was µCs angeht, und versuche anhand eines 
Evaluation Boards den M16C62P von Renesas kennen zu lernen.
Als IDE benutze ich den mitgelieferten HEW (4.02). Da die Anleitung vom 
EVB eher mager ist, versuche ich mich anhand des Tutorials von Prof. 
Brett Ninness (http://sigpromu.org/brett/elec3730/m16c_tut2.pdf) mit den 
verschiedenen Funktionen vertraut zu machen. (Habe nur port init 
verändert und die den Inhalt der if-schleife der interrupt fkt. 
verändert, da ich nur 4LEDs aber kein Display habe)
 Nachdem ich nun seit zwei Tagen keinen Timer Interrupt bekomme, frag 
ich mich, was ich falsch mache oder etwas vergesse:
ncrt30.a30 (Auszug)
mov.b  #03h,0ah  ;enable PRC1 and PRC0 bits
mov.b  #00h,04h  ;set processor mode 
mov.b  #08h,06h  ;set to no division mode on main clock
mov.b  #20h,07h  ;
mov.b  #00h,0ah  ;disable PRC1 and PRC0 bits
...
fset I
------
sample2.c
#pragma INTERRUPT TimerA0int
void TimerA0int(void)
{"lass LEDs an Port4 blinken"} //sind auch initialisiert
Timer initialisiert mit:
ta0mr = 0x80; //f32
ta0 = 0x7A11; //10Mhz-Quarz auf EVB -> soll 10Hz
ta0ic = 0x01; //priority lvl=1
tabsr |= 0x01; //starten

-> sect30.inc
.glb _TimerA0int
.lword _TimerA0int

Hab zusätzlich noch ein paar Ports (p4_0-p4_3) mit LEDs die bei 
interuppt blinken sollten.

Wenn ich debugge, ich hab ein Breakpoint in der Interrupt-Fkt., komme 
ich dort niemals hin..
Hab ich etwas wesentliches vergessen?

Dank im Voraus
Lunarfur

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Angaben zu Quellcode sind unzureichend. Insbesondere interessiert, 
wie die Datei sect30.inc aussieht - das ist die Datei, in der die 
Interruptvektor-Tabelle angelegt ist. Fehlt deine Interruptroutine dort, 
wird sie nie angesprungen (s. 2. Inserting an ISR into the Interrupt 
Vector Table im o.g. Tutorial)

Autor: Lunarfur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, erstmal danke für die Antwort. Hatte ich doch geschrieben:

> -> sect30.inc
> .glb _TimerA0int
> .lword _TimerA0int

um genau zu sein
.lword  dummy_int  ; vector 20  (for user) uart1 receive
.glb    _TimerA0int     ; declare reference for TimerA0int interrupt
.lword  _TimerA0int     ; vector 21  (for user) timer A0
;.lword  dummy_int  ; vector 21  (for user) timer A0

Habe das Forum nochmal durchsucht, aber auch der Zielprozessor ist 
korrekt ausgewählt.
Auch wenn ich nicht debugge, sondern flashe und dann resette passiert 
nichts.

Autor: Lunarfur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht nochmal genauer

In meiner C-Datei:
#include "sfr62p.h"

void main(void);
void initport(void);
void initTimerA0(void);
void startTimerA0(void);
void setTimerA0int(void);
void TimerA0int(void);

#pragma INTERRUPT TimerA0int //#pragma INTERRUPT -> use function as ISR (Interrup Service Routine)
void TimerA0int(void)
{
    static unsigned char one_hundred_msec_count = 0;
    static unsigned char seconds = 0;
    
    asm("fset I");  //enable interrupts
    
    one_hundred_msec_count++;
    if (one_hundred_msec_count > 9)
    { p4_1=(~p4_1);
    
        seconds++;
        switch(seconds){
            case 10: p4=0x00;
            break;
            case 9: p4=0x01;
            break;
            case 8: p4=0x02;
            break;
            case 7: p4=0x03;
            break;
            case 6: p4=0x05;
            break;
            case 5: p4=0x06;
            break;
            case 4: p4=0x07;
            break;
            case 3: p4=0x08;
            break;
            case 2: p4=0x0B;
            break;
            case 1: p4=0x0D;
            break;
            case 0: p4=0x0F;
            break;
            default:seconds=0;
            p4=0x0F;
         
        }
        one_hundred_msec_count = 0;
    }
}

void main(void)
{
    //initialise ports for LED
    initport();
    //init TimerA0, 
    asm("FCLR I");  //disable interrupts
    initTimerA0();
    //set timer interrupt 
    setTimerA0int();
    //start timer 
    startTimerA0();
    asm("FSET I"); //enable interrupt 
    //anything else
    while(1);  
    
}

void initport(void)
{
    int i;
    pd4=0xFF; //all lines = output
    p4=0x00; //all LEDs on (inverted logic)
    for(i=0;i<25000;i++); //wait to make visible for the eye
    p4=0xFF; //LEDs off
}

void initTimerA0(void)
{
    //select timer mode
    ta0mr = 0x80;           // XX?0 0000 (Hardware Manual, REJ09B0185-0241, p. 145)
                            // |||| |||+- timer operation mode select bit
                            // |||| ||+-- timer operation mode select bit
                            //            00:  timer mode
                            //            01:  event counter mode
                            //            10:  one-shot timer mode
                            //            11:  PWM mode
                            // |||| |+--- set MR0 = 0 in timer mode
                            // |||| +---- set MR1 = 0 in timer mode
                            // |||+------ MR2 must always be 0 in timer mode
                            // ||+------- MR3 ???
                            // |+-------- count source select bits:
                            // +--------- count source select bits:
                            //            00:  f1 or f2
                            //            01:  f8
                            //            10:  f32
                            //            11:  fc32
    ta0 = 0xFFFF;
    //ta0 = 0x7A11; //Divide Count Source by n+1 (Q1:10Mhz/32=312,5kHz) for T=100ms -> n=3124+1
}

void setTimerA0int(void)
{
    ta0ic = 0x01;           // ---- XXXX    (Hardware Manual, REJ09B0185-0241, p.111)
                            //      ||||
                            //      |||+-- Interupt priority level select bit
                            //      ||+--- Interupt priority level select bit
                            //      |+---- Interupt priority level select bit
                            //      |      000: Level 0 (interrupt disabled)
                            //      |      001: Level 1
                            //      |      010: Level 2
                            //      |      011: Level 3
                            //      |      100: Level 4
                            //      |      101: Level 5
                            //      |      110: Level 6
                            //      |      111: Level 7
                            //      +----- Interupt request bit 
                            //             0: Interrupt not requested
                            //             1: Interrupt requested
}

void startTimerA0(void)
{
    //Add Timer A0 to CounterStartFlag (OR!)
    tabsr |= 0x01;          // ---- XXXX XXXX    (Hardware Manual, REJ09B0185-0241, p.141)
                            //      |||| ||||
                            //      |||| |||+ Timer A0 Count Start Flag (0:Stop, 1:Start)
                            //      |||| ||+- Timer A1 Count Start Flag 
                            //      ...  .+-- Timer A2 ...
    //alternatively set single bit:
    //ta0s=1; // 1: start timer A0 (count flag)
}

ncrt0.a30
start:
;---------------------------------------------------------------------
; after reset,this program will start
;---------------------------------------------------------------------
    ldc      #istack_top,isp      ;set istack pointer
    mov.b    #03h,0ah                ;enable PRC1 and PRC0 bits (disable write protection)
    mov.b    #00h,04h        ;set processer mode 
    mov.b      #08h,06h            ;set to no division mode on main clock
    mov.b    #00h,0ah                ;enabele wirte protection

.if __STACKSIZE__ != 0
    ldc      #0080h,flg
    ldc      #stack_top,sp      ;set stack pointer 
.else
    ldc      #0000h,flg
.endif
    ldc      #data_SE_top,sb      ;set sb register 
    ldintb   #__VECTOR_ADR__

sect30.inc wie vorher beschrieben... (ohne if in der vector section)

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es muss sichergestellt sein, dass der Vektor in der Tabelle an der 
richtigen Position steht. In der ersten Fassung sah ich das nicht. Der 
zweite Ausschnitt sieht OK aus.

Vorsicht bei dem Flashen, wenn sec30.inc nicht 101%ig richtig ist. Ein 
Vektor zuviel drin z.B. durch ein vergessenes Auskommentieren des 
entsprechenden dummy_ints und man kann sich aus dem M16C (und R8C) 
aussperren.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In dem ausführlichen Code sehe ich keine Probleme. Bin ratlos.

Autor: Lunarfur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das flashen geht, was ich daran sehe, dass er nach einem Reset die LEDSs 
kurz aufblinke lässt, also initport() wird auf jeden Fall ausgeführt.

Autor: Lunarfur (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß nicht woran es jetzt liegt, aber es funktioniert, nachdem ich 
ein Demo-Programm geladen habe, jetzt geht auch mein Code.
Was ich beim weiteren Stöbern gelernt habe, und evtl. anderen helfen 
kann:
Vergesst nicht den Assemblerbefehl fset I um das Interrupt Flag zu 
setzen.

Woran es auch gelegen haben könnte: Denkt bei der Einrichtung des 
Prozessormodes sowie der System Clock, dass das jeweilige Protection Bit 
auf 1 gesetzt wird, bevor ihr die Register setzt, sonst könnte es sein, 
dass ihr mit dem default nur 1/8 der CPU-Frequenz arbeitet und unter 
Umständen einfach nur auf das Interrupt so lange warten müsst.

Grüße
Lunarfur

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.