Forum: Mikrocontroller und Digitale Elektronik PIC16F887 auf MC2V0 - I2C


von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von PINB (Gast)


Lesenswert?

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?

von Bier (Gast)


Lesenswert?

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

von Nobby Nic (Gast)


Lesenswert?

Stimmt die Ansteuerung der Latches? Mal mit dem Oszi oder Logic Analyzer 
die I2C-Pins vor dem Latch K8/K9 gemessen?

von Helper (Gast)


Lesenswert?

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
void I2C_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..

von Bier (Gast)


Lesenswert?

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

von San L. (zwillingsfreunde)


Lesenswert?

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.

von Bier (Gast)


Lesenswert?

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

von Takao K. (takao_k) Benutzerseite


Lesenswert?

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.

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von San L. (zwillingsfreunde)


Lesenswert?

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.

von Bier (Gast)


Lesenswert?

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
> #define SCL PORTCbits.RC3
2
> #define SDA PORTCbits.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

von San L. (zwillingsfreunde)


Lesenswert?

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...

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von San L. (zwillingsfreunde)


Lesenswert?

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
void peripherie_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.

von Bier (Gast)


Lesenswert?

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

von San L. (zwillingsfreunde)


Lesenswert?

Hab den Fehler... glaube ich.

Hier:
1
  for(unsigned char i = 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(unsigned char i = 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.

: Bearbeitet durch User
von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Lesenswert?

San Lue schrieb:
> Hab den Fehler... glaube ich.

Nein das ist schon Richtig so...

Die for-schleife zählt Rückwerts von 7 bis 0.

Angebommen ich möchte 01101100 Senden dann im ersten moment

SDA = 01101100 >> 7 & 00000001 -> 0 & 1 => 0
SDA = 01101100 >> 6 & 00000001 -> 1 & 1 => 1
SDA = 01101100 >> 5 & 00000001 -> 1 & 1 => 1
SDA = 01101100 >> 4 & 00000001 -> 0 & 1 => 0
SDA = 01101100 >> 3 & 00000001 -> 1 & 1 => 1
SDA = 01101100 >> 2 & 00000001 -> 1 & 1 => 1
SDA = 01101100 >> 1 & 00000001 -> 0 & 1 => 0
SDA = 01101100 >> 0 & 00000001 -> 0 & 1 => 0

Außerdem wird das MSB zuerst gesendet...

Der denkfehler liegt glaub bei dir daran das ich ja die verschiebung von 
data nicht speichere.

von Max H. (hartl192)


Lesenswert?

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.

von San L. (zwillingsfreunde)


Lesenswert?

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.

: Bearbeitet durch User
von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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...

von Max H. (hartl192)


Lesenswert?

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--)

von San L. (zwillingsfreunde)


Lesenswert?

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.

von Bier (Gast)


Lesenswert?

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

von Max H. (hartl192)


Lesenswert?

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?

: Bearbeitet durch User
von San L. (zwillingsfreunde)


Lesenswert?

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.

von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Lesenswert?

Ok den letzten beitrag könnt ihr also streichen...

von Max H. (hartl192)


Lesenswert?

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.

von San L. (zwillingsfreunde)


Lesenswert?

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 ;)

: Bearbeitet durch User
von Bier (Gast)


Lesenswert?

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

von San L. (zwillingsfreunde)


Lesenswert?

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.

von Bier (Gast)


Lesenswert?

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(unsigned char z = 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...

von Bier (Gast)


Lesenswert?

Bier schrieb:
>
1
> for(unsigned char z = 0; z <= 10000; z++)
2
> {
3
>     NOP();
4
> }
5
>

Ich meinte natürlich
1
for(unsigned long z = 0; z <= 10000; z++)
2
{
3
    NOP();
4
}

mfg
J. Bier

von San L. (zwillingsfreunde)


Lesenswert?

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...

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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...

von San L. (zwillingsfreunde)


Angehängte Dateien:

Lesenswert?

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.

: Bearbeitet durch User
von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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
void I2C_Send_Data(unsigned char data)
2
{
3
  SDADir = 0;
4
5
  for(signed char i = 7; i >= 0; i--)  // Achtung Clock ist nach übergabe Low
6
  {
7
    for(unsigned long z = 0; z <= 100; z++){NOP();}
8
    SDA = (data>>i) & 0b00000001;
9
10
    for(unsigned long z = 0; z <= 100; z++){NOP();}
11
    SCL = 1;
12
    for(unsigned long z = 0; z <= 100; z++){NOP();} //oder länger mal schauen wies funktioniert
13
    SCL = 0;
14
    for(unsigned long z = 0; z <= 100; z++){NOP();}
15
  }
16
  //Acknowledge
17
  SDADir = 1;
18
19
  for(unsigned long z = 0; z <= 100; z++){NOP();}
20
  SCL = 1;
21
  for(unsigned long z = 0; z <= 100; z++){NOP();}
22
  ACK = SDA;
23
  for(unsigned long z = 0; z <= 100; z++){NOP();}
24
  SCL = 0;
25
  for(unsigned long z = 0; z <= 100; z++){NOP();}
26
}

mfg
J. Bier

von Max H. (hartl192)


Lesenswert?

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

: Bearbeitet durch User
von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Pulldown (Gast)


Lesenswert?

Versuchs mal mit Pull down Widerständen auf den beiden Leitungen.

von Max H. (hartl192)


Lesenswert?

Pulldown schrieb:
> Versuchs mal mit Pull down Widerständen auf den beiden Leitungen.

Bist du die sicher, dass I2C nicht Pull Up haben will?

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Takao K. (takao_k) Benutzerseite


Lesenswert?

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.

von Bier (Gast)


Lesenswert?

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:
1
    //Acknowledge
2
    for(unsigned long z = 0; z <= 500; z++){NOP();}
3
    SCL = 1;
4
    for(unsigned long z = 0; z <= 500; z++){NOP();}
5
    I2C_SDA_Dir(1);
6
    ACK = SDA;
7
    I2C_SDA_Dir(0);
8
    for(unsigned long z = 0; z <= 500; z++){NOP();}
9
    SCL = 0;
10
    for(unsigned long z = 0; z <= 500; z++){NOP();}

Die funktion "I2C_SDA_Dir(unsigned char)":
1
void I2C_SDA_Dir(unsigned char dir) //1 = Read; 0 = Write
2
{
3
    if(dir)
4
    {
5
        K2Settings = bit_set_K2(0b10000000, K2Settings); //EN - OE K8
6
        K2Settings = bit_set_K2(0b00001000, K2Settings); //C1 - LE K8
7
8
        K2Settings = bit_clear_K2(0b00000010, K2Settings); //C1 - LE K9
9
        K2Settings = bit_clear_K2(0b00000100, K2Settings); //EN - OE K9
10
    }
11
    else
12
    {
13
        K2Settings = bit_set_K2(0b00000010, K2Settings); //C1 - LE K9
14
        K2Settings = bit_set_K2(0b00000100, K2Settings); //EN - OE K9
15
        
16
        K2Settings = bit_clear_K2(0b10000000, K2Settings); //EN - OE K8
17
        K2Settings = bit_clear_K2(0b00001000, K2Settings); //C1 - LE K8
18
    }
19
20
    SDADir = dir;
21
}

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Max H. (hartl192)


Lesenswert?

Bier schrieb:
> 4 MB, 1 Downloads
Das ist ein bisschen viel… Siehe Bildformate

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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:
1
void I2C_SDA_Dir(unsigned char dir) //1 = Read; 0 = Write
2
{
3
    if(dir)
4
    {
5
        K2Settings = bit_clear_K2(0b00000010, K2Settings); //C1 - LE K9
6
        K2Settings = bit_clear_K2(0b00000100, K2Settings); //EN - OE K9
7
8
        K2Settings = bit_set_K2(0b10000000, K2Settings); //EN - OE K8
9
        K2Settings = bit_set_K2(0b00001000, K2Settings); //C1 - LE K8
10
    }
11
    else
12
    {
13
        K2Settings = bit_clear_K2(0b10000000, K2Settings); //EN - OE K8
14
        K2Settings = bit_clear_K2(0b00001000, K2Settings); //C1 - LE K8
15
16
        K2Settings = bit_set_K2(0b00000010, K2Settings); //C1 - LE K9
17
        K2Settings = bit_set_K2(0b00000100, K2Settings); //EN - OE K9
18
    }
19
20
    SDADir = dir;
21
}

von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)



Lesenswert?

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
void init_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(unsigned long z = 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?

von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von San L. (zwillingsfreunde)


Lesenswert?

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

von Bier (Gast)


Lesenswert?

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

von Bier (Gast)


Angehängte Dateien:

Lesenswert?

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

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
Noch kein Account? Hier anmelden.