i2c mehrere Daten schicken



  • Hallo zusammen

    Ich habe eine i2c_Write Funktion geschrieben.

    Es handelt sich dabei um den PIC18F66K80.
    Ich weiss nicht, aber wie mache ich das am Besten, wenn ich nun aber mehrere Daten schicken muss ohne die Funktion x mal aufzurufen?
    mit Pointern?

    i2c.h Mastermode

    #ifndef	_I2C_H_
    #define _I2C_H_
    
    #define SlaveAddressTempSensorRead                                0x10010001
    #define SlaveAddressTempSensorWrite                               0x10010000
    #define i2C_SSPADD                                                SSPADD
    
    #define INPUT                                                     1
    #define OUTPUT                                                    0
    
    #define High                                                      1
    #define Low                                                       0
    
    #define Enabled                                                   1
    #define Disabled                                                  0
    
    #define I2C_SCL_PORTC3                                            TRISCbits.TRISC3
    #define I2C_SDA_PORTC4                                            TRISCbits.TRISC4
    #define SlewRateControl                                           SSPSTATbits.SMP
    #define ActivateI2C                                               SSPCON1bits.SSPEN
    #define ClockStreching                                            SSPCON1bits.CKP
    #define GeneralCallAdress                                         SSPCON2bits.GCEN
    #define StrechEnableBit                                           SSPCON2bits.SEN
    #define GeneralInterrupEnable                                     INTCONbits.GIEH
    
    #define i2c_MasterMode()                                          SSPCON1bits.SSPM3 = High; SSPCON1bits.SSPM2 = Low; SSPCON1bits.SSPM1 = Low; SSPCON1bits.SSPM0 = Low
    #define i2c_SlaveMode10bit()                                      SSPCON1bits.SSPM3 = Low; SSPCON1bits.SSPM2 = High; SSPCON1bits.SSPM1 = High; SSPCON1bits.SSPM0 = High
    #define i2c_SlaveMode7bit()                                       SSPCON1bits.SSPM3 = Low; SSPCON1bits.SSPM2 = High; SSPCON1bits.SSPM1 = High; SSPCON1bits.SSPM0 = Low
    #define i2c_EnablePeripheralInterrupt()                           RCONbits.IPEN = High; INTCONbits.PEIE = High
    #define i2c_GeneralInterrupt                                      INTCONbits.GIEH
    #define i2c_ACKSTAT                                               SSPCON2bits.ACKSTAT
    #define i2c_ACKDT                                                 SSPCON2bits.ACKDT
    #define i2c_Buffer                                                SSPBUF                                                    
    
    // SSPCON2 Control Bits
    #define i2c_Start()                                               SSPCON2bits.SEN = High
    #define i2c_StartInProgress                                       SSPCON2bits.SEN
    #define i2c_Stop()                                                SSPCON2bits.PEN = High
    #define i2c_StopInProgress                                        SSPCON2bits.PEN
    #define i2c_EnableReceiveMode()                                   SSPCON2bits.RCEN = High
    #define i2c_DisableReceiveMode()                                  SSPCON2bits.RCEN = Low
    #define i2c_EnableACK()                                           SSPCON2bits.ACKEN = High                                          
    #define i2c_RepeatedStart()                                       SSPCON2bits.RSEN = High
    
    // Interrupts
    #define i2c_ClearInterruptFlag()                                  PIR1bits.SSPIF = Low
    #define i2c_InterruptFlagcleared                                 !PIR1bits.SSPIF
    
    #define i2c_ReadWriteInterruptPriority                            IPR1bits.SSPIP                           
    #define i2c_MSSPPriority                                          PIE1bits.SSPIE
    
    void i2c_Init(void);
    void i2c_Read(char SlaveAdd);      
    void i2c_Write(char SlaveAdd, char Data); 
    
    #endif			/* _I2C_H_ */
    

    i2c.c Mastermode

    #include	<pic18.h>
    
    #include	"delay.h"
    #include 	"i2c.h"
    #include 	"lcd.h"
    
    void i2c_Init(void)
    {
        //*************************************************
        ActivateI2C = Enabled;                                                    // enables the operation of I2C
        SlewRateControl = Disabled;                                               // high speed mode, 400khz, depending on pull-up resistors
        ClockStreching = Enabled;                                                 // clock stretching disabled
        //*************************************************
        i2c_MasterMode();
        //*************************************************
        // Interrupt priority bits
        i2c_ReadWriteInterruptPriority = High;
        i2c_MSSPPriority = High;                                                  
        i2c_EnablePeripheralInterrupt();
        //*************************************************
        i2C_SSPADD = 0x04;                                                        // 100kHz I2C Clock with Fosc 2 MHz -> I2C Clock = Fosc/ (4*(SSPADD+1)
        //*************************************************
        i2c_GeneralInterrupt = Enabled;
    }
    
    void i2c_Write(char SlaveAdd, char Data)
    {
    
        i2c_Start();                                                              // Initiate the Start condition
        while(i2c_StartInProgress);                                               // Wait until Start condition is over
        i2c_ClearInterruptFlag();                                                 // clear SSP Interrupt Flag
    
        i2c_Buffer = SlaveAdd;                                                    // Send the Slave Address and R/W bit
        while(i2c_InterruptFlagcleared);
        i2c_ClearInterruptFlag();                                                 // clear SSP Interrupt Flag
        if(i2c_ACKSTAT)                                                           // check Acknowledge from slave
        {
            i2c_Stop();                                                           // Initiate Stop condition
            while(i2c_StopInProgress);                                            // Wait until Stop condition is over                                         
            lcdWriteStringXY(0,0,"Error: The communication wasn't successful!");  // Errormessage 
            return;                                                               // Exit Write
        }
    
        i2c_Buffer = Data;                                                        // Send Data
        i2c_ClearInterruptFlag();                                                 // clear SSP Interrupt Flag
        while(!i2c_InterruptFlagcleared);
        if(i2c_ACKSTAT)                                                           // check Acknowledge from slave
        {
            i2c_Stop();                                                           // Initiate Stop condition
            while(i2c_StopInProgress);                                            // Wait until Stop condition is over                                         
            lcdWriteStringXY(0,0,"Error: The communication wasn't successful!");  // Errormessage 
            return;                                                               // Exit Write
        }
    
        i2c_Stop();                                                              // Initiate the Stop condition
        while(i2c_StopInProgress);                                               // Wait until Start condition is over 
    }
    


  • buell schrieb:

    Ich weiss nicht, aber wie mache ich das am Besten, wenn ich nun aber mehrere Daten schicken muss ohne die Funktion x mal aufzurufen?
    mit Pointern?

    Da die Daten meist in einem Array (oder zusammenhängenden Speicher) vorliegen, wäre das ganz sinnvoll.

    ~Wenn du aber spezielle Fragen zu I²C hast, bist du hier schlecht aufgehoben.~



  • Furchtbarer globale Variablen/Makro Schrott.



  • DirkB schrieb:

    buell schrieb:

    Ich weiss nicht, aber wie mache ich das am Besten, wenn ich nun aber mehrere Daten schicken muss ohne die Funktion x mal aufzurufen?
    mit Pointern?

    Da die Daten meist in einem Array (oder zusammenhängenden Speicher) vorliegen, wäre das ganz sinnvoll.

    ~Wenn du aber spezielle Fragen zu I²C hast, bist du hier schlecht aufgehoben.~

    Nein zum i2c nicht.
    Gibt es etwas was zu verbessern ware am Code?



  • Auf die Schnelle:

    Wohin gehen die gelesenen Daten bei void i2c_Read(char SlaveAdd); ?

    Die rufende Funktion sollte auch über Fehler Bescheid wissen.

    (Das lcdWriteStringXY(0,0,"Error: The communication wasn't successful!"); hat in der Funktion nichts zu suchen.)



  • Hallo Dirk

    die erste und zweite frage versteh ich nicht.
    ich habe ja gar kein read. was ist bei dir die rufende fkt?

    wieso hat lcd write in der fkt nichts zu suchen. wo soll es sonst hin. ich frage ja das acknowlegde ab und wenn es nicht kommt ist etwas schief gelaufen. ein return alleine waere ja zu wenig und es wuerde stillschweigend abbrechen

    und warum sind die globalen variablen und makros nicht gut?



  • buell schrieb:

    ich habe ja gar kein read.

    In der i2c.h ist aber eins deklariert.
    Mit void als Rückgabetyp und nur einer Geräte-Adresse als Parameter.

    buell schrieb:

    was ist bei dir die rufende fkt?

    Die Funktion, die z.B i2c_Read aufruft.
    Wie soll die an die gelesenen Daten ran kommen?

    buell schrieb:

    wieso hat lcd write in der fkt nichts zu suchen. wo soll es sonst hin. ich frage ja das acknowlegde ab und wenn es nicht kommt ist etwas schief gelaufen. ein return alleine waere ja zu wenig und es wuerde stillschweigend abbrechen

    Dann braucht das return noch einen Parameter.
    Oder du übergibst noch einen weiteren Parameter für den Fehlerzustand (dann als Zeiger).
    Eine globale Fehlervariable wäre auch noch möglich (siehe errno : http://www.cplusplus.com/reference/cerrno/errno/?kw=errno)

    Die Funktion i2c_write ist nicht für die Userkommunikation da (schon vom Namen her nicht). Das macht dann eine der rufenden Funktionen.

    buell schrieb:

    und warum sind die globalen variablen und makros nicht gut?

    Bei globalen Variablen verliert man leicht den Überblick, wann und wo dises verändert werden.
    Der Code kann auch nicht nochmal innerhalb der Funktion aufgerufen werden. (wenn z.B. lcdWriteStringXY auch pber I2C funktionieren würde)

    So wie ich das sehe, sind das aber Register, bzw. Registerzugriffe. Da muss man dann den globalen Tod sterben.


Log in to reply