Hi Leute,
ich hab mir ein kleines Programm geschrieben das mir den RMS über 8192
Werte in der Sekunde berechnen sollte.
Jetzt dauert die Berechnung insgesamt ca. 5 Sekunden ist das normal?
Also wenn ich die Wurzelfunktion draussen lass verändert sich nichts
spürbar, bei der Multiplikation gewinne ich ca. 2 Sekunden.
Der msp430 hat doch ein Hard. Multiplier das sollte doch raz faz gehen.
Ich seh jetzt nicht ganz den Zeitfresser?
Der Timer A3 hat ja eine niedrigere Priorität wie der ADC12, deshalb
arbeitet der auch alles ab was im ADC gemacht werden soll.
Bin etwas ratlos, kann mir vll. jemand ein tip geben woran das liegen
kann?
1
unsignedintRMS_SIG1;
2
unsignedlonglongintSUM_SIG1;
3
4
#pragma vector=TIMERA0_VECTOR
5
__interruptvoidTimer_A(void)
6
{
7
i++;
8
P4OUT^=0xFF;// Toggle P1.0
9
P6SEL|=0x70;// Enable A/D channel A0
10
ADC12CTL0=ADC12ON+SHT0_0+MSC;// Turn on ADC12, set sampling time
11
ADC12CTL1=SHP+CONSEQ_1;// Use sampling timer, set mode
Naja, die Frage ist, ob der Kompiler automatisch den HW-Mult
benutzt....das solltest du anhand des Assembler-Listings oder der
Kompiler-Optionen erst mal prüfen.
Das Teilen durch j ist natürlich auch ein Zeitfresser....
Fabian Hof schrieb:> Also wenn ich die Wurzelfunktion draussen lass verändert sich nichts> spürbar, bei der Multiplikation gewinne ich ca. 2 Sekunden.
?
Hast du den Optimizer eingeschaltet.
Das kann ich mir nur schwer vorstellen, dass tatsächlich das bischen
Rechnerei bei einem ADC Ergebnis so dermassen zeitbestimmend sein soll.
Hast du vielleicht noch andere, höher priorisierte Interrupts am laufen,
die dem ADC Interrupt keine oder kaum Rechenzeit übrig lassen?
Hi,
so hab mal bitshift reingemacht, hätte ich auch selber drauf kommen
können. Geht soweit auch ohne Probleme.
Zum Thema Hardware Multiplier, wenn mir einer genau sagt wie ich das
einstell bei der IAR Workbench mach ich das rein. Ich hab halt gelesen
das er den automatischbenutz sofern es möglich ist.
Hier mal der Assembler-COde für die Multiplikation
1
ADC_SIG1*=ADC_SIG1//Quadrat
2
3
mov.wR6,R12
4
mov.wR7,R13
5
mov.wR6,R14
6
mov.wR7,R15
7
call#?Mul32HW
8
mov.wR12,R6
9
mov.wR13,R7
Kommt mir komisch vor im Usergiude von TI zum F149 steht was von
1
16x16UnsignedMultiplyAccumulate
2
MOV#01234h,&MAC;Loadfirstoperand
3
MOV#05678h,&OP2;Load2ndoperand
davon ist nichts zu finden.
Zum Thema Interrupts:
Ich hab nur die beiden Interrupts die ihr oben in meinem ersten Poste
seht laufen. Also sollte mir da nicht reinhageln.
Thema Takt:
Also ich muss sagen da hab ich garnichts eingestellt, ich bin davon
ausgegangen, das er automatisch auf 5 Mhz läuft bzw.
Wie kann ich mir nochmal MCLK auf PIN5.4 anschauen?
Stimmt das so?
Sieht nach HW multiplizierer aus also, da hab ich kein Zweifel.
Kann ich mir in der IAR genau anzeigen lassen wieviel Zeit eine
Operation verschlingt? Dann könnte man das mal eingrenzen.
Beibt wohl nur noch den Takt Hochzusetzen auf 5 MHZ dann sollte ich
Faktor 3 gewinnen.
> unsigned long int MW_SIG1,ADC_SIG1;
eine 16-Bit MUL kann nur dann verwendet werden, wenn die Variable auch
16-Bit breit ist. Du definierst aber ADC_SIG1 als unsinged long.
>#?Mul32HW
Diese Routine steht in einer .lib. Die Quelle dürfte verborgen sein :-(
Wenn du am DCO nix änderst, läuft der mit irgendeiner Standard-Frequenz,
die im Datenblatt steht. Aber ADC Messungen mit dem DCO...naja, würd ich
nicht machen, das ist ein relativ instabilder RC-Oszillator. Wenn du die
Betriebsspannung auf 3,6V anhebst, kannst du einen 8MHz Quarz
anschließen. Bei 3,3V gehts bis 7,4MHz stabil.
Ansonsten scheint er ja den HW Mult zu benutzen.
Top! Hab jetzt mal sichergestellt das der CLock auf ~4.6Mhz und den ADC
betreib ich jetzt mit ADC12OSC, das sollte ja der maximale sein.
Aber mal eine Frage:
Wenn ich die MIttelwertbildung und das Wurzelziehen im Main mache sollte
ich doch keine Probleme bekommen, ausser natürlich das dauert länger als
das meine 8192 Abtastwerte voll sind oder?
Das hab ich jetzt mal so versucht, siehe Anhang.
Leider springt er mir die while nie wieder an ausser beim ersten Aufruf,
hat einer eine Idee warum?
Langsam krieg ich totes Hirn, für heute.
Wenn das long long genauso implementiert ist, wie beim AVR-GCC, dann ist
es schneckenlahm. Da ist sogar float noch besser.
Am besten, Du bastelst Dir das long long aus 2 uint32_t selber.
Peter
>Wenn das long long genauso implementiert ist, wie beim AVR-GCC, dann ist>es schneckenlahm. Da ist sogar float noch besser.
Darum geht es doch garnicht. Offensichtlich muß nur der ADC schneller
laufen, damit die CPU schneller rechnet :-)
Kann man leicht messen. Am Anfang der ISR ein Pin auf High setzen, am am
Ende auf LOW. Oszi dran, messen. Dann sieht man,
den Abstand der Pulse = ADC Wandlertakt.
Die Breite der Pulse. Rechenzeit in der ISR
Das Tastverhältnis = CPU -Auslastung
MfG
Falk
Der Hardwaremultiplizierer kann nur maximal 16 bit x 16 bit berechnen.
ADC_SIG1 ist unsigned long int und daher 32 bit breit (oder ist das beim
IAR Compiler anders?).
ADC_SIG1=ADC12MEM0;
ADC_SIG1*=ADC_SIG1; //Quadrat
SUM_SIG1=SUM_SIG1+ADC_SIG1; //Summe
Das würde ich so schreiben:
SUM_SIG1 += ADC12MEM0 * ADC12MEM0;
Was ist das eigentlich für eine umständliche Vorgehensweise mit dem i
und j? Letztenendes will man doch samples zählen, das macht man am
einfachsten direkt im ADC-Interrupt.
Wofür zählt j mit, der Wert, den es bei der Auswertung haben wird, ist
doch zur Compilezeit bekannt (8192)?
Grüße,
Peter
Hi tip von Stefan mit LPM0 deaktivieren hat gepasst.
Klar kann er auch 32 bit mit dem HW Multiplier machen nur nicht auf
einmal. Aber die ganze Sache läuft jetzt auch soweit so gut.
Peter das j war noch aus einer früheren Version, ist natürlich bekannt
und mitlerweile auch verschwunden.
Ausserdem sollte man ADC_SIG1=ADC12MEM0; und dann SUM_SIG1 += ADC_SIG1 *
ADC_SIG1; machen sonst kommt ein volatile warning.