Interrupts umbiegen scheint nicht zu funktionieren

Gast #2230909
Lesenswert?

Hallo zusammen,

versuche Interrupts die ich im Bootloader über:

GICR = _BV(IVCE);
GICR = _BV(IVSEL);

auf die Bootloadersection umbiege am Ende beim Sprung in die Anwendung 
nach Adresse 0x0000 wieder zurückzubiegen über:

GICR = _BV(IVCE);
GICR &= ~_BV(IVSEL);

Leider funktioniert das scheinbar nicht, da der Timer nicht läuft.

Ich nutze in beiden Sektionen einen Timer. Muss ich im Bootloader sonst 
noch etwas zurückbiegen bevor das funktioniert?

BOOTRST ist gesetzt.

Fuses: high: 0xff und low: 0xd8

Wenn ich das Anwendungsprogramm nicht per Bootloader flashe, dann 
funktioniert es.
Das Programm wird durch den Bootloader auch richtig geflashed, da es 
prinzipiell funktioniert. Displayausgaben funktionieren soweit. Nur wenn 
über Timer gesteuert etwas auf das Display ausgegeben wird funktioniert 
dies nicht.

Laut Docu müsste IVSEL alles sein um die Interrupts richtig zu biegen.

Was könnte da noch fehlen??

Mfg Tobi
Gast #2230929
Lesenswert?

1
void timer_init(void)
2
{
3
  global_Timer = 0;
4
  global_sec_Timer = 0;
5
    
6
  cli();    
7
  
8
  // Initialisierung:
9
  TCCR0 = (1<<CS00) | (1<<CS02) | (1<<WGM01);  // Prescaler von 1024 | CTC-Modus (siehe unten für Beschreibung)
10
  OCR0  = 53;                  // Vergleichswert (11059200 * 0,005s / 1024)-1
11
  TIMSK |= (1<<OCIE0);    // Interrupts aktivieren und damit Timer starten
12
  sei();
13

14
  return;
15
}

in beiden Fällen.. also Bootloader und Anwendung
Gast #2231168
Lesenswert?

hm.. also ich habe nun versucht das TIMSK Register vor dem Sprung nach 
0x0000 auf 0 zu setzen .. bewirkt aber auch nichts...
Ansich müsste der Timer doch einfach neu initialisiert werden mit der 
o.g. Routine.. aber irgendwas mit Timern / Interrupts muss da wohl noch 
falsch sein... ich komm nur nicht drauf...

Keiner ne Idee?
Gast #2231226
Lesenswert?

hm.... ok..

also
1
uint8_t tmp1 = GICR | _BV(IVCE);
2
uint8_t tmp2 = tmp1 & (~_BV(IVSEL));
3
GICR = tmp1;
4
GICR = tmp2;

oder direkt:
1
GICR = 1;
2
GICR = 3;


funktionieren beide nicht...

sollten doch nun aber innerhalb vire Zyklen passieren.. schneller kann 
ich das doch nicht mehr realisieren?!?

eigendlich solte doch sogar
1
GICR = _BV(IVCE);

reichen da damit doch auch IVSEL richtig gesetzt ist? geht aber auch 
nicht
Gast #2231248
Lesenswert?

Ja habs auch gerade gemerkt...

bei meinen "tmp1/2" versuchen habe ich nicht berücksichtigt, dass IVCE 
gleichzeitig wieder auf "0" geschrieben werden muss und bei meiner 
direkten zuweisung mit den Zahlen muss das natürlich ne 1 und dann ne 0 
sein... Denkfehler..

Jetzt gehts auch :)

danke für den Stups Stefan.
Da wäre ich, trotz dessen dass ich das Datenblatt gelesen hatte!! nicht 
so schnell drauf gekommen, da ich blind vermutete das meine 
ursprüngliche Variante
1
GICR = _BV(IVCE);
2
GICR &= ~_BV(IVSEL);

sicherlich innerhalb der 4 Zyklen sein sollte... Ist auch recht knapp 
bemessen diese Zeit..

Der Codeteil wäre sicher gut für inlien Assembler... wenn mans 
beherrschen würde :)
#2231254
Lesenswert?

Tobi schrieb:
> Da wäre ich, trotz dessen dass ich das Datenblatt gelesen hatte!! nicht
> so schnell drauf gekommen, da ich blind vermutete das meine
> ursprüngliche Variante
1
 GICR = _BV(IVCE);
2
 GICR &= ~_BV(IVSEL);
>
> sicherlich innerhalb der 4 Zyklen sein sollte...

Aber auch da ist der Knackpunkt nicht die 4 Zyklen, sondern die 
Tatsache, dass du in der 2. Zeile eine 1 nach IVCE schreibst.
Gast #2231264
Lesenswert?

hm.. jetzt wo dus sagst :)
Man sollte eben nicht immer allem was man aus dem Netz kopiert blind 
vertrauen :)

Also so funktionierts jetzt auch:
1
GICR = _BV(IVCE);
2
GICR &= ~(_BV(IVSEL)|_BV(IVCE));

Danke!

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