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.
Mitvoid
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 (sieheerrno
: 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.