Ich habe ein Problem mit dem LPC1768 Timer generell:
Ich habe den Timer so initialisiert, daß er jede milli Sekunde aufgerufen wird.
Im Timerinterrupt drehe ich lediglich ein Portbit um, damit ich mit dem Ossi messen kann ob das Timing stimmt.
Das Timiung stimmt absolut. Da ich das Portbit bei jedem Interrupt umdrehe XOR müste aber ein symetrisches Rechteck herauskommen.
Aber, es kommt eine 650 nano Sekunden Flanke gefolgt von dem Rest der gewünschten einen milli Sekunde heruas.
Ähnlich einer extrem schmalen PWM. Wenn ich die letzte blödsinnige Zeile x-- mit reinkompiliere geht es einwandfrei.
Wo ist denn da der Zusammenhang. Ich Suche schon den ganzen Tag.
Erstaunlich aber auch, wenn ich zuerst das Interrupt Bit MR0INT lösche und dann das Portbit umdrehe geht es auch ohne das
blödsinnige x--. Der Zusammenhang ist mir bisher nicht erklärlich.
ich kann aber statt x-- auch for (x=0; x < 100; x++) ; benutzen, dann geht es auch wieder richtig.
Der eigentliche Code scheint also keine Rolle zu speilen, Hauptsache da kommt noch was.
Ich kann das Interruptbit auch 2 mal löschen dann geht es auch wieder richtig.
Es sieht so aus, als wenn der Prozossor es nicht mag, wenn als letzte Aktion in der Interrupt Routine das entsprechende
Interruptbit gelöscht wird. Ich habe es auch mit den Timern 1 2 und 3 probiert, die verhalten sich alle gleich "falsch"
Steht ein Stück Progrmmcode hinter dem Löschen des Interruptbits ist alles in Ordnung.
Code:
int x;
void TMR3_IRQHandler (void)
{
LPC_FIO1PIN.value ^= 2; /* Portbit umdrehen (Oszilloskope Signal) */
LPC_T3IR.bits.MR0INT = 1; /* Interrupt Bit loeschen */
x--; /* voelliger Blödsinn, aber ohne geht es nicht richtg ??????? */
}
Ein bischen Google und das Problem wurde mir tatsächlich exakt so bestätigt.
Ganz egal ob NXP oder Analog Devices, der Cortex M3 Kern ist schuld. Das ist jetzt aber nicht negtiv gemeint.
Ein "DSB" Befehl "Data Synchronization Barrier" als letzter Befehl wirkt Wunder.
Hiermit wird sichergestellt, daß alle Speicherzugriffe komplett erledigt sind bevor ein neuer Befehl eingeleitet wird.
Also entweder das Interruptbit NICHT als LETZTES löschen dann z.B. mittels "DSB" Befehl dafür sorgen, das alles reibungslos abläuft.
Ich hätt mal vorher googlen sollen, aber dafür bin ich stolz es selbst gefunden zu haben.
Bei IAR Embedded Workbench kann ich den DSB Befehl in der C-Source-Datei so eingeben:
__asm("DSB"); /* Data Synchronization Barrier */
ein schönes Wochenende wünsche ich allen.
Siro
Lesezeichen