Hallo,
möchte ich einen Pin auf 1 setzen so nutze ich:
PORTBbits.PB0 = 1;
das ganze funktioniert auch wenn ich es wieder auf 0 setzen möchte
PORTBbits.PB0 = 0;
Nur was geschieht hier im Hintergrund?
Beispiel:
Ich möchte Pin 1 am PORTB ein und ausschalten.
Das sind Bitfelder, die auf die Portregister gemappt sind. Mit
PORTBbits.PB0 = 1; setzt man in dem Bitfeld genau das Bit PB0 und damit
ein Bit im PORTB Register.
Mehr nicht.
Kann man sich im Header ansehen. In MPLABx retsklick -> jump to
declaration oder so.
Das ist um Längen lesbarer als der UND / ODER Kram.
Was der Compiler damit tut, weiß ich nicht.
Für den Anfang ist der Befehl LATB |= 0x01; vielleicht
etwas verwirrend für dich.
Wie würdest du denn nur die 3.LED leuchten lassen ?
Ist nicht LATB |= 0x03;
Das ist sicherlich auch eine Möglichkeit.
Hast du aber eine Dreifarbige LED dann bist du ständig dabei
LED_GREEN = 1;
LED_BLUE = 1;
LED_RED = 1;
LED_GREEN = 0;
LED_BLUE = 0;
LED_RED = 0;
jetzt bringen wir noch eine funktion für das blinken mit rein:
led_Flash(LED_GREEN | LED_BLUE);
oder zwei LEDs abschalten
led_Off(LED_GREEN | LED_BLUE);
klappt doch da wesentlich besser
Meine Idee wäre ja:
ob das so astrein ist?!
Simon schrieb:> Meine Idee wäre ja:> ob das so astrein ist?!
Deine Idee funktioniert nur dann, wenn alle LED am PORTB hängen. Der
darüber angegebene Code ist 100% unabhängig vom Pinning - man kann die
verschiedenen Ports beliebig mischen, so kann eine LED an PORTF sein,
die zweite an PORTB und so weiter.
Wie man den Status der LED an die Funktion übergibt, ja dafür gitbs
einen Million Möglichkeiten, angefangen von Boolschen Variablen bis hin
zu Strukturen.
Andererseits:
Wenn dir das mit den klassischen Bitmanipulationen gefällt: Es spricht
nichts dagegen.
PORTx sollte man bei Ausgängen eigentlich nie verwenden wenn es ein LATx
Register gibt!
Wenn man wissen möchte, was im Hintergrund geschieht, dann schaut man
einfach beim Debuggen in's Disassembly. (Breakpoint an der entsprechnden
Stelle setzen, Window|Debugging|Disassembly)
Simon schrieb:> Naja, nur du hast nur die Möglichkeit die daten von PORT zu lesen.
Michael hat sich extra die Mühe gemacht ein Datenblatt zu verlinken.
Schau doch bitte mal "Figure 10-1: Dedicated Port Structure Block
Diagram" an.
Simon schrieb:> Beim schreiben gibts vielleicht noch die option ob LAT oder PORT
Was beides das selbe bewirkt. Es wird immer ins Data Latch geschrieben.
(auch sehr schön im Bildchen zu erkennen)
Hallo Simon,
wenn du die Ports als ganzes liest/schreibst um einzelne Bit zu
bearbeiten, verzichtest du auf die BSET und BCLR Instructionen die es in
den PIC24 gibt.
zb: ein LATBbits.LATB4 = 1; // clock pin high
wird im Assemblerlisting zu
000E0A A882CC BSET LATB, #4
was genau ein opcode/fetch ist, also genau ein Wort im pic24, schon mal
platz im flash gespart.
Da es sogar nur einen Befehlszyklus baucht, ist es auch um einige Zyklen
schneller als die klassische Variante.
mfG
Peter ;-)
Peter C. schrieb:> Da es sogar nur einen Befehlszyklus baucht, ist es auch um einige Zyklen> schneller als die klassische Variante.
Falls die klassische Variante das mit dem Shift-Geraffel sein soll, dann
können das anscheinend auch einige Compiler optimal in bsf/bcf Befehle
übersetzen. Andere vermurksen sogar die Bitfeld Variante. Nachweise oder
Quellenangabe bleibe ich jetzt mal schuldig ;-)
Peter C. schrieb:> Da es sogar nur einen Befehlszyklus baucht, ist es auch um einige Zyklen> schneller als die klassische Variante.
Wer meint, die paar CPU-Zyklen sparen zu müssen, der ist bei PIC24
meiner Meinung nach falsch aufgehoben.
Für solche Projekte gibt es kleinere CPUs mit wenig Peripherie.
Ein PIC 24 hat nun aber viel Peripherie. Wenn man Ports schnell toggeln
muss (nur dann spielt sowas überheupt irgendeine Rolle!), dann sollte
man das einem Peripherieblock aufhalsen, nicht der CPU. Das ist nicht
nur viel schneller, sondern auch noch effiezienter - die CPU kann
derweil idlen sogar schlafen.
Bei ein paar LEDs (um die geht es hier!) spielt das gar keine Rolle. Die
Toggelt man alle paar 100 ms. Egal wie viele man hat, über 0,0x%
CPU-Last kommt man damit sowieso nie.
Und nein, eine PWM für LED macht nicht die CPU. Die macht der OC-Timer.
Während die CPU schläft. Zu einem winzigen Bruchteil des Stromverbrauchs
des Kerns.
Ich arbeite seit Jahren mit den Dingern, und die Pins die am schnellsten
vom der CPU getoggelt werden sind höchstens StatusLED - alle 250ms mal
was tun oder so. Alle anderen Geschichten machen die reichlich
vorhandenen Peripherieblöcke.
Hurra schrieb:> Ich arbeite seit Jahren mit den Dingern, und die Pins die am schnellsten> vom der CPU getoggelt werden sind höchstens StatusLED - alle 250ms mal> was tun oder so. Alle anderen Geschichten machen die reichlich> vorhandenen Peripherieblöcke.
Das ist eigentlich auch richtig. Aber zum Testen, zur Inbetriebnahme
mach ich vieles gern mal mit Bitbanging. Und wenn das dann gut und
schnell funktioniert, insbesondere mit den 70MHz der PIC24Exxx, bin ich
häufig zu faul das jetzt noch mal mit der eingebauten Peripherie zu
machen.
MfG Klaus
Klaus schrieb:> Das ist eigentlich auch richtig. Aber zum Testen, zur Inbetriebnahme> mach ich vieles gern mal mit Bitbanging. Und wenn das dann gut und> schnell funktioniert, insbesondere mit den 70MHz der PIC24Exxx, bin ich> häufig zu faul das jetzt noch mal mit der eingebauten Peripherie zu> machen.>> MfG Klaus
Dann braucht man sich um Effizienz aber wirklich keine Gedanken mehr zu
machen :-(
Nur: Der PIC24 ist eben ein Stromsparprozessor. Die Stärken des PIC24
sind ausgefeilte Stromsparmodi und viel Peripherie.
Bitbanging heißt damit, die Stärken zu ignoieren.
Übrig bleibt ein höchst mittelprächtiger Controller. Der Prozessorkern
ist nicht die starke Seite des PIC24.
Dann ist man mit einem CortexM0 mit wenigen Features beser bedient. Oder
einem PIC32 von mir aus.