Hallo zusammen,
wir sind gerade dabei, uns in den 16FX / MB96340 von Fujitsu
einzuarbeiten und auch gleich eine Frage.
- Der Prozessor läuft bei 16MHz.
- Wir haben einen Reload-Timer (RLT1), der auf 12,5 uSekunden gesetzt
ist und einen Interrupt auslöst.
- Gleichzeitig haben wir einen Free-Running-Timer, den wir zur
Zeitmessung einsetzen (mit Überlauferkennung).
- Als dritten haben wir noch einen weiteren Reload-Timer (RLT0), der
ebenfalls einen Interrupt auslöst; RLT0 wird nur für UART-Ausgaben
benutzt und läuft alle 100ms.
In dem Interrupt von RLT1 wird als erstes eine Zeitmessung vorgenommen
(Zeit die seit dem letzen IRQ RLT1 verstrichen ist) - das Ergebnis wird
gespeichert und dann in RLT0 ausgegeben.
Soweit klappt´s ganz gut mit einigen kleinen Abweichungen bei der
Zeitmessung.
Ziel der Routine in RLT1 ist die generierung diverser PWM Signale mit
vorheriger Ansteuerung von bis zu 7 Latches - diese Sachen sind im
Moment noch NICHT implementiert. Es geht zunächst nur um ein Signal an
PDR07_P0. Aber aus diesem Grund ist der Vergleich "L0_P0_Cnt" drin.
Das zu erzeugende Signal ist im Moment auch egal (ebenfalls, dass es
sicherlich einfachere Möglichkeiten gibt PPG, etc.).
Meine Frage ist nun - wenn ich den mit "Block 1" (siehe unten)
gekennzeichneten Block nicht drin habe, bekomme ich als Ergebnis 12,5
uSekunden für das Aufruf-Intervall RLT1. Sobald Block 1 drin ist, jedoch
bereits 25 uSekunden.
Verbrauchen so wenige Befehle aus "Block 1" (1 Division, 2 Vergleiche,
1-2 Variablen setzen, Variable erhöhen und Portausgabe) bereits mehr als
12,5 uSekunden, so dass ein Interrupt "verschluckt" wird ???
Habe die Main.c auch mal angehängt.
Tut mir leid, es ist eher eine Grundsatzfrage - aber das sind die
wichtigsten ;-) Ich kann mir nicht vorstellen, dass der uC so viel Zeit
für so ein paar Befehle vernichtet !? Oder doch!?
Danke,
Sebastian
---
__interrupt void RLT1_LatchTimer_IRQ (void)
{
// Zeitintervall seit letzem Aufruf
FRT0_Count = TCDT0;
FRT0_ovl1_cnt_func = FRT0_ovl1_cnt; // Save current FRT value
Ticks=abs(FRT0_ovl1_cnt_func - FRT0_ovl1_cnt_old) * 0x10000UL +
FRT0_Count - FRT0_Count_old;
FRT0_ovl1_cnt_old = FRT0_ovl1_cnt_func; // Save current FRT value as
reference for next cycle
FRT0_Count_old = FRT0_Count;
flag_ticks_valid=1;
// ------------- BLOCK 1 START -------------
helper_RLT1 = 10000; // per Definition - "Teiler" 10 kHz
if (L0_P0_Cnt>=(helper_RLT1 / L0_P0_Hz)) {
// Zeit für einen Flankenwechsel
// bestehender Wert kann nicht ausgelesen werden, sonst
// würden wir den Wert aus dem letzten Latch bekommen!
if (L0_Memory.bit.P00 == 1) {
L0_Memory.bit.P00 = 0;
} else {
L0_Memory.bit.P00 = 1;
}
// Jetzt den Counter zurücksetzen
// geht beides, 1. "sauberer" (kein Überspringen möglich)
// 2. einfacher & schneller.
// L0_P0_Cnt=L0_P0_Cnt-(helper_RLT1 / L0_P0_Hz);
L0_P0_Cnt=0;
}
L0_P0_Cnt++;
// Daten anlegen
PDR07 = L0_Memory.byte;
// ------------- BLOCK 1 ENDE -------------
TMCSR1_UF = 0; // reset underflow interrupt request flag
return;
}
Hallo nochmal, hat niemand eine Idee ode einen Tip dazu ? Oder habe ich das ganze zu umständlich geschildert ? Grüße, Sebastian
Gast
#2393163
Hi, ich fürchte, die Long-Multiplikation verbraucht bereits viel Zeit. Du hast in deiner ISR rund 190 Zyklen bis zum nächsten IRQ Zeit. Bei einer Long-Multiplikation muß auf die interne Bibliothek zurückgegriffen werden, da die 16LX-CPU keine Instruktion dafür hat. Diese Funktion braucht rund 150 Zyklen. Kommt nun noch die Multiplikation im "Block 1" hinzu, war's das dann. 16 MHz sind halt nicht so ultra-flott. Gruß.
Hallo zusammen, ich habe mich heute nochmal an das Problem rangesetzt und versucht, das ganze zu lösen. Ist mir soweit auch gelungen, ich hätte nur ganz gerne Feedback, ob jemand in den Routinen noch Probleme und/oder Verbesserungsmöglichkeiten gibt. Ziel war, sowohl die 32bit Variable als auch die Multiplikation zu vermeiden:
1 | |
2 | |
Ich habe folgendes gemacht (Kommentare habe ich zum besseren Verständnis drin gelassen):
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
Gibt´s eine bessere Lösung und/oder Verbessungsvorschläge ? Danke, Sebastian
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.