Guten Tag,
im moment Arbeite ich an einem Projekt der Schule über I²C.
Der kontroller ist der wie im Titel genannte PIC16F887 und befindet sich
auf der MC2V0 Hardware der IHK.
Link zum Datenblatt
http://www.stuttgart.ihk24.de/linkableblob/sihk24/aus_und_weiterbildung/pal/Elektroberufe/Standardbereitstellungsunterlagen/962276/.5./data/3190_B0-data.pdf
Die Aufgabe ist über I²C von einem DS1621, die Temperatur auszulesen und
an den 8 LEDs auf der Frontplatte des MC2V0 einschubs Binär
darzustellen.
Ich habe schonmal mit dem PIC16F887 und seinem I²C Interface gearbeitet,
allerdings scheint die Platine die benutzung des Interfaces zu
verhindern. Da der Bus nur an mit dem DS1621 verbunden ist und keine
anderen Daten darüber übermittelt werden, habe ich mir ein "eigenes" I²C
Protokoll zusammen getackert, allerdings kann ich an den zwei I²C Pins
(RC3 und RC4) keine Spannungsänderung messen. Oder besser gesagt keine
Spannungsänderung die mir die Funktion meiner Programmierung
bestätigt...
Meinen aktuellen Quellcode könnt ihr dem Anhang entnehmen.
Ich Arbeite mit MPLAB X IDE 1.70 und dem HiTech Compiler.
Ich bin mit meinem Latein so gut wie am Ende. Das letztemal als ich den
PIC für eine I²C Funktion programmiert habe gab es keinerlei Probleme.
Vielen dank für eure Hilfe
J. Bier
Guten Morgen,
hat keiner eine idee?
Ich kann verstehen das sich keiner für mich in die Hardware von der
MC2V0 Platine einarbeiten will, aber könntet ihr mal schauen ob mein I²C
Protokoll funktionieren müsste?
Ich habe leider keinen anderen I²C Baustein den ich mit einem leichter
zu bedienenden PIC ansteuern könnte. Wenn ich weis das wenigstens das
Funktioniert, wäre ich schonmal einen großen Schritt weiter.
mit freundlichen Grüßen
J. Bier
Hm, also entweder bin ich blind, oder du initialisierst deinen I2C
überhaupt nicht.
Wo werden die Register SSPCONx usw. Initialisiert?
Kannst ja mal im Datenblatt nach:
MASTER SYNCHRONOUS
SERIAL PORT (MSSP)
MODULE
suchen.. Kapitel 13 bei dem Offiziellen Datasheet von Mircochip. Hab mir
deine Software sonst noch nich gross angeschaut, ist es Absicht dass du
die weggelassen hast?
Guten Tag,
nein mach ich auch nicht. Den versuch mit dem I²C Interface zu arbeiten
habe ich Aufgegeben. Das Problem ist das der PIC auf der MC2Vo Platine
mit einem Bus für alle Geräte arbeitet. Das Problem ist damit ich Daten
auf den LEDs ausgeben kann, muss ich die Daten auf PORTC schreiben. Auf
diesem liegt aber auch der I²C Bus und deswegen muss ich ihn Anschalten,
einmal Datenabrufen und danach wieder Ausschalten.
Ich habe ewig daran rumgebastelt und konnte nichtmal Registrieren, dass
das Interface eine Start-condition einleitet. Deswegen habe ich mir das
Interface selbst geschrieben. Ich weis es ist unschön und unterstützt
auch viele Standards nicht, aber an dem Bus ist eh nur der eine
Sensor...
mit freundlichen Grüßen
J. Bier
So ein Interface selbst zu schreiben ist zwar nicht unmöglich,
allerdings schon kompliziert. Hut ab, dass du es immerhin versuchst.
Bier schrieb:> Ich habe ewig daran rumgebastelt und konnte nichtmal Registrieren, dass> das Interface eine Start-condition einleitet.
Lag wohl an einer Fehlerhaften Initialisation. Das müsste theoretisch
einwandfrei Funktionieren und damit wärst du dann auch auf der sicheren
Seite. Bei deinem Code ist das Problem, dass du dir selbst mehr
Fehlerquellen einbaust, indem durch den selbstgeschriebenen Code noch
mehr Punkte dazu kommen, an denen man nicht 100 % sicher sein kann, ob
sie funktionieren. Oder anders ausgedrückt: Du verzichtest auf Dinge,
welche zu 100 % funktionieren würden und bastelst stattdessen selbst
etwas, ob das so schlau ist ... naja, jedem selbst überlassen.
Dann ne kleine Frage (leider schon etwas eingerostet im Programmieren,
aber evt. ists ja trotzdem was)
Wenn ich das richitg verstanden habe, versuchst du beispielsweise in der
Funktion I2C_Stop ein Ack zu senden.
Schaut man sich das ganze mal an:
1
voidI2C_Stop(void)
2
{
3
//Acknowledge Send
4
SDADir=1;
5
6
__delay_ms(100);
7
SDA=1;
8
__delay_ms(100);
9
SCL=1;
10
__delay_ms(100);
11
SCL=0;
12
__delay_ms(100);
13
SDA=0;
14
__delay_ms(100);
15
SCL=1;
16
__delay_ms(100);
17
SDA=1;
18
}
1
//Acknowledge Send
2
SDADir=1;
Sicher, dass dieses SDADir stimmt?
1
#define SDADir TRISCbits.TRISC4
und eine 1 auf einem TRISx Bit steht doch eher für einen Eingang, oder
ahbe ich da etwas falsches in Erinnerung?
Sogesehen versuchst du also einen Eingang zu schalten, was nicht möglich
ist. Könnte das ein Fehler sein?
Wie gesagt, schon länegr nicht mehr Programmiert und eher unsicher,
vielleicht übersehe ich da auch etwas..
Guten Tag,
ja mach ich direkt am PIC... deswegen wundert es mich auch so. Es ist
als ob das Compilierte Programm etwas anderes macht als das
geschriebene. Alte Projekte funktionieren auf diesem jedoch einwandfrei.
Was natürlich auch noch ein Problem sein könnte ist, dass ich die
ansteuerung der Latches Falsch mache. Mittlerweile kenne ich die
Datenblätter von diesen fast Auswenig.
mit freundlichen Grüßen
J. Bier
Helper schrieb:> und eine 1 auf einem TRISx Bit steht doch eher für einen Eingang, oder> ahbe ich da etwas falsches in Erinnerung?
Absolut korrekt.
Helper schrieb:> Sogesehen versuchst du also einen Eingang zu schalten, was nicht möglich> ist.
In der Tat, sieht zumindst so aus nach kurzen Überfliegen des von dir
geposteten Ausschnitt aus dem Code. Weiter hab ich ihn nicht angeschaut.
Kann aber deine Aussage nur bestätigen.
Guten Tag Helper,
vielen Dank. Das ist mir noch nicht aufgefallen. Ich glaub ich seh' bald
den Wald vor leuter Beumen nicht mehr. Werds gleich mal versuchen.
mit freundlichen Grüßen
J. Bier
I2c kannst du auch mit Software machen.
Code fuer 16F5x habe ich moeglicherweise auf meinem Laptop.
einfach genau nach der Spezifikation programmieren, mehrmals genau
durchlesen, und Tristate richtig setzen.
Die Geschwindigkeit von 100 Kbps muss nicht eingehalten werden. Spielt
eigentlich gar keine Rolle.
Soo, da ich mittlerweile auf meinen Laptop umsteigen musste Benutze ich
nun MPLAB X IDE 2.05 und den XC8 Compiler.
Hier ist mein neuer Quellcode. Ich hatte beim Programmieren die Richtung
aller Pins einfach vertauscht.
Allerdings ergibt sich immernoch keine änderung.
mfg
J. Bier
Takao K.:
> I2c kannst du auch mit Software machen.> Code fuer 16F5x habe ich moeglicherweise auf meinem Laptop.> einfach genau nach der Spezifikation programmieren, mehrmals genau> durchlesen, und Tristate richtig setzen.
Das versuche ich ja gerade... und das mit den 100kHz weis ich. Ansonsten
würde ich es nicht versuchen. Da der PIC zu langsam wäre.
Mfg
J. Bier
Bier schrieb:> Soo, da ich mittlerweile auf meinen Laptop umsteigen musste Benutze ich> nun MPLAB X IDE 2.05 und den XC8 Compiler.
Da bin ich mir nun wirklich nicht mehr sicher, aber ist es möglich dass
der XC8 Compiler RC3 bzw. RC4 garnicht kennt? Spuckt dir der Compiler da
kein Fehler aus?
Zumindest beim XC32 ist es nichtmehr möglich, RC3 so direkt
anzusprechen.
Die korrekte Variante wäre in dem falle
1
#define SCL PORTCbits.RC3
2
#define SDA PORTCbits.RC4
Alternativ kannst du sonst auch einmal versuchen, die Ausgänge über die
LATx Register zu beschreiben, anstelle von PORTx. Bei der Ansteuerung
über PORTx funktionieren einige Bitmanipulationen nicht. Informationen
dazu gibts im Datenblatt.
San Lue schrieb:> Bier schrieb:>> Soo, da ich mittlerweile auf meinen Laptop umsteigen musste Benutze ich>> nun MPLAB X IDE 2.05 und den XC8 Compiler.>> Da bin ich mir nun wirklich nicht mehr sicher, aber ist es möglich dass> der XC8 Compiler RC3 bzw. RC4 garnicht kennt? Spuckt dir der Compiler da> kein Fehler aus?> Zumindest beim XC32 ist es nichtmehr möglich, RC3 so direkt> anzusprechen.>> Die korrekte Variante wäre in dem falle>
1
>#defineSCLPORTCbits.RC3
2
>#defineSDAPORTCbits.RC4
3
>
Ok danke. Eigentlich arbeiten wir immernoch mit dem HiTech Compiler,
aber da ich wegen den Feiertagen zuhause weiterarbeiten muss. Hatte ich
keine Wahl. Werds mal versuchen.
mfg
J. Bier
Bier schrieb:> Ok danke. Eigentlich arbeiten wir immernoch mit dem HiTech Compiler,> aber da ich wegen den Feiertagen zuhause weiterarbeiten muss. Hatte ich> keine Wahl. Werds mal versuchen.
Wie gesagt, absolut keine garantie dass es funktioniert. Hab aber hier
grad selbst MPLAB X v2.05 offen, programmiere grade an einem 32-Bit uC
mit dem XC32 Compiler. Der spuckt mir da Fehlermeldungen aus, wenn ich
es so schreibe, wie du es getan hast.
Wäre aber auch durchaus möglich, dass der Fehler hier bei mir liegt,
also leg auf diese Meinung vielleicht nicht all zuviel Wert, aber wenn
du ohnehin nicht weiterkommst kann ein Versuch nicht schaden.
Hast du ein PICKit oder ein sonstiges Tool zum Debuggen? Könnte bei
dieser Anwendung auch ganz hilfreich sein, dann könntest du mal Schritt
für Schritt durchgehen...
Also mit meiner neusten Kreation kann ich immerhin an RC3 einen "Takt"
messen...
Inwiefern man das auch so nennen kann. Das signal schein relativ
regelmäßig zu sein. Hat eine Offset von 2,5V und Uss = 2V also ein
Toggeln zwischen 4,5V und 2,5V. Das Problem ist das sich auf der
Datenleitung garnichts tut.
Diese Platine macht mich noch wahnsinnig.
mfg
J. Bier
San Lue schrieb:> Hast du ein PICKit oder ein sonstiges Tool zum Debuggen? Könnte bei> dieser Anwendung auch ganz hilfreich sein, dann könntest du mal Schritt> für Schritt durchgehen...
Ich benutze das PicKit 2 mit der beiligenden Software Version 2.61.
Dieses ist an eine kleine Adapterplatine angeschlossen, welche das
Signal mittels eines 9 Poligen Kabels, über D-SUB stecker, auf die
Platine bringt.
Ansonsten habe ich nur noch ein Osci mit 4 Kanälen, aber nur zwei
Tastköpfe dabei...
Mfg
J. Bier
Bier schrieb:> Also mit meiner neusten Kreation kann ich immerhin an RC3 einen "Takt"> messen...
Immerhin, es tut sich schonmal was!
Bier schrieb:> Inwiefern man das auch so nennen kann. Das signal schein relativ> regelmäßig zu sein. Hat eine Offset von 2,5V und Uss = 2V also ein> Toggeln zwischen 4,5V und 2,5V.
Was sich da genau tut, ist allerdings ein Rätsel... Hängen da
irgendwelche Kondensatoren an den Leitungen? Sind da irgendwelche
Pull-Up's / Pull-Down vorhanden?
San Lue schrieb:> Hast du ein PICKit oder ein sonstiges Tool zum Debuggen?
Zudem, so als kleiner Nebentipp, zur besseren Übersicht im Programm:
Wenn du schon SDADir so schön definiert, dann benutz es auch ... Das
TRISCbits.TRISC4 könnte man hier beispielsweise ganz einfach ersetzen.
Hat zwar keinen Einfluss auf das Programm, sieht aber schöner aus und
verschafft klarheit.
1
voidperipherie_I2C(void)
2
{
3
SCL=1;
4
SDA=1;
5
6
K2Settings=bit_clear_K2(0b10000000,K2Settings);
7
K2Settings=bit_clear_K2(0b00000010,K2Settings);
8
K2Settings=bit_clear_K2(0b00000100,K2Settings);
9
K2Settings=bit_clear_K2(0b00001000,K2Settings);
10
11
__delay_ms(20);
12
13
TRISCbits.TRISC4=0;
14
TRISCbits.TRISC3=0;
15
}
Bier schrieb:> Ich benutze das PicKit 2
Kannst du dein Programm denn debuggen? Dann könntest du mal Schritt für
Schritt durchgehen und schauen, was genau passiert... kannst dir dazu
die wichtigsten Register anzeigen lassen, hilft evt.
Ok hab einen Fehler gefunden. In Zeile 270 und 313 springt er nichtmehr
aus der for-schleife da (i >= 0) und wenn bei 0-- ist er ja wieder bei
255 und somit in einer Endlosschleife.
Hab es auf (i > 0) geändert. Jetzt funktioniert wenigstens das
Grundprinzip. Er sendet Paar takte. Danach nichts mehr. Und paar
Sekunden später wieder paar Takte. Allerdings immernoch ohne
veränderungen auf der Datenleitung.
mfg
J. Bier
for(unsignedchari=7;i>=0;i--)// Achtung Clock ist nach übergabe Low
2
{
3
SDA=(data>>i)&0b00000001;
Wenn er in diese Schleife kommt, ist I genau 7. Gehen wir mal davon aus,
DATA = 11111111
Was hier nun geschieht:
Er verschiebt das ganze Byte um 7 stellen.
Übrig Bleibt:
SDA = 00000001
und damit hat sich der ganze spuck dann schon.
In meinen Augen müsste das eher so aussehen:
1
for(unsignedchari=7;i>=0;i--)// Achtung Clock ist nach übergabe Low
2
{
3
SDA=(data>>1)&0b00000001;
Sprich, er muss die Bits im Byte um eine stelle verschieben, nicht um I
stellen. Je nachdem, was dein erstes Byte war, ist es dann durchaus
möglich dass du da immer eine 0 mit dem Und verknüpft hast und somit nie
eine Änderung sehen konntest.
San Lue schrieb:> Was sich da genau tut, ist allerdings ein Rätsel... Hängen da> irgendwelche Kondensatoren an den Leitungen? Sind da irgendwelche> Pull-Up's / Pull-Down vorhanden?
Den Schaltplan der Platine kann man in der verlinkten PDF, aus meinem
ersten Beitag entnehmen. Die SDA und SCL leitungen laufen über die
Latches K8 und K9. K8 ist für die Richtung Senden. K9 zum empfangen.
Beide hängen an Pullups.
> San Lue schrieb:>> Hast du ein PICKit oder ein sonstiges Tool zum Debuggen?
Nein habe ich nicht. Außer das ist mit dieser Software möglich.
- MPLAB X IDE v2.10
- MPLAB IPE v2.10
- MPLAB driver switcher
- PICkit 2 v2.61
> Zudem, so als kleiner Nebentipp, zur besseren Übersicht im Programm:> Wenn du schon SDADir so schön definiert, dann benutz es auch ... Das> TRISCbits.TRISC4 könnte man hier beispielsweise ganz einfach ersetzen.> Hat zwar keinen Einfluss auf das Programm, sieht aber schöner aus und> verschafft klarheit.
Ja? Habs geändert.
> Kannst du dein Programm denn debuggen? Dann könntest du mal Schritt für> Schritt durchgehen und schauen, was genau passiert... kannst dir dazu> die wichtigsten Register anzeigen lassen, hilft evt.
Die Register kann ich doch in MPLAB mit dem Program Memory- und dem EE
Data Memory fenster sehen, oder?
mfg
J. Bier
San Lue schrieb:> for(unsigned char i = 7; i >= 0; i--) // Achtung Clock ist nach> übergabe Low> {> SDA = (data>>i) & 0b00000001;
Achtung Endlosschleife: Da i unsigned ist, kann es nie kleiner null
werden, i >= 0 ist somit immer TRUE.
Noch als kleiner Nachtrag:
Bei einer Verschiebung (Shift) um X-Stellen hängt es vom Datentyp der
Variable ab, ob sie mit 0 oder mit 1 aufgefüllt wird.
Ist die Variable dem Typ unsigned zugewiesen (wie in deinem Fall), wird
alles mit Nullen aufgefüllt.
Aus einem:
Data = 11111111
welches um 7 Stellen verschoben wird, wird zu einem
Data = 00000001
Anders ist es beim Typ signed. In diesem Falle würden die neuen Stellen
mit Einsen aufgefüllt.
Ein:
Data = 11111111
welches um 7 Stellen verschoben wird, bleibt ein
Data = 11111111
Bier schrieb:> Nein habe ich nicht. Außer das ist mit dieser Software möglich.
Ist es.
In MPLAB X hast du oben in der Menübar einen Punkt "Debug" Wähl diesen
mal, dann sollte sich da theoretisch ein Fenster öffnen in welchem du
das PICKit 2 auswählen kannst. Danach ist es dir möglich, dein Programm
Schritt für Schritt durchzugehen.
Max H. schrieb:> Achtung Endlosschleife: Da i unsigned ist, kann es nie kleiner null> werden, i >= 0 ist somit immer TRUE.
Korrekt, haben wir oben bereits erkannt und geändert. Hab nur
ausversehentlich einen alten Code kopiert.
Bier schrieb:> Ok hab einen Fehler gefunden. In Zeile 270 und 313 springt er nichtmehr> aus der for-schleife da (i >= 0) und wenn bei 0-- ist er ja wieder bei> 255 und somit in einer Endlosschleife.>> Hab es auf (i > 0) geändert.
Max H. schrieb:> Achtung Endlosschleife: Da i unsigned ist, kann es nie kleiner null> werden, i >= 0 ist somit immer TRUE.
Schon behoben...
@All damit der gleiche Fehler nicht mehrmals gefunden wird. Ist hier
jetzt die neuste Version meines Codes...
mfg
J. Bier
San Lue schrieb:> Noch als kleiner Nachtrag:>> Bei einer Verschiebung (Shift) um X-Stellen hängt es vom Datentyp der> Variable ab, ob sie mit 0 oder mit 1 aufgefüllt wird.>> Ist die Variable dem Typ unsigned zugewiesen (wie in deinem Fall), wird> alles mit Nullen aufgefüllt.>> Aus einem:> Data = 11111111> welches um 7 Stellen verschoben wird, wird zu einem> Data = 00000001>> Anders ist es beim Typ signed. In diesem Falle würden die neuen Stellen> mit Einsen aufgefüllt.> Ein:> Data = 11111111> welches um 7 Stellen verschoben wird, bleibt ein> Data = 11111111
Ok gut zu wissen. Aber das habe ich ja durch die AND-Verknüpfung am ende
Ausgeschlossen, oder? So bleibt immer nur das letzte Bit übrig.
> Ist es.> In MPLAB X hast du oben in der Menübar einen Punkt "Debug" Wähl diesen> mal, dann sollte sich da theoretisch ein Fenster öffnen in welchem du> das PICKit 2 auswählen kannst. Danach ist es dir möglich, dein Programm> Schritt für Schritt durchzugehen.
Ok werd ich gleich mal Versuchen...
Bier schrieb:> Schon behoben...> for(unsigned char i = 7; i > 0; i--)
So wird die Schleife ein Mal zu wenig ausgeführt. Ich würde das
vorschlagen:
for(signed char i = 7; i >= 0; i--)
Bier schrieb:> Ok gut zu wissen. Aber das habe ich ja durch die AND-Verknüpfung am ende> Ausgeschlossen, oder? So bleibt immer nur das letzte Bit übrig.
Ja. Das war eher als generelle Information gedacht und als ich das
geschrieben hatte, war immernoch mein Denkfehler vonwege SDA = SDA>>I
mit drin. Spielt natürlich keine Rolle in diesem Fall, kann aber nie
schaden es tortzdem zu wissen.
Bier schrieb:> Ok werd ich gleich mal Versuchen...
Denke, ist die einfachste Variante. Ohne das ganze zu Debuggen wird es
schwierig den Fehler zu finden. Bin gerade dabei mit den XC8 Compiler
herunterzuladen, werde das ganze dann auch mal auf meinem Testboard
durchgehen und schauen was ich da so messe.
Max H. schrieb:> Bier schrieb:>> Schon behoben...>> for(unsigned char i = 7; i > 0; i--)> So wird die Schleife ein Mal zu wenig ausgeführt. Ich würde das> vorschlagen:> for(signed char i = 7; i >= 0; i--)
Nein wird sie nicht...
Ist i = 2 wird eins abgezogen und dann die schleife ausgeführt.
Ist i = 1 wird eins abgezogen und dann die schleife ausgeführt.
Also führt sich die schleife auch aus wenn es 0 ist. Nur eben danach
nicht mehr...
Oder sehe ich das jetzt falsch?
mfg
J. Bier
Bier schrieb:> Also führt sich die schleife auch aus wenn es 0 ist> for(unsigned char i = 7; i > 0; i--)
So wird die Schleife nur für alle i>0 ausgeführt. Ist 0>0?
Bier schrieb:> Oder sehe ich das jetzt falsch?
Ja, er hat recht. Die Schleife würde nur dann noch einmal ausgeführt
werden, wenn da wieder ein I >= 0 ist, was ja nicht funktioniert.
Wenn man die Schleife in einem Satz beschreiben will:
Sie wird solange ausgeführt, wie I grösser als 0 ist.
7 = Schleife wird ausgeführt (1 Bit)
6 = Schleife wird ausgeführt (2 Bit)
5 = Schleife wird ausgeführt (3 Bit)
4 = Schleife wird ausgeführt (4 Bit)
3 = Schleife wird ausgeführt (5 Bit)
2 = Schleife wird ausgeführt (6 Bit)
1 = Schleife wird ausgeführt (7 Bit)
0 = Schleife wird nichtmehr ausgeführt, da I 0 wäre und somit der
Anforderung
"I grösser als 0" nichtmehr stimmt.
Lösungen: signed Char, oder I mit 8 Initialisieren.
Max H. schrieb:>> Also führt sich die schleife auch aus wenn es 0 ist>> for(unsigned char i = 7; i > 0; i--)> So wird die Schleife nur für alle i>0 ausgeführt. Ist 0>0?
Davor war das Problem ja das i einen überlauf hatte und somit, wo i = 0
war immernoch einem eins abgezogen wurde und i damit auf i = 255
gerutscht ist.
Das sollte aber eben nicht mehr passieren wenn ich eben nicht I >= 0
mache, sondern i > 0. Damit führt sich eben genau dieser überlauf nicht
mehr aus.
Aber ist auch egal... werd einfach wieder meine alte variante nehmen und
aus "unsigned char" ein "char" machen. Die lösung gefällt mir doch
besser...
mfg
J. Bier
Bier schrieb:> Das sollte aber eben nicht mehr passieren wenn ich eben nicht I >= 0> mache, sondern i > 0. Damit führt sich eben genau dieser überlauf nicht> mehr aus.
Es ist keine Endlosschleife mehr, aber sie wird nur 7-mal ausgeführt,
weil sie für i=0 nicht mehr ausgeführt wird.
Die Frage ist, ob das Programm überhaupt bis zu dieser Schleife kommt.
Die erste Funktion die aufgerufen wird, welche eine Änderung an RC3 bzw.
RC4 erzwingen müsste, ist peripherie_I2C.
Direkt die ersten beiden Zeilen:
1
SCL=1;
2
SDA=1;
Bereits hier müsste eine Änderung zu sehen sein. Was ich nicht ganz
verstehe, wieso hast du am Schluss der besagten Funktion:
1
SDADir=0;
2
TRISCbits.TRISC3=0;
drin stehen? Die beiden Bits müssten ohnehin schon auf 0 von der
Initialisation sein.. Tut zwar auch nichts zur Sache, aber sind wieder
paar Zeilen die man streichen kann.
Hab jetzt den Compiler, debugge mal drauf los ;)
San Lue schrieb:> drin stehen? Die beiden Bits müssten ohnehin schon auf 0 von der> Initialisation sein.. Tut zwar auch nichts zur Sache, aber sind wieder> paar Zeilen die man streichen kann.
Der Grund dafür ist das SDA und SCL im Ruhezustand beide High sind.
Ich habs etwas abgeändert... aber es dürfte keinen unterschied machen.
> Hab jetzt den Compiler, debugge mal drauf los ;)
Ok, vielen Dank für deine mühen und natürlich auch an alle anderen.
mfg
J. Bier
Bier schrieb:> Ok, vielen Dank für deine mühen und natürlich auch an alle anderen.
Kein Problem
Kurz ein paar kleine Fragen zur Sicherstellung:
Du arbeitest derzeit mit MPLAB X v2.05 mit dem XC 8 Compiler, stimmt
das?
Wenn dem so ist:
Die funktion _delay_ms(XX) und _delay_us(XX) sind bei diesem Compiler
nicht integriert. Der Code bleibt also an dieser Stelle stehen (Auch
sehr schön zu sehen beim Debuggen)
Desweiteren, beim Aufruf von peripherie_I2C wird zumindest im Software
Debugger sowohl der Zustand von RC3 auch wie der von RC4 geändert.
Bleibt dann aber stecken bei besagtem Delay. Zumindest bei mir weiss der
Compiler nicht, was er mit der Funktion anfangen soll.
Worüber ich hingegen recht überrascht bin, dass er offenbar Befehle wie
1
RB2=0;
erkennt, sprich, man die Ports wieder mit RXX ansprechen kann. Bei
meinem XC32 Compiler war dies wie bereits geschrieben nur mit
PORTXbits.RXX möglich. Ich suche mal noch ein wenig weiter.
San Lue schrieb:> Bier schrieb:>> Ok, vielen Dank für deine mühen und natürlich auch an alle anderen.>> Kein Problem>> Kurz ein paar kleine Fragen zur Sicherstellung:> Du arbeitest derzeit mit MPLAB X v2.05 mit dem XC 8 Compiler, stimmt> das?
Ne MPLAB v2.10... Sry beim download link stand noch v2.05 aber in der
Systemsteuerung steht v2.10
> Wenn dem so ist:> Die funktion _delay_ms(XX) und _delay_us(XX) sind bei diesem Compiler> nicht integriert. Der Code bleibt also an dieser Stelle stehen (Auch> sehr schön zu sehen beim Debuggen)
Ja sowas in der art vermute ich auch gerade, da anscheinden (laut Osci)
die komplette while(TRUE) durchlaufen wird, aber mein zweimal Blinken
bei den LEDs nicht anzukommen scheint (bzw. so schnell ist das es nur
einmal sehr kurz ist...
Anscheinden bleibt er bei mir nicht stecken, sondern ignoriert es
einfach komplett. Wenn ich aber alles durch z.b.
1
for(unsignedcharz=0;z<=10000;z++)
2
{
3
NOP();
4
}
ersetze funktioniert es genausowenig.
Welche möglichkeiten habe ich noch eine Wartezeit zu erzeugen?
Im HiTech Kompiler funktioniert das Problemlos...
Achja schau mal was dein Debugger sagt, wenn du die beiden Makros oben
wieder einkommentierst...
Bier schrieb:> Im HiTech Kompiler funktioniert das Problemlos...
Die Delayfunktionen kommen auch vom HiTech Compiler. Bin etwas verwirrt,
arbeitest du nun mit dem HiTech oder mit dem XC?
Sofern es XC ist, wird es ein Problem bei den Delays geben, der HiTech
dürfte die normal aushüren können...
Habe hier derzeit leider nur MPLAB X zur Verfügung.
Bier schrieb:> Welche möglichkeiten habe ich noch eine Wartezeit zu erzeugen?
Theoretisch genau diese, welche du da aufgeschrieben hast. Auch die
Delay Funktion im Hitech Compiler ist nichts anderes als eine Schleife,
an welche du einen Parameter übergibst. Im inneren wird dann halt soviel
Zeit verbtraten, dass Beispielsweise ein
__delay_ms(1);
genau 1 ms dauert. Man kann sich da ja relativ einfach ausrechnen,
wieviele Nops es dafür braucht.
Ansonsten bin ich auch gerade etwas ratlos... bis auf die Delay
funktion, welche ich nicht debuggen kann, müsste das ganze eigentlich
funktionieren.
Ich schlage folgendes vor:
Erstelle ein neues Projekt, initialisiere in dem Projekt nur das
nötigste und versuch dort mal ein paar Bits von PORTA, B, und vorallem
RC4 zu ändern. Gespannt drauf, ob es dann klappt...
Ok, jetzt funktioniert es aufeinmal...
Also mit der Zeitverzögerung und der for-schleife. Komisch???
Aber kann mir einer erklären wieso LED P5 -> Also RC4 trotz diesem
Bitmuster 0b10101010 einfach trotzdem an ist?
Ich komme leider nicht in den Debug mode da steht:
PK2Error0028: Unable to enter debug mode
mfg
J. Bier
San Lue schrieb:> Die Delayfunktionen kommen auch vom HiTech Compiler. Bin etwas verwirrt,> arbeitest du nun mit dem HiTech oder mit dem XC?
Im moment mit dem XC8, aber auf der Arbeit und in der Schule mit dem
HiTech...
Bier schrieb:> Aber kann mir einer erklären wieso LED P5 -> Also RC4 trotz diesem> Bitmuster 0b10101010 einfach trotzdem an ist?
Leider mag mein Adobe Reader gerade nicht mitspielen, kriege eine
Fehlermeldung bei der öffnung des Schemas.
Änder mal das Bit zu 1, ist es möglich, dass sie dann abschaltet?
Falls ja, wäre die LED Low aktiv geschaltet.
Bier schrieb:> Ich komme leider nicht in den Debug mode da steht:> PK2Error0028: Unable to enter debug mode
Kannst sonst als Debug Tool aus den Simulator wählen, dann kannst du das
Programm direkt auf deinem PC simulieren ohne Hardware.
Habe das gerade bei mir einmal gemacht, da funktioniert alles perfekt,
solange ich die delay's auskommentiere, was du ja nicht machen musst da
anderer Compiler. Auch RC4 ändert laut MPLAB seinen Zustand zwischen 0
und 1.
Bier schrieb:> Im moment mit dem XC8, aber auf der Arbeit und in der Schule mit dem> HiTech...
Dann ersetz die Delays durch eine For schleife, solange du mit dem XC8
arbeitest.
Im Anhang ein Bild von der Anzeige des PORTC direkt nach dem Ausführen
der Zeile SDA=1;
Man sieht, RC4 ändert seinen Zustand.
San Lue schrieb:> Kannst sonst als Debug Tool aus den Simulator wählen, dann kannst du das> Programm direkt auf deinem PC simulieren ohne Hardware.>> Habe das gerade bei mir einmal gemacht, da funktioniert alles perfekt,> solange ich die delay's auskommentiere, was du ja nicht machen musst da> anderer Compiler. Auch RC4 ändert laut MPLAB seinen Zustand zwischen 0> und 1.
Wo kann ich das machen? Unter der Option Debug finde ich nur Disconect
from Debugger, aber nichts wo ich auswählen kann wo es debuggen soll...
> Bier schrieb:>> Im moment mit dem XC8, aber auf der Arbeit und in der Schule mit dem>> HiTech...>> Dann ersetz die Delays durch eine For schleife, solange du mit dem XC8> arbeitest.>> Im Anhang ein Bild von der Anzeige des PORTC direkt nach dem Ausführen> der Zeile SDA=1;> Man sieht, RC4 ändert seinen Zustand.
Hm bei mir geht er nicht mehr aus... werd mal mit dem Osci paar PINs
testen
mfg
J. Bier
So hier meine Testdatei...
RC3 und RC4 sollten nach dem Bitmuster kurz aus und danach wieder an
gehen...
RC3 macht das auch aber RC4 bleibt dauer High...
Das einzige was mir noch einfällt ist das vieleicht irgend ein Latch da
noch einen komischen Pegel drauf gibt... muss das mal überprüfen.
mfg
J. Bier
Ok habs... der Draht den ich zum Messen benutzt habe muss irgendwie an
einen High Pegel gekommen sein und hat deshalb das ganze ergebnis
versaut. Und noch schlimmer das ding hat auch noch einen Drahbruch,
weshalb ich am Osci nur ein Low Signal gemessen habe...
Ich schneid mir mal ein neues Stück zurecht und poste dann meine neuen
Ergebnisse.
Damit habe ich jetzt garnicht gerechnet :o
mfg
J. Bier
So immerhin sehe ich jetzt eine plausieble Funktion des PICs
hier meine Ergebnisse...
Wie man sehen kann sind die Pegel immernoch sehr Fragwürdig. Könnte das
mit den Latches K8 und K9 zusammenhängen?
Sie müssten beide auf durchzug geschaltet sein und nach K8 gibt es ja
noch die zwei Dioden. BAT43...
mfg
J. Bier
So bin noch an der Auswertung des Ergebnisses um die Pegel werd ich mich
nur kümmern, wenn es nötig ist. Vieleicht sind sie ja noch in den
erkennbaren Grenzen.
Das Osci Bild zeigt den Anfang der zu senden Adresse (0b100100 RW) aber
wie man unschwer erkennen kann, werden die High Pegel nach Standard
übertragen und bei den Low Pegeln ändert sich das Datensignal bei einem
SCL = High, was aber niemals Passieren dürfte...
Hat jemand eine idee, wieso? Von der Programmierung her dürfte es doch
keine solchen Probleme geben, oder?
1
voidI2C_Send_Data(unsignedchardata)
2
{
3
SDADir=0;
4
5
for(signedchari=7;i>=0;i--)// Achtung Clock ist nach übergabe Low
6
{
7
for(unsignedlongz=0;z<=100;z++){NOP();}
8
SDA=(data>>i)&0b00000001;
9
10
for(unsignedlongz=0;z<=100;z++){NOP();}
11
SCL=1;
12
for(unsignedlongz=0;z<=100;z++){NOP();}//oder länger mal schauen wies funktioniert
Bier schrieb:> So bin noch an der Auswertung des Ergebnisses um die Pegel werd ich mich> nur kümmern, wenn es nötig ist.
Es ist jetzt nötig: Wenn du SDA auf '1' setzt, liest der PIC die Pegel
am gesamten Port ein, ändert das bit und schreibt das gesamte Byte
wieder zurück ins PORTx Register. Bei den Pegeln, liest er SCL als '1'
und schreibt also wider 1 zurück. Und wenn er SCL auf '1' setzen sollte
setzt er SDA damit auch auf '1'.
http://www.sprut.de/electronic/pic/fallen/fallen.html#inout
Max H. schrieb:> Es ist jetzt nötig: Wenn du SDA auf '1' setzt, liest der PIC die Pegel> am gesamten Port ein, ändert das bit und schreibt das gesamte Byte> wieder zurück ins PORTx Register. Bei den Pegeln, liest er SCL als '1'> und schreibt also wider 1 zurück. Und wenn er SCL auf '1' setzen sollte> setzt er SDA damit auch auf '1'.>> http://www.sprut.de/electronic/pic/fallen/fallen.html#inout
Ok. wow danke für den Tipp! Das hätte ich nicht selber gefunden.
Werd mich gleich mal dran setzen.
Der schlimmste fall wäre das ich immer nur ein Latch durchschalten darf.
Das würde bedeuten ich muss vor jedem Bit, schauen, ob ich Einlesen oder
Ausgeben will und die Latches K8/K9 entsprechen modifizieren.
mfg
J. Bier
Verdammt. Es ist genau wie vermutet.
Das ist das neue Bild wenn nur das Latch zum Senden K8 durchgeschaltet
ist.
Ok dann hab ich ja ein wenig Arbeit vor mir...
Wenn ich Fertig bin, werde ich natürlich meine Lösung hier noch Posten,
auch wenn keine Fehler auftreten.
mfg
J. Bier
Soo. War einfacher als ich es mir vorgestellt hatte. Allerdings habe ich
das Problem das der Baustein DS1621 nicht Antwortet.
Ich glaube nicht das die Clock "zu schnell" ist wie ihr an dem Bild
sehen könnt sind 250ms/DIV eingestellt.
Ich bekomme nichtmal ein positives Acknowledge-Bit zurück. Die Baustein
adresse "1001000" müsste stimmen, da A1, A2 und A3 auf Masse liegen.
Hat jemand eine idee?
mfg
J. Bier
@Pulldown / Max H. Ja ein I²C Bus erzwingt Pullups auf beiden Leitungen.
Tristate umschalten um ACKN zu lesen?
Gibt es einen kleinen Trick, keine daten schreiben,
sondern nur Tristate umschalten
Wenn TS = 1 : Ausgabe = 1.
Wenn TS = 0 : Ausgabe = 0.
Wenn gelesen werden soll, 1 ausgeben.
Takao K. schrieb:> Tristate umschalten um ACKN zu lesen?>> Gibt es einen kleinen Trick, keine daten schreiben,>> sondern nur Tristate umschalten>> Wenn TS = 1 : Ausgabe = 1.> Wenn TS = 0 : Ausgabe = 0.>> Wenn gelesen werden soll, 1 ausgeben.
Bitte erkläre das genauer. Ich muss die zwei Ladges K8 und K9 im Wechsel
in den Tristate-, Weitergabe mode schalten.
Hier ein Auszug wie ich das ACKN versuche zu Lesen:
Als kleine Berichtigung. Ich hatte am Ende I2C_Stop() vergessen.
Deswegen hatte ich keine 18 Takte. Hier nochmal das aktuelle Bild.
Diese kurzen Piks die man da auf SDA sehen kann streuen sich da manchmal
ein. Aber ich glaube nicht das sie zu den Temperaturdaten gehören, da
sie sehr willkürlich sind.
mfg
J. Bier
Max H. schrieb:> Bier schrieb:>> 4 MB, 1 Downloads> Das ist ein bisschen viel… Siehe Bildformate
Stimmt. Ich werde die Bilder fortan Komprimieren.
Diese Piks auf der Leitung haben mich doch gewundert. Hier hab ich einen
mal auf dem Osci hoch aufgelöst. Woher dies Kurze schwankung auf der SCL
Leitung kommt, kann ich mir nicht erklären. Aber er sieht mir doch nicht
mehr so willkürlich aus wie anfangs vermutet.
mfg
J. Bier
So hab die Idee bekommen, dass Ab und An schalten der Ladges zu
vertauschen.
Wie man in dem Bild sehen kann ist das Ergebnis, das die SCL leitung
nicht mehr schwankt. Die Piks kommen jetzt am Ende jedes SCL
High-Pegels, bei dem ich einen Low-Pegel einlese.
Die neue funktion:
Im Datenblatt das DS1621:
> A master must signal an end of data to the slave>> by not generating an acknowledge bit on the last byte that has been> clocked out of the slave. In this case,> the slave must leave the data line HIGH to enable the master to generate> the STOP condition.
Hab ich natürlich sofort Angepasst.
mfg
J. Bier
So scheint soweit zu funktionieren ;)
Muss wohl nurnoch die ansteuerung des DS1621 machen... dachte erst das
wenn ich einfach aus dem Baustein auslese, er mir die Temperatur gibt,
aber anscheinen muss ich noch ein paar Konfigurwationsbytes senden...
Wenn ich fertig bin werde ich natürlich meine Lösung zum Abschluss
hochladen.
mfg
J. Bier
Gute Nacht,
habe einiges Abgeändert und mich von diesem Beitrag inspirieren lassen:
http://forum.arduino.cc/index.php/topic,30088.0.html
Die Initialisierung des DS1621 scheint soweit reibungslos zu laufen. Nur
das Abfragen der Temperatur will einfach nicht Funktionieren.
Wie man dem Bild entnehmen kann Sendet mir der Baustein nach der Adresse
und Read ein Nack und bricht ab, oder wie auch immer.
Meine Frage wie muss ich den jetzt richtig Initialisieren? Aus dem
Datenblatt kann ich zwar viele verschiedene Configurationen entnehmen,
aber das macht mich gerade nicht viel schlauer, da jedes Beispiel das
ich finde anders zu sein Scheint.
Wie z.B. das: Beitrag "Atmega16, Ds1621, Display"
und der vorherige Link.
Für einen einmaligen Abruf brauche ich die Config AAh (aus dem
Datenblatt) aber wie muss ich ihn initialisieren?
Und wieso sendet mir der Baustein ein NACK?
Werd mich um die dinge dann Morgen kümmern. Vieleicht habt ihr ja noch
eine Idee.
mit freundlichen Grüßen
J. Bier
Morgen,
ich habe mich wieder an mein Programm gesetzt und die "Repeated
Startcondition" eingebaut. Wie man in dem Bild sehen kann, sollte der
Bus einwandfrei Funktionieren, allerdings sendet der DS1621 keine Werte
zurück.
Der Baustein sendet mir auch immer ein ACK zurück, was doch bedeuten
müsste, dass dieser versteht was ich haben möchte. ;)
Steuere ich den Baustein falsch an?
Aus Speicherplatzgründen benutze ich nun die USB Funktion des Oscis.
mfg
J. Bier
Ich habe noch einige Dinge ergänzt und habe mich strickt an die Vorgaben
aus dem Datenblatt gehalten.
Ich initialisiere den Baustein direkt nach dem PIC:
1
voidinit_DS1621(void)
2
{
3
peripherie_I2C();
4
I2C_Start();
5
I2C_Send_Data(DS1621_Write);
6
I2C_Send_Data(0xAC);
7
I2C_Send_Data(0x01);//1SHOT Mode Enabled
8
I2C_Stop();
9
for(unsignedlongz=0;z<=20000;z++);
10
peripherie_NoI2C();
11
}
Mit 0xAC verschaffe ich mir Zugang zum Config Register und schreibe
0x03. Das aktiviert den 1 Shot Mode. [Bild 01 - Initialice]
- Der Fehler: Am Ende der Configdaten Sendet der Baustein ein NACK.
Etwas später sende ich das Start Convert T Protocol. Warte danach eine
Zeit ab und versuche die Temperatur zu Lesen:
[c]
peripherie_I2C();
I2C_Start();
I2C_Send_Data(DS1621_Write);
I2C_Send_Data(0xEE); //Start Convert T Protocol
I2C_Stop();
for(unsigned long z = 0; z <= 100000; z++){NOP();}
I2C_Start();
I2C_Send_Data(DS1621_Write);
I2C_Send_Data(0xAA);
I2C_Restart();
I2C_Send_Data(DS1621_Read);
Temp1 = I2C_Read_Data();
I2C_ACK();
Temp2 = I2C_Read_Data();
I2C_NACK();
I2C_Stop();
peripherie_NoI2C();
[c/]
Start Convert T Protocol: [Bild 02 - Start Convert T]
Lesen der Temperatur: [Bild 03 - Read Temp]
Soweit ich das sehe sind alle übertragungen Korrekt, jedoch sendet mir
der Baustein trotzdem ein Nack bei der Initialisierung und beim Abruf
der Daten (in der zweiten Adresse).
Ich habe gerade überhaupt keine Idee, was ich falsch mache.
mfg
J. Bier
PS: Das wird langsam zu einem Selbstgespräch... hat denn keiner mehr
eine Idee?
Konnte gerade Feststellen, dass der DS1621 mir kein NACK zurück gibt,
wenn ich ihm als Config Byte 0x02 übertrage. Somit würde der Baustein,
aber nicht im "one Shot mode" laufen...
Eigentlich ist es mir egal, hauptsache ich bekomme endlich mal eine
Antwort...
Naja werd dann mal weiter schauen.
mfg
J. Bier
Guten Morgen,
hier mein neuster Code.
Der DS1621 nimmt die Configs an und lässt sich mit Start Convert T auch
im Continuous starten. Alles soweit also in Ordnung.
Allerdings bekomme ich beim Abruf der Daten (Entweder mit 0xAA 2 Byte,
oder 0xA1 1 Byte) beim 2. Senden des Adressbytes mit R/W = 1 ein NACK
zurück und das Datenbyte ist Leer.
Alle meine übetragungen entsprechen den im Datenblatt, des DS1621,
gezeigten Figuren. (Seite 9)
Ich weis es gibt hier im Forum schon genug Artikel zu dem DS1621 und ich
habe mich seit meinem letzten Beitrag mit nichts anderem mehr
beschäftigt, aber ich finde meinen Fehler trotzdem nicht.
mit freundlichen Grüßen
J. Bier
Suche gerade danach woran es liegen kann ein NACK nach dem Addressbyte
zu bekommen und möchte nochmal betonen, dass der Baustein korrekt
verdratet ist. Mit einem (.hex) file von einer alten IHK Prüfung (weis
leider gerade nicht welcher.. Sommer 09 oder 10) lässt sich nehmlich
dieser Problemlos ansteuern.
Microchip Forum:
> You are correct, the ACK is hardware> generated. The SLAVE always sends an ACK if> the data was received properly including an> ACK for the last byte.
Ich habe mein Osci auch direkt an die Pins des ICs gehängt und dieser
bekommt alle Bytes störungsfrei.
mfg
J. Bier
Hallo Bier
Konntest du den Fehler mittlerweile finden?
Bier schrieb:> Mit einem (.hex) file von einer alten IHK Prüfung (weis> leider gerade nicht welcher.. Sommer 09 oder 10) lässt sich nehmlich> dieser Problemlos ansteuern.
Könntest ja mal das alte HEX File zum Ansteuern benutzen und mit deinem
Oszilloskop die I2C Leitungen aufzeichnen. Danach wertest du mal aus,
was für Dsaten das HEX File so an den Baustein sendet.
Danach nimmst du dein Programm und sendest ihm mal die genau selben
Daten. Auch wenn es noch nicht der Modi ist, den du dann willst, rein
theoretisch müsstest du dann eine Antwort erhalten. So kannst du
immerhin ausschliessen, ob es sich nun um eine falsche initialisierung
handelt oder ob dein Soft-I2C Probleme macht.
Gruss
San Lue schrieb:> Konntest du den Fehler mittlerweile finden?
Nein bis jetzt nicht...
> Könntest ja mal das alte HEX File zum Ansteuern benutzen und mit deinem> Oszilloskop die I2C Leitungen aufzeichnen. Danach wertest du mal aus,> was für Dsaten das HEX File so an den Baustein sendet.>> Danach nimmst du dein Programm und sendest ihm mal die genau selben> Daten. Auch wenn es noch nicht der Modi ist, den du dann willst, rein> theoretisch müsstest du dann eine Antwort erhalten. So kannst du> immerhin ausschliessen, ob es sich nun um eine falsche initialisierung> handelt oder ob dein Soft-I2C Probleme macht.
Das hab ich schonmal versucht, aber mit mäßigem Erfolg, da der Takt der
übertragung in diesem Programm deutlich erhäht ist als bei meinem. Ich
wollte das bei mir erst machen, wenn es eben funktioniert.
Werd mich da vieleicht nochmal dran setzen... leider ist übermorgen
schon die Präsentation. Aber würde mich schon noch interessieren, das zu
Lösen.
mfg
J. Bier
Guten Morgen,
meine I²C Programmierung funktioniert jetzt einwandfrei. Es gibt nur
noch ein paar kleinigkeiten, die ich ändern musste.
1. Bei umschalten der Treiber musste ich kurzzeitig auf PORTC ein
anderes Signal ausgeben und deshalb habe ich nach der aktivierung der
Treiber SDA immernoch auf Low Pegel gehabt und dieser ist ja Dominant...
2. Bei meiner I2C_Start Funktion funktioniert aus irgend einem Grund die
verzögerung nicht und deshalb wurden beide Pegel gleichzeitig runter
gezogen. Ich habe die For-Schleife so angepasst, das anstatt NOP(), SCL
auf High gesetzt wird. Danach ging es...
3. und letztes Problem. Beim Aktivieren der Treiber werden beide
Signalleitungen kurz auf Masse gezogen. Das kann ich aber nicht
verhindern. Zumindest habe ich noch keine Idee wie...
Vieleicht erst in den Tri-Sate mode und dann Aktivieren...
Habe meinen I2C Code an einer anderen Platine ohne Treiber getestet und
er Funktioniert einwandfrei.
Vielen dank für eure Hilfen und Mühen
Fals ich mich nochmal an die Treiber Platine MC2V0 setze und Erfolg
haben sollte, werde ich diesen hier Posten. Bis dahin Closed.
mit freundlichen Grüßen
J. Bier