Estoy intentando implementar el Circuito Inter-Integrado (I2C) del STM32F3 Discovery Board para comunicarme con 2 esclavos (arduino) en mi proyecto. Sin embargo, no puedo enviar ningún dato a arduino.
Aquí está mi codificación:
void I2CInit(I2C_TypeDef* I2Cx){
if (I2Cx == I2C1){
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_OwnAddress1 = 0x2F;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing = 0xA061191F;
I2C_Init(I2C1,&I2C_InitStructure);
I2C_Cmd(I2C1,ENABLE);
I2C_AcknowledgeConfig(I2C1,ENABLE);
I2C_Init(I2C1,&I2C_InitStructure);
I2C_Cmd(I2C1,ENABLE);
}
else {
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure1.GPIO_OType = GPIO_OType_OD ;
GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA,&GPIO_InitStructure1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_4);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_4);
I2C_DeInit(I2C2);
I2C_InitStructure1.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure1.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure1.I2C_DigitalFilter = 0x00;
I2C_InitStructure1.I2C_OwnAddress1 = 0x01;
I2C_InitStructure1.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure1.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure1.I2C_Timing =0x00902025;
I2C_Init(I2C2,&I2C_InitStructure1);
I2C_Cmd(I2C2,ENABLE);
I2C_AcknowledgeConfig(I2C2,ENABLE);
I2C_Init(I2C2,&I2C_InitStructure);
I2C_Cmd(I2C2,ENABLE);
}
}
Pienso que he hecho la configuración I2C correctamente. Por lo tanto, creo que el problema probablemente proviene del I2Cx_Write ().
Test_Status I2Cx_Write(I2C_TypeDef* I2Cx, uint8_t *buff, uint32_t nbyte, uint8_t SlaveAddr){
/*--------Test on BUSY Flag-------------*/
__IO uint32_t timeout = 0xFFFF;
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)!=RESET)
{
if (timeout-- == 0) return Error;
}
I2C_TransferHandling(I2Cx,SlaveAddr,nbyte,I2C_AutoEnd_Mode,I2C_Generate_Start_Write);
while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_TXIS)== RESET);
{
if((timeout--) == 0) return Error;
}
while(nbyte){
I2C_SendData(I2Cx, *buff++);
GPIOE->ODR |= 1L << 11;
while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_TXE) == RESET);
nbyte-- ;
}
I2C_GenerateSTOP(I2Cx, ENABLE);
while(I2C_GetFlagStatus(I2Cx,I2C_FLAG_STOPF) == RESET)
{
if((timeout--) == 0) return Error;
}
return Success;
}
Codificación para Arduino:
#include <Wire.h>
void setup()
{
Wire.begin(8);
Wire.onReceive(receiveEvent);
Serial.begin(115200);
}
void loop()
{
delay(100);
}
void receiveEvent(int howMany)
{
while (1 < Wire.available())
{
char c = Wire.read();
Serial.print(c);
}
int x = Wire.read();
Serial.println(x);
}
Estaré muy agradecido si alguien me puede ayudar a detectar el problema.
Editar # 1
Intenté usar I2C1 e I2C2 de STM32F3.
Editar # 2
En realidad, está bien si coloca la I2C_OwnAddress, no afecta al STM32 como maestro en la comunicación I2C. Solo establezca cualquier número. p.ej. Establecí la I2C_OwnAddress = 0x2F; Solo lo configuras correctamente cuando lo usas como esclavo.
Editar # 3
Alguna información extra:
Conexión de cables:
I2C1:
PB6 - SCL
PB7 - SDA
I2C2:
PA9 - SCL
PA10 - SDA
* Recuerde la conexión a tierra común entre los dispositivos I2C.