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
Könnte eine Variante der IO Speed Falle sein. http://www.sprut.de/electronic/pic/fallen/fallen.html#iospeed Dummerweise lesen die PIC 16 Bit-Befehle nicht das Latch sondern die 8 Pins.
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
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
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
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.
sorry, hatte was von pic24 gelesen. Es ist ein PIC16F887 Ja, entweder ein shadow register benutzen, welches dann auf PortC geschrieben wird, oder die Pinzuordnung und Programmierung durchdacht machen. Shadow register ist die manuelle Implementation eines LATx Registers. http://www.piclist.com/techref/readmodwrite.htm
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.