Tach
Arbeite am Bau einer Wetterstation mit dem PIC16F877A. Ich will 3
Sensoren (Temperatur,Feuchte,Druck) mit I2C auslesen und dann über die
I/0 Pins auf dem LCD ausgeben. Ein einfaches Programm, welches etwas auf
das Display schreibt funktioniert. Doch sobald der I2C-Startbefehl
ausgeführt wird, geht nichts mehr. An was kann das liegen?
Display ist ein 20x4 mit HD44780 Controller
lg
>An was kann das liegen?
An dem Programm, an der Hardware oder an sonstwas. :-)
Vor allem beschreibe bitte Dein Problem detailliert.
Dann poste bitte, Schaltplan und Software.
Hilfreich ist auch der Artikel:
http://www.mikrocontroller.net/articles/Netiquette
Hallo,
weißt Du wo Dein Programm hängenbleibt?
Ich hatte mal ein ähnliches Problem, zufälligerweise ebenfalls bei einer
I2C-Kommunikation. Bei mir war es ein verstellter
Kommunikationsparameter (Busgeschwindigkeit). Dies hatte zur Folge, dass
im Unterprogramm zum Versenden der Daten in einer Endlosschleife auf ein
Flag gewartet wurde, dass aber nicht gekommen ist. Dieses Unterprogramm
war in einer I2C-Bibliothek, die ich bekommen habe.
Grüße,
Robert.
Jörg Esser schrieb:> Probier mal kleinere Abschlusswiderstände im 5V Teil. So 2k.
Hat leider nicht funktioniert
RobWa schrieb:> Hallo,> weißt Du wo Dein Programm hängenbleibt?> Ich hatte mal ein ähnliches Problem, zufälligerweise ebenfalls bei einer> I2C-Kommunikation. Bei mir war es ein verstellter> Kommunikationsparameter (Busgeschwindigkeit). Dies hatte zur Folge, dass> im Unterprogramm zum Versenden der Daten in einer Endlosschleife auf ein> Flag gewartet wurde, dass aber nicht gekommen ist. Dieses Unterprogramm> war in einer I2C-Bibliothek, die ich bekommen habe.
Ja laut Debugg wartet es so wie ich es intepretiere auf ein Flag und
bleibt hängen
Wie hast du das Problem gelöst?
Hi,
das ist zwar schon etwas länger her, aber ich glaube bei mir war das
globale Interruptflag gelöscht oder die Interrupt-Prioritätsstufe
deaktiviert. Dadurch wurde der zugehörige Interrupt vom I2C-Datenempfang
nicht ausgelöst in dem das Flag gesetzt wurde. In dem Fall entweder
schauen warum der Interrupt deaktiviert wurde oder sicherheitshalber vor
Eintritt in die kritische Funktion einfach wieder aktivieren.
HTH,
Robert.
Das er so lange auf ein Flag wartet sollte aber nur passieren wenn der
Bus ziemlich schlechte Signale führt. In einem meiner Projekte ist das
so und dort habe ich einen Timer eingebaut der bei überschreiten der
Wartezeit die Kommunikation von vorne startet. Allerdings sollte sowas
nicht die Regel sein. In deinem Fall würde ich mir die Signale mit nem
Oszi erstmal anschauen. Wenn du alles Freiluft und mit 100m Kabel und
mit 1Mhz Bustakt verdrahtet hast kann das natürlich schon eher
passieren. Aber das sieht meine Glaskugel leider nicht....
Hallo,
ein zweites Mal hatte ich so ein Problem als ich die Taktfrequenz des
Controllers zur Laufzeit geändert hatte. Dabei habe ich vergessen die
Timingparameter der I2C-Schnittstelle umzustellen. Das hat ebenfalls
dazu geführt, dass das erwartete Flag ausgeblieben ist.
BG,
Robert.
Jörg Esser schrieb:> Das er so lange auf ein Flag wartet sollte aber nur passieren wenn der> Bus ziemlich schlechte Signale führt. In einem meiner Projekte ist das> so und dort habe ich einen Timer eingebaut der bei überschreiten der> Wartezeit die Kommunikation von vorne startet. Allerdings sollte sowas> nicht die Regel sein. In deinem Fall würde ich mir die Signale mit nem> Oszi erstmal anschauen. Wenn du alles Freiluft und mit 100m Kabel und> mit 1Mhz Bustakt verdrahtet hast kann das natürlich schon eher> passieren. Aber das sieht meine Glaskugel leider nicht....
Das ganze ist auf einem Print mit Hauptsächlich SMD bauteilen :)
Ich werde mir das ganze am Montag nochmals genauer anschauen. Vielleicht
finde ich noch heraus wo der Hund begraben liegt.
Danke schonmal
Wer hat die Schaltung entworfen? Du?
Warum wird der 5V-Zweig des PCA9306 über einen 200k-Widerstand versorgt?
Was hast sich der Erfinder dabei gedacht?
Wenn man gewollte hätte, hätte man das ganze auch nur mit 3.3V aufbauen
können. Entweder wollte man nicht oder war zu doof dazu.
fchk
PS: Wenn ich nochmal auf den Plan schaue, fallen mir noch ein paar
weitere Fehler auf.
Frank K. schrieb:> Wer hat die Schaltung entworfen? Du?
Teilweise
Frank K. schrieb:> Warum wird der 5V-Zweig des PCA9306 über einen 200k-Widerstand versorgt?> Was hast sich der Erfinder dabei gedacht?
Habe ich so übernommen aus einem alten Projekt, welches nicht von mir
stammt.
Frank K. schrieb:> Wenn man gewollte hätte, hätte man das ganze auch nur mit 3.3V aufbauen> können. Entweder wollte man nicht oder war zu doof dazu.
Zu doof
Frank K. schrieb:> PS: Wenn ich nochmal auf den Plan schaue, fallen mir noch ein paar> weitere Fehler auf.
Raus damit, nehme Kritik gerne entgegen
Hab herausgefunden wo das Programm hängenbleibt. Und zwar beim Befehl:
while(!SSPIF);
da wartet er auf SSPIF, was nicht kommt..
Habe aber keine Ahnung woran das liegt
Gruss
Was ist i2c_init();?
Woher kommt es, was steht da drin?
Das selbe mit i2c_start();
Wo stellst du den Takt deines uC ein?
Welche I2C Geräte sind bisher am Bus angeschlossen? Alle? Kannst du Alle
bis auf den EEPROM mal weg lassen?
Hallo,
Adrian schrieb:> Hab herausgefunden wo das Programm hängenbleibt. Und zwar beim Befehl:> while(!SSPIF);>> da wartet er auf SSPIF, was nicht kommt..
hast Du schon überprüft ob Dein Interrupt an dieser Stelle aktiv ist?
Das sieht ziemlich gleich aus wie mein Problem, dass ich in meiner
Antwort vom 06.12.2013 16:26 beschrieben habe.
Grüße,
Robert.
RobWa schrieb:> hast Du schon überprüft ob Dein Interrupt an dieser Stelle aktiv ist?> Das sieht ziemlich gleich aus wie mein Problem, dass ich in meiner> Antwort vom 06.12.2013 16:26 beschrieben habe.>> Grüße,> Robert.
Seh ich das in den Special Function Registers? Wenn ja ist es da nicht
aufgeführt->nicht aktiv?
Ich kenn mich mit den PIC-µCs nicht so aus, aber kannst Du nicht einfach
den globalen Interrupt vor der Aktivierung des I2C-Transfers enablen?
z.B. durch die Funktion sei();
Da können Dir aber sicher PIC-Experten besser weiterhelfen.
Grüße,
Robert.
@Adrian:
Ich vermisse in Deiner Schaltung einen Kondensator an Pin 7 und 8 des
PCA9306. Das Datenblatt sagt bei den "Application Information": "A
filter capacitor on VREF2 is recommended."
Auch wenn das nur empfohlen ist, aber man kann es ja mal probieren ...
Gruß Dietrich
SSPIF wird unabhängig von Interrupts geschalten:
Datenblatt:
The following events will cause SSP Interrupt Flag bit,
SSPIF, to be set (SSP interrupt if enabled):
• Start condition
• Stop condition
• Data transfer byte transmitted/received
• Acknowledge transmit
• Repeated Start
Wo du einen Fehler hast, scheint in der Baudrate berechnung, die falsche
Werte liefert, siehe Datenblatt Seite 99. Nimm dort einen fertig
berechneten passenden Wert und teste es nochmal.
Wenn ich SDA und SCL vom PCA9306 trenne funktioniert es ^^. Folglich
müsste etwas mit der Verdrahtung des PCA9306 nicht stimmen oder am
3.3V-Pfad ist was faul. Sieht jemand den Fehler gerade auf Anhieb?
Schaue sicher Morgen weiter. Gibt nicht mehr soooo viele möglichkeiten.
Gruss
Adrian
Adrian schrieb:> Wenn ich SDA und SCL vom PCA9306 trenne funktioniert es ^^. Folglich> müsste etwas mit der Verdrahtung des PCA9306 nicht stimmen oder am> 3.3V-Pfad ist was faul. Sieht jemand den Fehler gerade auf Anhieb?> Schaue sicher Morgen weiter. Gibt nicht mehr soooo viele möglichkeiten.
Ja.
1. Überbrücke den 200k Widerstand
2. 100n zwischen 3.3V Pin und GND direkt am PCA9306
3. 100n zwischen 5V Pin und GND direkt am PCA9306
So, jetzt weiter:
4. Dein PIC hat zwei VCC-GND-Paare (11-12, 31-32) 100n zwischen jedes
Paar, und zwar direkt an die Pins.
5. Betrifft LCD: Die im 4-Bit Modus unbenutzten Datenleitungen D0..D3
offen lassen oder allenfalls über 10k an Ground oder VCC. Wenn Du vom
Display liest, leiden sonst die Ausgangstreiber.
6. Hänge die Datenleitungen zum Display nicht an RB4-RB7, sondern an RD0
bis RD3. Dadurch sparst Du Dir Schalter S1 und S2 und kannst problemlos
debuggen.
Zur Umrüstung auf reinen 3.3V Betrieb:
7. Ersetze den PIC16F877A durch einen PIC16LF877A und den Quarz durch
einen 10 MHz Quarz. Alternativ kannst Du auch einen ganz anderen PIC
einsetzen - ich würde da den PIC18F46K20 empfehlen. Der läuft auch bei
voller Taktrate mit 64 MHz bei 3.3V und braucht dafür einen 16MHz Quarz.
Die Pinbelegung ist weitgehend gleich.
8. PCA9306 entfernen, SCL1 und SCL2 brücken, SDA1 und SDA2 brücken,
Extra Pullups R4 und R5 entfernen.
9. Sicherstellen, dass das EEPROM eines für 3.3V ist (24C...: 5V
24LC...:3-5V 24AA...: 1.8-5V)
10. Alle Bausteine von der 5V-Versorgung auf die 3.3V Versorgung
umklemmen.
11. Die Textmodus-LCDs laufen fast alle auch mit 3.3V, brauchen dann
aber eine negative Kontrastspannung. Heißt also: Den GND-Pin des
Kontrastpotis musst Du auf etwa -3V legen, die Du Dir einfach mit einem
ICL7660 und zwei 10u X7R keramisch erzeugen kannst. Alternativ reicht
auch ein PWM-Ausgang und einige Dioden und Kondensatoren. Siehe
http://www.sprut.de/electronic/switch/minus.html
So, das wären meine Anmerkungen.
fchk