Estoy implementando una forma de transferir datos usando el protocolo I2C entre PIC32mx y Arduino Uno. Decidí establecer PIC como maestro y Arduino como esclavo . Pasé por todas las definiciones y configuraciones para el I2C en el PIC porque ya lo tengo funcionando perfectamente con un barómetro. Consideremos al Arduino como un esclavo más en este protocolo. Entonces, desde el lado maestro de PIC tengo el siguiente código
#define EEPROM_I2C_BUS I2C1
#define i2d_address 0x14
#define I2C_CLOCK_FREQ 5000
BOOL BarI2CTransmitOneByte( UINT8 data )
{
// Wait for the transmitter to be ready
while(G_RUNNING && !I2CTransmitterIsReady(EEPROM_I2C_BUS));
// Transmit the byte
if(I2CSendByte(EEPROM_I2C_BUS, data) == I2C_MASTER_BUS_COLLISION)
{
DBPRINTF("Error: I2C Master Bus Collision\n");
return FALSE;
}
// Wait for the transmission to finish
while(G_RUNNING && !I2CTransmissionHasCompleted(EEPROM_I2C_BUS));
return TRUE;
}
void BarI2CStopTransfer( void )
{
I2C_STATUS status;
// Send the Stop signal
I2CStop(EEPROM_I2C_BUS);
// Wait for the signal to complete
do
{
status = I2CGetStatus(EEPROM_I2C_BUS);
} while( G_RUNNING && !(status & I2C_STOP) );
}
BOOL BarI2CStartTransfer( BOOL restart )
{
I2C_STATUS status;
// // Send the Stop signal
// I2CStop(EEPROM_I2C_BUS);
// Send the Start (or Restart) signal
if(restart)
{
I2CRepeatStart(EEPROM_I2C_BUS);
}
else
{
// Wait for the bus to be idle, then start the transfer
while( G_RUNNING && !I2CBusIsIdle(EEPROM_I2C_BUS) );
if(I2CStart(EEPROM_I2C_BUS) != I2C_SUCCESS)
{
DBPRINTF("Error: Bus collision during transfer Start\n");
return FALSE;
}
}
// Wait for the signal to complete
do
{
status = I2CGetStatus(EEPROM_I2C_BUS);
} while ( !(status & I2C_START) );
return TRUE;
}
void main(){
UINT32 actualClock;
BOOL Success2 = TRUE;
actualClock = I2CSetFrequency(EEPROM_I2C_BUS, GetPeripheralClock(), I2C_CLOCK_FREQ);
if ( abs(actualClock-I2C_CLOCK_FREQ) > I2C_CLOCK_FREQ/10 )
{
//DBPRINTF("Error: I2C1 clock frequency (%u) error exceeds 10%%.\n", (unsigned)actualClock);
}
// Enable the I2C bus
I2CEnable(EEPROM_I2C_BUS, TRUE);
I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, i2d_address, I2C_WRITE);
i2cData[0] = SlaveAddress.byte;
i2cData[1] = 0x03; // EEPROM location to read (high address byte)
DataSz = 2;
if( !BarI2CStartTransfer(FALSE) )
{
while(G_RUNNING && 1);
}
Index = 0;
while(Success2 & (Index < DataSz) )
{
// Transmit a byte
if (BarI2CTransmitOneByte(i2cData[Index]))
{
// Advance to the next byte
Index++;
}
else
{
Success2 = FALSE;
}
// Verify that the byte was acknowledged
if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
{
DBPRINTF("Error: Sent byte was not acknowledged\n");
Success2 = FALSE;
}
}
BarI2CStopTransfer();
if(Success2)
{
// Send a Repeated Started condition
if( !BarI2CStartTransfer(FALSE) )
{
while(1);
}
// Transmit the address with the READ bit set
I2C_FORMAT_7_BIT_ADDRESS(SlaveAddress, i2d_address, I2C_READ);
if (BarI2CTransmitOneByte(SlaveAddress.byte))
{
// Verify that the byte was acknowledged
if(!I2CByteWasAcknowledged(EEPROM_I2C_BUS))
{
DBPRINTF("Error: Sent byte was not acknowledged\n");
Success2 = FALSE;
}
}
else
{
Success2 = FALSE;
}
}
// Read the data from the desired address
if(Success2)
{
if(I2CReceiverEnable(EEPROM_I2C_BUS, TRUE) == I2C_RECEIVE_OVERFLOW)
{
DBPRINTF("Error: I2C Receive Overflow\n");
Success2 = FALSE;
}
else
{
while(!I2CReceivedDataIsAvailable(EEPROM_I2C_BUS));
i2cbyte = I2CGetByte(EEPROM_I2C_BUS);
}
}
BarI2CStopTransfer();
if(!Success2)
{
while( G_RUNNING && 1);
}
Para el lado esclavo de Arduino , escribí el siguiente código:
void setup(void)
{
Wire.begin(20);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.begin(9600); // start serial comm
}
void receiveEvent(int howMany){
int x = Wire.read();
}
void requestEvent(){
Wire.write('x');
}
void loop(){
}
Entonces, desde el lado del PIC, estoy enviando el byte 0x03 que recibo en el método receiveEvent en el lado de Arduino. En este punto todo está funcionando bien. Después de eso, se llama a requestEvent y el carácter 'x' se envía al lado PIC. Ahora el lado PIC está bloqueando la DBPRINTF("Error: I2C Receive Overflow\n");
oración, lo que significa que estoy tardando demasiado en recibir el byte 'x' del lado Arduino y la línea SDA tampoco se libera.
Tengo pull ups en mi protocolo I2C a 3.3V ( Master-PIC ) y trato de comunicarme usando A4(SDA)
y A5(SCL)
en el lado Slave-Arduino que está a 5V. Estoy siguiendo este Tutorial cuidadosamente y tratando de replicar la parte de "Lectura de un esclavo" pero sin éxito.
EDITAR: estoy siguiendo el procedimiento y estoy recibiendo el byte correctamente desde el lado de arduino, sin embargo, el código está bloqueado en el RFIDI2CStopTransfer();
lado del PIC y no sé por qué. ¿Hay alguien que pueda ayudarme con este problema?
Parte del problema estaba relacionado con la dirección que utilicé para comunicarme con Arduino. Estaba usando 0x07 como dirección pero está reservado, así que cambié a 0x14 (20 en decimal). Sin embargo, he editado la publicación para obtener ayuda con este nuevo problema.
adam lorenzo
escafandra autónoma
SoreDakeNoKoto
escafandra autónoma
SoreDakeNoKoto
escafandra autónoma
escafandra autónoma
SoreDakeNoKoto
escafandra autónoma
SoreDakeNoKoto
SoreDakeNoKoto
escafandra autónoma
SoreDakeNoKoto
escafandra autónoma
SoreDakeNoKoto
escafandra autónoma
SoreDakeNoKoto
I2CAcknowledgeByte(EEPROM_I2C_BUS, FALSE); while (!I2CAcknowledgeHasCompleted(EEPROM_I2C_BUS));
despuésI2CGetByte()
y vuelva a intentarlo. Si se atasca, ¿dónde se atasca esta vez?