Forum: Mikrocontroller und Digitale Elektronik XMEGA:Periodischer Interrupt funzt nicht


von Thomas (Gast)


Lesenswert?

Hallo,
versuche folgendermassen einen periodischen 1s interrupt zu generieren.
- Normaler Clock wie nach Aufstarten (2MHz).
- RTC auf internem 32768Hz mit 32x prescaler (1024Hz)
- Interrupt auf periodisch setzen (Period Register)
- Periode auf 1024
-> Logischerweise sollte das OVFIF nach 1s gesetzt werden, aber die 
Interrupt-Routine wird nicht aufgerufen.

Dadurch, dass ich den RTC-Clock auf den Ausgang PR0 setze kann ich den 
Clock messen, welcher 1024Hz clockt, das funktioniert also.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
ISR(RTC_OVF_vect) {
5
  PORTD.OUTTGL = 0x08;
6
}
7
8
int main(void) {
9
  PORTA_DIR = 0xFF;
10
  PORTC_DIR = 0xFF;
11
  PORTD_DIR = 0xFF;  
12
  PORTR_DIR = 0x03;  
13
  PORTA.OUT = 0x20;   // Reset control
14
  my_delay(500, 0, 0);
15
  PORTA.OUT = 0x00;   // End Reset control
16
17
//  cli();
18
  PMIC.CTRL = 0x07;                    // Enable all interrupt levels 
19
  CLK.RTCCTRL = (CLK_RTCSRC_RCOSC_gc | CLK_RTCEN_bm); // select 32768/32 int osc
20
  RTC.CTRL = RTC_PRESCALER_DIV1_gc;    // no prescaler
21
  RTC.PER = 0x0400;                    // Set the period for 1s (2^10)
22
  RTC.INTCTRL = RTC_OVFINTLVL_HI_gc;   // Enable of interrupt and set to level High        
23
  PORTCFG.CLKOUT = (PORTCFG_RTCCLKOUT_PR0_gc);  // RTC to Pin R0 
24
25
//  sei(); 
26
27
  while (1) {
28
    PORTD.OUT = 0x01;
29
    my_delay(300, 0, 0);
30
    PORTD.OUT = 0x02;
31
    my_delay(300, 0, 0);
32
  }
33
}

von MWS (Gast)


Lesenswert?

Warum ist das SEI(); auskommentiert?
Nur die Levels zu erlauben reicht nicht.

von Thomas (Gast)


Lesenswert?

Natürlich,
hab ich mal auskommentiert weil es vorher schon nicht gieng.
Danach hab ich die Levels enabled, aber das sei(); vergessen 
zurückzusetzen.
Das dumme ist auch, dass ich das schon mal wieder eingeschaltet hab aber 
mittlerweile hab ich's rausgefunden.
Der Interrupt währe aufgerufen worden, wenn ich lange genug gewartet 
hätte. Er wird nämlich im moment nur ca. alle 64s aufgerufen. Das 
heisst, er funktioniert, nur mit dem Counter stimmt noch was nicht. 
Zählt er vielleicht rückwärts?
Das werde ich wohl noch rausfinden.
Danke.

von Thomas (Gast)


Lesenswert?

Komisch,
der Interrupt scheint nur beim Overflow des ganzen Zählers auszulösen. 
Egal was ich ins period register schreibe es sind immer 64s. Dabei 
heisst es doch nach Datenblatt:
"PERL – Period Register Low
The PERH and PERL register pair represents the 16-bit value, PER. PER is 
constantly compared with the counter value
(CNT). A match will set OVFIF in the INTFLAGS register and clear CNT. "

von MWS (Gast)


Lesenswert?

Thomas schrieb:
> Komisch,
> der Interrupt scheint nur beim Overflow des ganzen Zählers auszulösen.

Das PER-Register wird Dir den Wert nicht annehmen.
Hier gibt's 'ne Appnote: http://www.atmel.com/images/doc8047.pdf

Zitat:
3.1.3 Change RTC period
1. Wait for SYNCBUSY flag to clear.
2. Write period value by writing to the PER registers.
3. Write either CNT or COMP register.

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.