Hallo Zusammen
Ich habe heute mit dem PIC32 angefangen, habe schon mit PIC18 schöne
Erfolge erzielt.
Meine Frage was ist der Unterschied bei dem nachfolgenden Programmcode.
Der erste ist aus einem Demo des 32er Kit, wobei es mir nur um die IOs
geht, Port D.
**************************************************************
// configure IOPORTS PORTD.RD0, RD1 as outputs
// could also use mPORTDSetPinsDigitalOut(BIT_6 | BIT_7);
PORTSetPinsDigitalOut(IOPORT_D, BIT_0 | BIT_1);
// initialize the port pins states = output low
PORTClearBits(IOPORT_D, BIT_0 | BIT_1);
// PORTD.RD6, RD7 as inputs
// could also use mPORTDSetPinsDigitalIn(BIT_6 | BIT_7);
PORTSetPinsDigitalIn(IOPORT_D, BIT_6 | BIT_7);
while(1)
{
if(PORTDbits.RD6 == 0) // 0 = switch is pressed
{
PORTSetBits(IOPORT_D, BIT_0); // RED LED = on (same as
LATDSET = 0x0001)
if(last_sw_state == 1) // display a message only when
switch changes state
{
DBPRINTF("Switch SW1 has been pressed. \n");
last_sw_state = 0;
}
}
else // 1 = switch is not pressed
{
PORTClearBits(IOPORT_D, BIT_0); // RED LED = off (same as
LATDCLR = 0x0001)
if(last_sw_state == 0) // display a message only
when switch changes state
{
DBPRINTF("Switch SW1 has been released. \n");
last_sw_state = 1;
}
}
};
*******************************************************************
Diesen Code habe ich geschrieben so wie ich es eben vom PIC18 kenne.
Er ist um einiges einfacher und es werden die Ausgänge (Leds)
angesteuert und die gedrückte Taste erkannt, so wie oben.
*********************************************************************
#define Led0 LATDbits.LATD0
#define Led1 LATDbits.LATD1
#define Led2 LATDbits.LATD2
#define Taste0 PORTDbits.RD6
#define Taste1 PORTDbits.RD7
#define Taste2 PORTDbits.RD13
TRISD = 11111000;
if(Taste0 ==1){
Led0=1;
}
else{
Led0=0;
}
***************************************************
Bitte um eure Meinung. Danke.
Lg.
Johann K.
Klatec schrieb:> TRISD = 11111000;
Sollte das nicht 0b11111000 sein? Passt aber auch nicht auf Taste2?
Hast Du geprüft, ob die Led0=1 etc. "atomar" abgebildet werden?
("PIC32 LAT, TRIS and PORT operations are not atomic like with 24/33")
Ich verwende die LATxbits.y nicht, da der Code nicht so einfach mit
anderen Architekturen verwendet werden kann, sondern TRISxSET, CLR, INV
indirekt (in Makros verpackt). Das ist ein anderes Thema, die Frage ist,
ob bei den structs das auch auf SET/CLR/INV abgebildet wird.
Deine Initialsierung schlägt m. W. fehl, wenn es sich bei den Pins um
"analog pins" handelt. Eine einfache Zuweisung an TRIS reicht dann nicht
aus. Dann wird Dein "einfacher" Code etwas weniger einfach. Deshalb
finde ich den Ansatz "ohne Funktionen/Makros" nicht "zukunftssicher".
Deshalb meine Meinung: Weder Ansatz A noch Ansatz B (der erste bindet
unnötig an die Architektur).
Ich schreibe mir immer ein paar Makros für GPIO, weil mir die
Portabilität wichtig ist. Und damit Überraschungen wie mit den "analog
pins" den Quelltext nur an einer Stelle betreffen.
Hallo Roland
Hast natürlich recht es muss natürlich 0bxxx heißen, wundert mich warum
es keine Fehlermeldung gab.
Bei den analogen Eingängen verwende ich bei den PIC18 z.B.
ANCON0 = 0; //als Dig. IO verwendet
ANCON1 = 0; //als Dig. IO verwendet
Wenn ich es richtig verstanden habe ist meine Art der Programmierung nur
auf eine Art Controller anwendbar und wenn ich einen anderen verwenden
möchte müßte ich einige Arbeit aufwenden.
Die Unterschiede liegen im CPU-Kern. Bei PIC18/24 gibts extra
Bit-Setz/Lösch Befehle, die man auch auf die Portregister anwenden kann.
Bei PIC32 hat Microchip erstmals keinen eigenen Kern genommen, sondern
von MIPS einen zugekauft. Und der kann das so nicht. Da muss man das LAT
erst in ein CPU-Register laden, ein Bit löschen, und es dann wieder
zurückschreiben. Das sind also drei Befehle, die unterbrochen werden
können.
Um eine nicht-unterbrechbare, schnellere Variante zu bekommen, hat
Microchip neben den Port-Registern noch weitere Register hinzugefügt,
mit denen man mit einem einzigen Schreibbefehl Bits gezielt
setzen/löschen/invertieren kann. So etwas ähnliches gibts auch bei den
ARM Cortex Controllern.
Die Makros bzw Funktionen aus dem PIC32-Beispiel benutzen diese
Setz/Lösch-Register, und deswegen sollte man die auch benutzen. Ist
sicherer und im Falle der Makros (mPort....) auch schneller.
Beim Compiler ist auch der Quellcode der Bibliotheken dabei. Den kannst
Du Dir anschauen, um zu verstehen, was da passiert.
fchk
Klatec schrieb:> ANCON0 = 0; //als Dig. IO verwendet> ANCON1 = 0; //als Dig. IO verwendet
Ich finde es besser, wenn eben diese Zuweisung zusammen mit der
TRIS-Zuweisung in einer Funkion/Makro zusammengefasst sind, und nicht
"verstreut" im Hauptprogramm herumliegen. So wird es auch automatisch
wiederverwendet.
Klatec schrieb:> Wenn ich es richtig verstanden habe ist meine Art der Programmierung nur> auf eine Art Controller anwendbar und wenn ich einen anderen verwenden> möchte müßte ich einige Arbeit aufwenden.
Wenn der andere Controller nicht von Microchip kommt, dann meiner
Erfahrung nach: Eindeutig Ja. Denn die Wahrscheinlichkeit, dass diese
Zuweisungen irgendwie portabel sind, geht gegen null. Versuch' doch
einfach mal, dieses simple Programm zu portieren. Da ist nur "if" und
das "else" portabel ;-)
Die Frage ist, ob das für Dich relevant ist.
Ich hoffe ja immer noch, dass Microchip MIPS aufkauft.