Ok, also erst mal ein paar grundsätzlich Dinge:

Die I/O Pins sind in Ports organisiert. Diese belegen eine Position im Speicher und sind (theoretisch) so breit, wie der Datenbus des Rechners. Bei den PIC12, PIC16 und PIC18 also 8Bit ( dazu der XC8 ), bei den PIC24 und den dsPIC33 16Bit ( dazu der XC16 ) usw. Das "theoretisch" soll sagen, daß nicht in jedem Port alle Bits vorhanden sind.

Die Ports heißen PORTA, PORTB ... und können so direkt angesprochen werden.

PORTA = 0b101010;

Wenn man beim Projekt den richtigen Prozessor eingestellt hat, zieht xc.h die passenden Headerfiles an, damit PORTA auch an der Adresse landet, die zum Prozessor passt.

Eigentlich will man meist nicht einen Port sondern nur ein Bit in einem Port ansprechen. Auch dafür gibts Unterstützung in den Headerfile. Für jeden Port wie auch für jedes Special Function Register ist ein Bitfeld definiert, über das man Bits einzeln ansprechen kann. Bitfelder in C sind Structuren und werden wie solche angesprochen. Den Namen haben die Microchip-Leute so konstruiert: zuerst der Portname (oder das SFR) dann (kleingeschrieben) bits. Das ist der Structurname, danach folgt ein Punkt, wie in C üblich, und dann der Name des Bits oder Bitfelds.

Das klingt jetzt bestimmt sehr trocken, daher ein paar Beispiele:

PORTA = 0b10101010; // ganzen Port setzen

Wobei, es gibt Gründe, die ich jetzt hier nicht vertiefen will, nicht auf den Port sondern auf das Portlatch zu schreiben. Also

LATA = 0b10101010;

Und jetzt einzelne Bits:

LATAbits.LATA0 = 1; // Bit 0 von Porta bzw RA0 auf 1
TRISAbits.TRISA0 = 1; // RA0 auf Input
if ( PORTAbits.RA0 == 1) {....}

So läßt sich jedes Portbit einzeln steuern. Und die Headerfiles sorgen dafür, daß man nicht vorhandene Bits eines Ports garnicht erst ansprechen kann.

Damit man den Code besser mit der Hardware in Zusammenhang bringt, definiere ich mir meisst passende Namen.

#define LED_RED LATBbits.LATB3

Wenn jetzt noch die LED vom Port nach GND geht, kann ich im Programm einfach schreiben:

LED_RED = 1;

und sie geht an.

Diese Definition der Bitfelder gibt es für alle Register der PICs. Daher sind die Headerfile recht lang. Selbst für den simplen PIC16F1825 sind es über 7000 Zeilen, bei den großen wesentlich mehr. Hier noch ein Beispiel für ein Bitfeld mit Felder größer als ein Bit. CCP1CON ist ein Register aus dem PWM Controller

CCP1CONbits.CCP1M ist 4 Bits breit, CCP1CONbits.DC1B und CCP1CONbits.P1M jeweils 2 Bit. Die Bezeichnung CCP1CON und CCP1M findet man genauso im Datenblatt.

Man kann also schreiben

CCP1CONbits.CCP1M = 0b0100; // Capture mode: every falling edge

exakt wie es im Datenblatt steht.

Sorry, wenn das etwas lang geworden ist. Ich hoffe aber, es ist verständlich.

MfG Klebwax