Registerzuweisung bei PIC16F887

OP #2698018
Lesenswert?

Hallo,

ich komme aus der AVR Welt und möchte nun auch PIC Controller 
programmieren.
Nun wollte ich in dem PORTC Register eines PIC16F887 2 Bits mit dem Wert 
0 beschreiben.
Ich habe es folgendermaßen versucht:

PORTCbits.RC3 = 0;
PORTCbits.RC4 = 0;

oder ich habe versucht direkt zu adressieren:

RC3 = 0;
RC4 = 0;

Allerdings funktioniert dieses nicht. Einer der beiden Werte wird immer 
nicht übernommen.
Wenn ich die Zuweisung allerdings über das komplette Register durchführe 
funktioniert es problemlos.

PORTC = 0b11100111;

Was mache ich wohl falsch? Ich hatte gedacht, dass man beim PIC die Bits 
einzeln ansprechen kann und nicht wie beim AVR maskieren muss?!

Ich hoffe, de Informationen reichen aus um mir weiter zu helfen.
Vielen Dank schonmal!

MfG
Olli
Gast #2698034
Lesenswert?

Ich benutze zwar die PIC24xx aber

Oliver S. schrieb:
> PORTCbits.RC3 = 0;
> PORTCbits.RC4 = 0;
>
> oder ich habe versucht direkt zu adressieren:
>
> RC3 = 0;
> RC4 = 0;

Das ist das gleiche. In einem Headerfile wirst du sowas finden wie

#define RC3 PORTCbits.RC3

Oliver S. schrieb:
> Allerdings funktioniert dieses nicht. Einer der beiden Werte wird immer
> nicht übernommen.
> Wenn ich die Zuweisung allerdings über das komplette Register durchführe
> funktioniert es problemlos.

Das ändern von Bits in einem Port sollte man nicht hintereinander 
machen. Immer etwas anderes dazwischen, zur Not ein NOP. Ich weiß jetzt 
nicht, wie die Funktion für einen NOP beim Compiler für die die PIC16 
aussieht, mußt du mal nachsehen (nop() ?, _nop() ?, oder irgenwas mit 
__builtin ??).

MfG Klaus
OP #2700172
Lesenswert?

Hallo,

vielen Dank für die Antworten.
Leider habe ich es bislang noch nicht so hinbekommen wie ich es mir 
vorgestellt hatte.
Nun habe ich versucht die Bits im PORTC umzudrehen. Also:
1
PORTC &= ~(RC3);
2
PORTC &= ~(RC4);

Damit funktioniert das nun auch wohl, da die Register zu Beginn wohl mit 
1 initilaisiert werden.

Allerdings möchte ich gerne wissen warum das mit der Methode nicht 
funktioniert, die ich bereits gepostet habe.

Bisher versucht habe ich nun auch:
1
PORTCbits.RC3 = 0;
2
_nop();
3
_nop();
4
_nop();
5
_nop();
6
PORTCbits.RC4 = 0;

Allerdings funktioniert dieses aber nicht.
Eventuell hat jemand noch eine Idee wie man das richtig macht oder warum 
das bei mir nicht funktioniert.

MfG
Olli
OP #2700243
Lesenswert?

Hallo,

ich habe das Problem gefunden.
Die Ports sollten auf low geschaltet werden, obwohl die TRIS Bits dieser 
Ports auf 1 (also Eingänge) waren.
Dies ist nötig, da die Pins zuerst einmal Hochohmig sein sollen und 
später die externe Schaltung auf low ziehen.
Diese Vorgehensweise wollte wohl der Compiler (oder was auch immer) 
nicht so ganz unterstützen.
Nun habe ich die Pins zuerst als Ausgänge konfiguriert, sie dann auf low 
gezogen und danach die Pins wieder als Eingänge (hochohmig).
Zur Info: Ich verwende den Hi-Tech Compiler PICC.

Ich habe es nun folgendermaßen realisiert:
1
TRISCbits.TRISC3 = 0; //als Ausgänge setzen
2
TRISCbits.TRISC4 = 0;
3
  
4
PORTCbits.RC3 = 0; //Ausgänge auf Low
5
PORTCbits.RC4 = 0;
6
  
7
TRISCbits.TRISC3 = 1; //als Eingänge setzen
8
TRISCbits.TRISC4 = 1;

Eventuell hilft es irgendjemanden mal bei der Fehlersuche.

MfG
Olli
Gast #2700300
Lesenswert?

Das bringt dich auch nicht wirklich weiter, ein Write auf irgendein Bit 
im selben Port ändert es wieder auf high, mit hoher Sicherheit.

Beschreib das LATx Register, LATCbits.RC4 = 0; als Beispiel, wobei
auch hier dasselbe gilt, ein Write auf PortB ändert dir die Bits.
PORTx solltest du nur als readonly benutzen, zum write solltest du
ausschließlich LATx benutzen, das erspart dir viel Arger.
Aussnahmen gibt es immer, das ist jedoch die Regel.
Beim PORTx stimmt das sehr wohl wegen man sollte den Port nicht gleich 
hintereinander ändern, beim LATx besteht diese Limitierung nicht, für
das Lesen des Ports, also btfsx und Konsorten ist es egal.
#2701430
Lesenswert?

Hallo Oliver,

bei den "einfachen" PICs (so wie deinem)ohne LAT-Register für die 
I/O-Ports stolpern wohl die Meisten zu Anfang über dieses Problem.

Die gängigste Variante, die ich kenne und in diversen Programmen gesehen 
habe, ist, das Bitmuster für die Ausgänge eines Ports in einem anderen 
Register vorzuhalten. Alle Bitmanipulationen werden nur dort 
vorgenommen, und das gesamte Byte danach auf das Port-Register 
geschrieben. Damit umgeht man die Fallen (I/O-Speed, Read-Modify-Write).

HTH
Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren