Tengo un problema al utilizar I2C en un dsPIC33EP512MU810. Utilizo la biblioteca periférica para PIC24 y dsPIC33 para administrar los registros, pero también escribí algunas funciones. Estas son las funciones que utilizo para I2C
#include <xc.h>
#include <stdint.h>
#include "I2C1.h"
#include <i2c.h>
#include <libpic30.h>
#include "common.h"
void Open_I2C1(void)
{
// Configre SCA/SDA pin as open-drain. This may change from device to device.
//Refer the datasheet for more information.
ODCDbits.ODCD9 = 0;
ODCDbits.ODCD10 = 0;
OpenI2C1((I2C2_ON & I2C2_IDLE_CON & I2C2_CLK_HLD & I2C2_IPMI_DIS &
I2C2_7BIT_ADD & I2C2_SLW_EN & I2C2_SM_DIS &
I2C2_GCALL_DIS & I2C2_STR_DIS &
I2C2_NACK & I2C2_ACK_DIS & I2C2_RCV_DIS &
I2C2_STOP_DIS & I2C2_RESTART_DIS &
I2C2_START_DIS), 0x4E);
IdleI2C1();
I2C1CONbits.I2CEN = 1;
IEC1bits.MI2C1IE = 1;
IFS1bits.MI2C1IF = 0;
}
void WriteByte_I2C1(unsigned char WriteAddressIC, unsigned char WriteAddressRegister, uint8_t MSByte, uint8_t LSByte)
{
ResetVariables_I2C1();
Start_I2C1();
while(!IFS1bits.MI2C1IF);
IFS1bits.MI2C1IF=0;
//Write Slave address and set master for transmission
MasterWriteI2C1(WriteAddressIC);
WaitFlag_I2C1();
WaitForACK_I2C1();
MasterWriteI2C1(WriteAddressRegister);
WaitFlag_I2C1();
WaitForACK_I2C1();
MasterWriteI2C1(MSByte);
WaitFlag_I2C1();
WaitForACK_I2C1();
MasterWriteI2C1(LSByte);
WaitFlag_I2C1();
WaitForACK_I2C1();
ResetVariables_I2C1();
StopI2C1();
WaitFlag_I2C1();
WaitForACK_I2C1();
IdleI2C1();
}
uint16_t ReadByte_I2C1 (unsigned char ReadAddressIC, unsigned char RegisterAddress)
{
uint8_t Byte = 0x00;
uint16_t result = 0x0000;
ResetVariables_I2C1();
Start_I2C1();
while((!IFS1bits.MI2C1IF)) {
}
//Write Slave address and set master for transmission
MasterWriteI2C1(ReadAddressIC);
WaitFlag_I2C1();
WaitForACK_I2C1();
MasterWriteI2C1(RegisterAddress);
WaitFlag_I2C1();
WaitForACK_I2C1();
ResetVariables_I2C1();
RestartI2C1();
WaitFlag_I2C1();
MasterWriteI2C1(ReadAddressIC + 1);
WaitFlag_I2C1();
WaitForACK_I2C1();
ResetVariables_I2C1();
I2C1CONbits.RCEN = 1;
while(I2C1CONbits.RCEN)
{
LATCbits.LATC2 ^= 1;
}
I2C1STATbits.I2COV = 0;
Byte = I2C1RCV;
result = Byte<<8;
WaitFlag_I2C1();
I2C1CONbits.RCEN = 1;
while(I2C1CONbits.RCEN)
{
LATCbits.LATC2 ^= 1;
}
I2C1STATbits.I2COV = 0;
Byte = I2C1RCV;
result |= Byte;
WaitFlag_I2C1();
ResetVariables_I2C1();
NotAckI2C1();
WaitFlag_I2C1();
ResetVariables_I2C1();
StopI2C1();
WaitFlag_I2C1();
IdleI2C1();
return Byte;
}
void ResetVariables_I2C1(void)
{
I2C1CONbits.ACKEN=0;
I2C1CONbits.PEN=0;
I2C1CONbits.RCEN=0;
I2C1CONbits.RSEN=0;
I2C1CONbits.SEN=0;
}
void WaitFlag_I2C1(void)
{
while(!IFS1bits.MI2C1IF);
LATCbits.LATC2 ^=1; // wait for flag to be high
IFS1bits.MI2C1IF=0;
}
void WaitForACK_I2C1(void)
{
while(I2C1STATbits.ACKSTAT); // wait for ack receive from slave
LATCbits.LATC2 ^=1;
}
void Start_I2C1(void){
I2C1CONbits.SEN = 1;
}
Cuando uso la función de escritura, la función se detiene justo después de enviar la condición de inicio porque la bandera nunca se establece. Lo medí por la buena y antigua técnica de pasos de LED, donde enciendo un LED después de cada paso para ver cuándo se detiene. También eché un vistazo a las líneas SDA y SCL con un osciloscopio y solo puedo ver las condiciones de inicio. También revisé la configuración de mi hardware, por ejemplo. está todo conectado, no hay cortocircuitos o casi cortocircuitos y se comprueba si puedo usar otros dispositivos para comunicarme con el IC con el que quiero hablar con el dsPIC33. También verifiqué si uso los pines correctos. Uso ASD1 / RD9 y ASCL1 / RD10, lo que significa que tengo que configurar 'ALTI2C1 = ON' en los bits de configuración.
Pero ahora se me acabaron las ideas de lo que podría ser que hiciera mal aquí y por qué la bandera no se está levantando. Le agradecería que alguien me indicara la dirección correcta aquí