Hallo Zusammen,
eine kurze Frage:
Ist es möglich den unten stehende C code einfacher zu schreiben ?
Oder so zu schreiben das er schneller vom µC abgearbeitet werden kann?
in der Schleife soll perm. der IO Pin 6.0 abgefragt werden und nach
seinem Zustand (high / low) auf den IO Pin 1.2 gesetzt werden.
while(UCA1IFG == 0x02) // mache solange , bis was im rx Puffer ist
{
if (P6IN & (1 << 0)) // ist 6.0 high
{
P1OUT |= 0x04; // dann setze 1.2 auf high
}
else
{
P1OUT &=~ 0x04; // oder eben auf "low"
}
vielen Dank
newbi
In C kannst du nicht wissen wie schnell der Code abgearbeitet wird,
dafür bräuchstest du Assembler und wissen über die µC Type.
Vielleicht ist es schneller wenn du 3 while Schleifen hast und du somit
nur ein if und kein else hast.
Das setzen des Bits ist soweit richtig, du kannst das so machen und
musst nicht Toggeln.
ich will mich mit dem code (unter anderen) vorbereiten auf das nächste
Semester.
hab mir dazu in der uni eine Evalboard von Ti ausgeliehen mit einem
msp430f5506
@ Vlad Tepesch
ich will nicht toggeln, ich will den Zustand des pins 1.2 anhand des
Zustands von pin 6.0 setzen
@ HenningW
kannst du das mit den 3 while schleifen skizzieren ?
newbi schrieb:> ich will nicht toggeln, ich will den Zustand des pins 1.2 anhand des> Zustands von pin 6.0 setzen
oh, sorry, hab übersehen, dass das ein anderer Pin ist der Abgefragt
wird.
Tip:
wenn man portablen Code schreiben will, kapselt man Hardwarezugriffe.
Zb in eigene (inline) Funktionen.
Das hat den Vorteil, dass der Code auch viel verständlicher ist:
1
inlinevoidStatusLedEin()
2
{
3
P1OUT|=0x04;// dann setze 1.2 auf high
4
}
5
6
inlinevoidStatusLedAus()
7
{
8
P1OUT&=~0x04;// dann setze 1.2 auf high
9
}
10
11
inlineboolisActive()
12
{
13
returnP6IN&(1<<0);
14
}
15
16
17
...
18
if(isActive())
19
{
20
StatusLedEin();
21
}
22
else
23
{
24
StatusLedAus()// oder eben auf "low"
25
}
26
...
keine Angst, der Compiler optimiert das schon vernünftig
newbi schrieb:> Hallo Zusammen,>> eine kurze Frage:> Ist es möglich den unten stehende C code einfacher zu schreiben ?> Oder so zu schreiben das er schneller vom µC abgearbeitet werden kann?
Auf C Ebene ist das erst mal alles.
Jetzt kommt man in die Phase in der man sich die Frage stellt
* muss es schneller sein?
wie schnell bin ich überhaupt? Welche Vorgaben habe ich, wie schnell
ich sein muss?
* Was hat der Comiler da draus gemacht und habe ich alle meine
Compileroptionen bereits ausgeschöpft?
Ist zb der Optimizer eingeschaltet?
* Wie sieht der Assemblercode aus?
Gibt es im Assemblercode noch Verbesserungspotential und wenn ja
wie könnte ich das von C aus nutzen?
* Gehe ich die Sache vielleicht überhaupt falsch an?
Welche anderen Möglichkeiten gibt es diese Funktionalität zu
erreichen? Operationen aus der Schleife rausschaufeln? Interrupts
nutzen?
* Reissen alle Stricke und muss ich vielleicht überhaupt auf
Assembler ausweichen? Inline-Assembler?
vor while ersten zustand setzen
wenn erster zustand high
while(UCA1IFG == 0x02)
while(UCA1IFG == 0x02 && pin aktiv){}
if uca1fg == 2 pin low
while(UCA1IFG == 0x02 && pin aktiv){}
if uca1fg == 2 pin high
bei low analog dazu
Dann im Assemblercode prüfen obs mit weniger Takten abgearbeitet wird.
Du kommst für solche Optimierungen und Zeitkritischen Sachen nicht an
Assembler herum.
erstmal vielen Dank für die Tipps.
Ich arbeite mich seit einigen Tagen erstmal in C ein. Assembler ist mir
seit dem zwar schon einige Male über den Weg gelaufen, aber parallel
damit arbeiten und wirklich nutzen liegt noch in weiter ferne.
Wenn ich am Eingang (Pin 6.0 ) einen Taster anschließe und an Pin 1.2
eine LED an und aus mache, spielt Zeit eher eine Nebenrolle
Ich versuche über einen Tongenerator (LVTTL Signal ist eingstellt) eine
Frequenz bis 1MHZ einzuzspeisen und am Ausgang (Pin 1.2) zu messen.
Das klappt bis etwa 200 KHz
Testweise hatte ich vorher in der while Schleife den Ausgang getoggelt
da habe 2,4 MHz gemessen.
In den code Beispielen Von TI tauchte immer wieder das hoch setzen der
CLk bis 25 Mhz auf.
Wäre das nicht auch ein Lösung um mein Problem?
newbi schrieb:> In den code Beispielen Von TI tauchte immer wieder das hoch setzen der> CLk bis 25 Mhz auf.> Wäre das nicht auch ein Lösung um mein Problem?
Auch wenn TI das hin und wieder macht laeuft der uC ausserhalb seiner
Specs. Sowas macht man nicht weil es nicht garantiert ist das er das
unter allen Umstaenden (Temperatur , Spannung etc.) macht.
Die Beispiele von TI sind nicht das verbindliche Datenblatt und nur was
dort drin steht wird auch garantiert.
ok, vielen Dank, das eval board sollte ich nicht kaputt machen, sonst
gibts nen "duchgefallen" für die Prüfung und den Zorn des Profs. ;-)
Ich werde alle Vorschläge jetzt durcharbeiten.
vielen Dank an alle
newbi schrieb:> Oder so zu schreiben das er schneller vom µC abgearbeitet werden kann?
Wenn es schnell und unabhängig von Compilerumsetzung/-optimierungsstufe
sein soll, wäre Inline-Assembler wohl die richige Wahl.
1
$asm(...)
Die Details hängen von deinem Prozessor und eingesetzten Assember ab.
Falls du die Problem, dass du ohne C nicht hättest, unbedingt in C lösen
möchtest, solltest du einfach einen Blick in den erzeugten ASM-Code
werfen, um zu gucken, was noch optimiert werden kann und so lange am C
Code und der Oprimierung feilen, bis die gewünchte Assemblerzeile da
steht.
newbi schrieb:> ok, vielen Dank, das eval board sollte ich nicht kaputt machen, sonst> gibts nen "duchgefallen" für die Prüfung und den Zorn des Profs. ;-)
Kaputt geht er dabei nicht. Nur die Stabilitaet deines Programm laesst
dann zu wuenschen ueberig.
@newbi
Dein Codebeispiel ist gut so: Kurz und übersichtlich und der Compiler
hat die Möglichkeit, das optimal in Assambler umzusetzen. Ob er das
wirklich tut hängt vom Compiler und den eingestellten Optionen (z.B.
Optimierung) ab.
@HenningW
Die Version mit den While Schlaufen ist viel unübersichtlicher bzw.
schwerer durchschaubar, sowas würde ich nicht empfehlen! Ich bin mir
auch zimlich sicher, dass der Compiler dies weniger effizient übersetzen
wird...
Mag das jemand mal kompilieren? Hab gerade keinen Compiler zur Hand (vom
nicht vorhandenen Header für den TI ganz abgesehen).
Würde selbst aber auch die Methode von Vlad anwenden.
Grüße,
Edson
...ich sach nur: erzeugten asm-code anschauen und abchecken ob man nicht
evtl. in eine read-modify-write falle tappen kann, wenn das ganze 8-bit
port gesetzt wird und nicht das einzelne portpin...
Meister Eder schrieb im Beitrag #2310292:
> Das ist nur die halbe Lösung, weil das Bit im Ausgangsregister P1OUT nie> zurückgesetzt wird.
Verdammt du hast recht. Kleiner Denkfehler von mir.
1
while(UCA1IFG==0x02)// mache solange , bis was im rx Puffer ist
2
P1OUT=(P1OUT&0xFB)|(P6IN<<2)&0x04;
oder (wenn möglich)
1
intx=P1OUT&0xFB;
2
while(UCA1IFG==0x02)// mache solange , bis was im rx Puffer ist
Samuel K. schrieb:> Meister Eder schrieb im Beitrag #2310292:>> Das ist nur die halbe Lösung, weil das Bit im Ausgangsregister P1OUT nie>> zurückgesetzt wird.>> Verdammt du hast recht. Kleiner Denkfehler von mir.
Danke fürs zitieren. Hab meinen Beitrag vorhin "aus Versehen" wieder
gelöscht, wollte ihn eigentlich bearbeiten.
Deine Korrekturen passen, ich rate aber mal dass das Kompilat gegenüber
der Inline-Deklaration keine Vorteile hat (genau wie mein Beispiel).
Werds bei Zeiten mal prüfen.
einen Guten Morgen an alle
und erstmal vielen Dank für eure Hilfe.
Ich bin gestern all eure Vorschläge, Tips und Denkanstöße durchgegangen.
rausgekommen ist dabei, dass eine If Abfrage schneller ist als ein
ausrechnen
ala:
int x = P1OUT & 0xFB;
while(UCA1IFG == 0x02) // mache solange , bis was im rx Puffer ist
P1OUT = x | (P6IN << 2) & 0x04;
der Controller braucht zwischen -Signal am Eingang-( Pin 6.0) bis
-Signal am Ausgang ( Pin 1.2 ) bei If abfrage ca. 1 µs, bei ausrechnen
ca. 1,6 µs
@ Helmut Lenzen
Die kuerzeste Version der inneren "if" Abfrage:
mit IAR Compiler
// 142 if(P6IN & 1)
BIT.B #0x1, &0x34
JNC ??main_1
// 143 {
// 144 P1OUT |= 0x04;
BIS.B #0x4, &0x21
JMP ??main_2
// 145 } else
// 146 {
// 147 P1OUT &= 0x04;
??main_1:
AND.B #0x4, &0x21
// 148 }
??main_2:
Ich würde deinen/diesen Code gerne mal probieren, wie kann an ich ihn
benutzen/einfügen in meinen Code?
Ich benutze die IAR Kickstart.
Trotz all meiner Bemühungen gestern, schaffe ich es nicht das
Eingangssignal bis auf 1MHz "hoch zu drehen" und es so Fehlerfrei am
Ausgang zu messen.
z. Zeit ist die Grenze etwa 350 KHz.
Deshalb ist meine letzte Frage: Ist dies überhaupt möglich /
Softwareseitig möglich ?
(Wie oben schon geschreiben: es ist ein Evalboard von TI mit einem
f5506)
Ich möchte meine Helfer hier nicht von der wirklichen Arbeit abhalten
Gruß an alle
newbi schrieb:> Ich würde deinen/diesen Code gerne mal probieren, wie kann an ich ihn> benutzen/einfügen in meinen Code?> Ich benutze die IAR Kickstart.
Das ist das was der IAR Compiler daraus macht. Wenn du deinen C-Code mit
dem IAR Compiler uebersetzt hast sollte er das daraus gemacht haben. Du
kann es dir im C-Compiler Listing anschauen. Du must nur unter Options
das Assemblerlisting einschalten.
Helmut Lenzen schrieb:> Das ist das was der IAR Compiler daraus macht. Wenn du deinen C-Code mit> dem IAR Compiler uebersetzt hast sollte er das daraus gemacht haben. Du> kann es dir im C-Compiler Listing anschauen. Du must nur unter Options> das Assemblerlisting einschalten.
mein Sie Options --> links category "Assembler" und rechts tab "List"
und dort Haken bei "output list file" ?
wo befindedet sich das Assembler list file ?
newbi schrieb:> ok, vielen Dank, das eval board sollte ich nicht kaputt machen, sonst> gibts nen "duchgefallen" für die Prüfung und den Zorn des Profs. ;-)
Kauf dir halt das Launchpad für nen 5er. Da sind 2 kleine Prozessoren
dabei mit ähnlicher Architektur. Du kannst selber was basteln und wenn
ein Prozessor kaputt geht, geht ja immer noch der andere. Der Zorn des
Professors belibt dir erspart :)
Was auch bei MSP430 interessant ist, sind die Videos von Prof.
Lovisvcach, die aus hochschulinternen Praktika zur
Mikrocontrollerprogrammierung entstanden sind. Hier das erste:
http://www.youtube.com/watch?v=NKgXNXY9OSk
mfg mf
Es kann (theoretisch) auch billger sein den Pin einzulesen, zu maskieren
(verunden) zu schieben und dann wieder auszugeben (mit oder). Wenn
Sprünge auf dem µC teuer (langsam) sind kann dies beschleunigend wirken
(muss aber nich).
Auf dem AVR lohnt sichs z.B. nicht, da dort ein Sprung sehr schnell
geht, wie das beim MSP40 is weis ich nicht.
Max schrieb:> Auf dem AVR lohnt sichs z.B. nicht, da dort ein Sprung sehr schnell> geht, wie das beim MSP40 is weis ich nicht.
Definiere mal "sehr schnell". Es braucht mindestens 2 Zyklen, da erst
der Programcounter auf dem Stack gesichert wird und dann der
Programcounter mit der neuen Adresse geladen wird. Die Adressen sind
allerdings 16bit lang. Müsste man in der Auflistung der Befehle
nachsehen, zumal der AVR ja nur eine 8-Bit-Maschine ist(PC laden: atomic
Operation von 2x 8 Bit laden??).
Dann macht es ja noch einen Unterschied, ob "weit" oder "kurz"
gesprungen wird.
Beim MSP ist es, wie ich denke, anders. Der ist aber eine
16-Bit-Maschine. Es könnte u.U. schneller gehen.
mfg mf
Hi
>Es braucht mindestens 2 Zyklen, da erst>der Programcounter auf dem Stack gesichert wird und dann der>Programcounter mit der neuen Adresse geladen wird.
Du beschreibst einen 'call' keinen 'jmp'.
MfG Spess
Mini Float schrieb:> Definiere mal "sehr schnell". Es braucht mindestens 2 Zyklen, da erst> der Programcounter auf dem Stack gesichert wird und dann der> Programcounter mit der neuen Adresse geladen wird. Die Adressen sind> allerdings 16bit lang. Müsste man in der Auflistung der Befehle> nachsehen, zumal der AVR ja nur eine 8-Bit-Maschine ist(PC laden: atomic> Operation von 2x 8 Bit laden??).> Dann macht es ja noch einen Unterschied, ob "weit" oder "kurz"> gesprungen wird.
Bei AVRs braucht rjmp immer 2 Zyklen. Eigentlich braucht er nur einen,
das Problem ist aber, dass der AVR den nächsten Befehl immer vorraus
liest. Das funktioniert nach einem rjmp nicht und der µC braucht noch
einen Takt um diesen zu lesen.
Übrigens kann der avr auch 2 Register gleichzeitig kopieren (movw) und
braucht nur einen Takt, obwohl er ein 8bit µC ist.
Peter schrieb:> Das selbe kurz und genau so schnell:...
Ich dachte erst ich hätte dasselbe schon gestern gepostet. Mein
(Tipp-)Fehler, im True-Rückgabezweig des ternären Operators 0x04 statt
(P1OUT|0x04) zu schreiben.
Gruß,
Edson
Hallo Zusammen,
ich habe die letzte Zeit genutzt eure Vorschläge durch zuarbeiten und
habe richtig dazugelernt.
Vielen Dank dafür
Leider schaffe ich es nicht ein Eingangssignal(Pin 6.0) mit 1MHz auf den
Ausgang (Pin 1.2) zu "übergeben"
Ich habe auch schon ein TI samplescode genutz um die Frequenz auf 25 MHz
zu erhöhen.
Ich fragte zwar schonmal, aber ist mein Vorhaben überhaupt möglich ?
Den Ausgang mit 2,5 Mhz zu toggeln auf jeden Fall Ja.
Grüße
Hallo Zusammen,
ich arbeite immernoch an den Problem von oben.
Anstatt einer IF abfrage kann ich doch perm. den Zustand vom Eingang
setzen
so etwa:
bool r ;
while(1)
{
r = P6IN & BIT0; // 6.0 eingang
P5OUT = r & BIT1; // 5.1 ausgang
}
was ist daran falsch ?
newbi schrieb:> Ich fragte zwar schonmal, aber ist mein Vorhaben überhaupt möglich ?> Den Ausgang mit 2,5 Mhz zu toggeln auf jeden Fall Ja.
Du musst schauen was der Comüpiler aus deinem C-Code macht. Ich kann
jedoch nur Avrasm:
1
loop:
2
sbic PINA, B
3
rjmp h
4
cbi PORTD, A
5
sbic PINA, C
6
rjmp loop
7
rjmp end
8
h:
9
sbi PORTD, A
10
sbic PINA, C
11
rjmp loop
12
end:
worst case 8 Takte (optimierbar auf 7 mit out), das sollte dein MSP auch
schaffen.
Bin ich jetzt zu böld oder hab ich was verpasst?
/* P1_P2 als Ausgang konfigurieren */
DP1_P2 = 1;
<SCHLEIFE START>
/* aktuellen Zustand von P6_P0 auf P1_P2 setzen */
P1_P2 = P6_P0;
<SCHLEIFE ENDE>