Problem mit PIC-interrupts

OP #2425576
Lesenswert?

ich hab gerade mit der programmierung von einem PIC18F4550 begonnen.

IDE: mplab + proteus/isis
compiler: C18
vorkenntnisse: 8051, AVRs

ich bin durch ein wenig googeln nun darauf gekommen, dass der pic18f 
generell nur 2 interruptvektoren kennt, 0x08 für high priority und bei 
0x18 für high priority.
so gut so weit.

leider wird meine ISR (Timer1_ISR()) nie ausgeführt? code ist copypasta.

gibt es denn keine möglichkeit dem compiler zu sagen: die funktion soll 
meine timer1 isr sein? ausser über die flagunterscheidung.

der timer1 interrupt tritt jedenfalls auf, sagt isis (siehe screenshot). 
vielleicht kann man der simulation auch nicht ganz trauen.
1
//main insterrupt handler
2
#pragma interruptlow MainISR
3
void MainISR(void)
4
{
5
  Timer1_ISR();
6
}  
7

8
//high ISR routine
9
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
10
void ISR_high(void)
11
{
12
     _asm
13
       goto MainISR      // Sprung zur Interruptroutine
14
    _endasm
15
}  
16
//low ISR routine
17
#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
18
void ISR_low(void)
19
{
20
  _asm
21
       goto MainISR       // Sprung zur Interruptroutine
22
    _endasm
23
}
1
void InitializeRTC(void)
2
{
3
  T1CONbits.RD16 = 1;    //16 bit mode
4
  T1CONbits.T1CKPS1 = 1;  //prescaler: 1:8
5
  T1CONbits.T1CKPS0 = 1;
6
  T1CONbits.T1OSCEN = 1;  //enable oscillator circuit
7
  T1CONbits.TMR1CS = 0;  //use internal clock
8
  T1CONbits.T1SYNC = 0;  //synchronize timer with external clock
9
  
10
  TMR1L = 0x00;
11
  TMR1H = 0x00;
12
  
13
  T1CONbits.TMR1ON = 1;  //enable timer 1
14
}  
15

16
void Timer1_ISR(void)
17
{
18
  T1CONbits.TMR1ON = 0;  //disable timer 1
19
  PIR1bits.TMR1IF = 0;  //reset flag
20
  TMR1L = 0x00;    //reset timer registers
21
  TMR1H = 0x00;
22
  MAX7219_DisplayChar(3,'A');
23
  T1CONbits.TMR1ON = 1;  //enable timer 1
24
}
1
//initialize interrupts
2
void ConfigureInterrupts()
3
{
4
  RCONbits.IPEN = 0;    //no interrupt priority
5
  RCONbits.SBOREN = 0;  //no brownout detection
6
    
7
  //timer
8
  PIE1bits.TMR1IE = 1;    //enable timer 1 interrupt
9
  INTCONbits.GIE = 1;      //global interrupt enable
10
}
Angehängte Dateien:
Gast #2425614
Lesenswert?

Hallo Frank,


>>gibt es denn keine möglichkeit dem compiler zu sagen: die funktion soll
>>meine timer1 isr sein? ausser über die flagunterscheidung.

Nein. Ist halt so. Geh' halt in den Interrrupt-Handlern die jeweiligen 
Flags durch und gut.
In der Praxis wirst Du es ohnehin so gestaltem, daß Du das _wirklich_ 
zeitkritische in den Handler mit der hohen Prio legen wirst. Der Rest 
ist eh' egal. D kommt es auf die paar Zyklen zur Fallunterscheidung 
nicht an.

BTW: Wenn Du GENAUE Timerzyklen haben willst: Schalt' den Timer in der 
Interruptroutine nicht ab. Never. Einfach laufen lassen.

Schau Dir mal im Datenblatt die Interruptlogik an; Du musst noch 
Pheeripheral Interupts einschalten, dann sollte es funktionieren.

Viele Grüße,
Marcus
OP #2425663
Lesenswert?

Marcus schrieb:
> BTW: Wenn Du GENAUE Timerzyklen haben willst: Schalt' den Timer in der
> Interruptroutine nicht ab. Never. Einfach laufen lassen.

ja, eigentlich brauch ich sehr genaue timerzyklen da ich eine RTC 
implementieren will (mit quarz versteht sich)

damit das timerregister nach genau einer sekunde überläuft muss ich 
allerdings das high register bei jedem interrupt auf 0x80 setzen und das 
dürfte doch unvorhersehbare ergebnisse liefern wenn ich den timer 
weiterlaufen lasse?

oder ist das egal, wenn man davon ausgeht dass die ISR innerhalb von 255 
(also vor dem überlauf von low->high) abgeschlossen ist?

eine autoreload funktionalität scheint es ja nicht zu geben...

p.s.: was ist denn peripheral und was nicht?
Gast #2425676
Lesenswert?

>ja, eigentlich brauch ich sehr genaue timerzyklen da ich eine RTC
>implementieren will (mit quarz versteht sich)

Da wirst du mit Overflow aber nichts. Bei jedem Overflow
verlierst du Zeit. Nimm CCP.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren