PIC < > AVR (mit IIC)

OP Persönliche Seite #2321851
Lesenswert?

Guten Morgen zusammen,
der Betreff sagt es eigentlich schon ganz gut. Ich bin dabei meine 
ersten Gehversuche mit dem IIC Bus zu machen und bin im Augenblick 
irgendwie fest gefahren. Kurz zu meiner Situation: Ich habe mir vor 
Jahren mal einen RP6 Roboter gekauft und bastle daran i.M. wieder ein 
bisschen herum.

Ich möchte eine IIC Verbindung von einem PIC18F2550 zu dem ATMEGA32 
aufbauen. Der ATMEGA32 ist der Hauptcontroller auf dem RP6. Der 
Hersteller liefert ein fertiges Slave Programm für den ATMEGA mit, mit 
dem es möglich sein soll alles über einen zweiten Controller als Master 
steuern zu lassen.

Also der PIC ist mein Master und der Atmel der Slave. Und mein Vorhaben 
zunächst ist, die digitalisierten Akku Werte aus dem Atmel zu laden 
(möchte diese an meinem LCD am PIC ausgeben). Es scheint leider nicht zu 
funktionieren. Meine Variablen bleiben leer (debugge mit ICD2).

Hier einmal mein kompletter main.c Code:
1
**********************************************************************************************/
2
//  Include Dateien
3
/**********************************************************************************************/
4

5
#include <p18cxxx.h>         // Für den PIC - wird autom. erkannt
6
#include "delays.h"                  // Für die Warteschleife
7
#include "RP6.X/lcd.h"
8
#include "RP6.X/adu.h"
9
#include "../h/i2c.h"
10

11
/**********************************************************************************************/
12
//  Konfiguration
13
/**********************************************************************************************/
14

15
#pragma config FOSC = HS      // Taktbereich auswählen
16
#pragma config PWRT = ON      // Power On Timer An
17
#pragma config BOR = OFF      // Brown Out Reset Aus
18
#pragma config WDT = OFF        // Watchdog Timer Aus
19
#pragma config LVP = OFF      // Low Voltage Programming Disable
20
#pragma config PBADEN = OFF      //
21
#pragma config VREGEN = OFF      //
22
#pragma config MCLRE = ON      // Master Clear Reset An
23

24
/**********************************************************************************************/
25
//  Globale Variablen deklarieren
26
/**********************************************************************************************/
27

28
unsigned char i;
29
unsigned char Akku[3];
30

31
/**********************************************************************************************/
32
//  Hauptprogramm
33
/**********************************************************************************************/
34

35
void main(void)
36
{
37
    unsigned char i;
38

39
    for(i=0;i<3;i++)Akku[i]=0;
40

41
// Konfiguration
42
    LATA=LATB=LATC=0;               //
43
    TRISA = 0x01;                   // PA1  --> Input Rest --> Output
44
    TRISB = 0x00;                   // Alle --> Output
45
    TRISC = 0x00;                   // Alle --> Output
46

47
    Setup_ADC();                    // AD Wandler Konfigurieren
48
    Init_LCD();                     // LCD Initialisieren
49
    OpenI2C(MASTER,SLEW_OFF);       // IIC Bus konfigurieren
50
    SSPADD=19;                      // 100kHz=8MHz/4*(SSPADD+1)
51

52
    while(1)
53
    {
54
        //I2C
55
        IdleI2C();
56
        StartI2C();                         //Start I2C
57
        WriteI2C(0x0A|0x00);                //Adresse senden (nächster Befehl schreibend)
58
        while(WriteI2C(0x15)!=0);           //Schreiben
59
        IdleI2C();                          //
60
        RestartI2C();                       //
61
        IdleI2C();                          //
62
        WriteI2C(0x0A|0x01);                //Adresse senden (nächster Befehl lesend)
63
        getsI2C(Akku,2);                    //Lesen und Ergebnis in Akku
64
        Akku[2]='\0';                       //Abschluss '0'
65
        NotAckI2C();                        //Not acknowledge
66
        while( SSPCON2bits.ACKEN!=0);       //
67
        CloseI2C();                         //I2C beenden
68

69
        //ADC
70
        Read_ADC(0);                        //Analog - Digital Pin auslesen
71
    }
72
}

Btw.: Ich benutze MPLAB X und den C18 Compiler.


Das Slave Programm vom Atmel ist im Anhang.

Viele Grüße Nico
Angehängte Dateien:
#2322992
Lesenswert?

Man schreibt beim I2C nicht einfach so ins Blaue hinein.
Du mußt nach jedem Adresse/Daten schreiben prüfen, ob ein ACK kommt.

Beim Lesen sendet der Master nach jedem Byte ein ACK und nach dem 
letzten Byte ein NACK.

Der Master muß das SCL-Stretching beherrschen.


Peter
OP Persönliche Seite #2322998
Lesenswert?

Hallo Peter,
das stimmt.. Meine Aussage vor voreilig. Das ACK Bit wird nämlich nicht 
gesendet (warum auch immer).

Edit:
1
IdleI2C();
2
StartI2C();              //Start I2C
3
Data = SSPBUF;            //read any previous stored content in buffer to clear buffer full status
4

5
do
6
{
7
  Status = WriteI2C(0x0A|0x00);  //Adresse senden bis..
8
  if(Status == -1)                //Bus Kollision?
9
  {
10
    Data = SSPBUF;        //upon bus collision detection clear the buffer,
11
    SSPCON1bits.WCOL=0;         //Bus Kollisions Bit löschen
12
  }
13
}
14
while(Status!=0);                    //..die Übertragung erfolgreich war
Angehängte Dateien:
OP Persönliche Seite #2323636
Lesenswert?

Nabend zusammen,
konnte mich jetzt erst zurück melden war unterwegs. Also nach einiger 
Recherche bin ich auf das 
(http://www.roboternetz.de/community/threads/54623-%DCber-I2C-den-Akkuwert-aus-dem-Atmel-auslesen/page2?p=523311) 
gestoßen. Hier wird berichtet, dass die Adresse fälschlicherweise nicht 
dez. 10 sondern dez. 5 ist. Allerdings hat das nicht geholfen.

Ich werde jetzt wirklich mal alle Adressen durch probieren.

Gruß Nico

Edit: Stop mal, wenn die ADR dez. 5 ist, dann ist das 8.Bit ja "1" 
sprich der Controller gibt Daten zum Lesen bereit.. Dürfen I2C Bausteine 
denn nicht nur gerade Adressen haben?
Gast #2323657
Lesenswert?

>Edit: Stop mal, wenn die ADR dez. 5 ist, dann ist das 8.Bit ja "1"
>sprich der Controller gibt Daten zum Lesen bereit.. Dürfen I2C Bausteine
>denn nicht nur gerade Adressen haben?

Was meinst du warum ich dir oben das mit dem links schieben
empfohlen habe? Die I2C Adresse ist in den oberen sieben Bit.
OP Persönliche Seite #2323733
Lesenswert?

=) So ich habe mal eine ältere Version des Slave Programms für den AVR 
herunter geladen, hier ist der Adressfehler noch nicht vorhanden. Jetzt 
läuft es wie folgt ab:

-> Adressierung
<- ACK
-> Senden 22 (High Register Akku)
-> Adressierung +1
<- ACK
<- Empfange FFh (das wird falsch sein ist auch FFh wenn ich den Low Wert 
auslese)

Das ausgelesene Byte muss falsch sein, da der Akkuwert sich iwo im 
Bereich von dez.: 720 bewegen muss. Was kann jetzt noch falsch sein?

Hier die Übertragung:
1
        IdleI2C();
2
        StartI2C();                         //Start I2C
3
       
4
        Data = SSPBUF;                      //read any previous stored content in buffer to clear buffer full status
5
        do
6
  {
7
  Status = WriteI2C(ADR|0x00);        //Adresse senden bis..
8
            if(Status == -1)                //Bus Kollision?
9
            {
10
                Data = SSPBUF;              //upon bus collision detection clear the buffer,
11
                SSPCON1bits.WCOL=0;         //Bus Kollisions Bit löschen
12
            }
13
  }
14
        while(Status!=0);                   //..die Übertragung erfolgreich war
15
        
16
        WriteI2C(22);                       //Dezimal: 22 Schreiben
17
        WriteI2C(ADR|0x01);                 //Adresse senden (nächster Befehl lesend)
18
        AKKUH=ReadI2C();                    //Lesen und Ergebnis in Akku
19
        IdleI2C();
20
        CloseI2C();                         //I2C beenden

PS: Habe zum Testen erst mal nur das High Register ausgelesen.

Gruß Nico

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren