Estoy trabajando con PIC24FJ192GB106 (paquete de 64 pines) y el módulo I2C me está volviendo loco.
aquí está el código:
int counter = 1;
address = 0b01110000; // ADD7 = 0111000 ; W = 0;
cmd1 = 0xFF;
cmd2 = 0xFF;
I2C1CONbits.I2CEN = 0; // turn off the I2C1 module
wait(100);
I2C1CON = 0x1000; // default settings of I2C1 module
wait(100);
I2C1BRG = 39; // set the baud-rate generator -> 100 kHz SCL, Fosc = 8 MHz
wait(100);
I2C1CONbits.I2CEN = 1; // start the I2C1 module
wait(100);
IFS1bits.MI2C1IF = 0; // clear interrupt flag (just to make sure)
(*)
I2C1CONbits.SEN = 1; // initiates Start condition
while (I2C1CONbits.SEN == 1 ){counter++;}; // wait until Start condition is executed
I2C1TRN = address; // send data
while (I2C1STATbits.TRSTAT == 1 ){counter++;}; // wait while data is being send + ignore ACK from slave
I2C1TRN = cmd1; // send data
while (I2C1STATbits.TRSTAT == 1 ){counter++;}; // wait while data is being send + ignore ACK from slave
I2C1TRN = cmd2; // send data
while (I2C1STATbits.TRSTAT == 1 ){counter++;}; // wait while data is being send + ignore ACK from slave
I2C1CONbits.PEN = 1; // initiates Stop condition
while (I2C1CONbits.PEN == 1 ){counter++;}; // wait until Stop condition is executed
TRISE = counter; // show counter on LEDs
A partir de (*) y EN NO-DE EL CÓDIGO ESTÁ EJECUTADO. No hay respuesta en los pines (medidos por un osciloscopio). El I2C1 está ubicado en los pines no removibles SCL1 - pin 44, SDA1 - pin 43. Se ha conectado un pull-up de 4.7 kOhm (3.3 V). También he intentado establecer los bits correspondientes en ODCD a 1 (pin digital) y 0 (drenaje abierto). TRISD está configurado para entrada (0xFF) (pero también he probado la opción de salida).
Sospecho que ninguno de los bits SEN, PEN y el registro I2C1TRN están activados, porque el "contador" sigue siendo el mismo valor. Teniendo en cuenta que el PIC tiene un reloj de 8MHZ y solo I2C de 100 kHz, tiene que haber tiempo para al menos un contador ++, mientras se espera.
¿Hay algo que pueda hacer? (Excepto cambiar el PIC). ¿Me he perdido algo? ¿Qué otras opciones de depuración tengo?
P.S. El PIC está bien por lo demás. Otros módulos (PWM, ADC, UART) funcionan perfectamente. El oscilador interno es (notablemente) preciso (medido en el osciloscopio en el pin del reloj de referencia). Todos los otros pines funcionan (registro portE).
P.S. 2
aquí están mis configuraciones para el PIC24
OSCCONbits.COSC = 0b111; // current oscillator selection bits // '111' FastRC Oscillator with Postscaler(FRCDIV)
OSCCONbits.NOSC = 0b111; // new oscillator selection bits
OSCCONbits.CLKLOCK = 1;// if FCKSM (config word) is disabled (then FCSM is disabled) the NO EFFECT //OSCCONbits.IOLOCK -> lock function
OSCCONbits.LOCK = 1; // PPL Lock Status bit // when OSCCON.COSC = any non PPL clock mode then NO EFFECT //OSCCONbits.CF -> to be READ in case FCSM has detected a failure (FCSM is disabled anyway)
OSCCONbits.LPOSCEN = 0; // Primary Oscillator Sleep Enable bit // [0] - Primary Osc continues during sleep mode
OSCCONbits.SOSCEN = 0; // Secondary Oscillator Enable bit // [0] - 32kHz Secondary Osc is disabled
OSCCONbits.OSWEN = 0; // Oscillator Switch Enable bit // [1]-changes from OSCCON.COSC to OSCCON.NOSC/[0]-nothing
CLKDIVbits.ROI = 0; // Recover on Interrupt bit // [0] - Interrupts have no effect on the DOZEN bit
CLKDIVbits.DOZE = 0b000; // CPU Peripheral Clock Ratio Select bits // [000] - 1:1
CLKDIVbits.DOZEN = 0; // DOZE Enable bit // [0] - CPU peripheral clock ratio is set to 1:1
CLKDIVbits.RCDIV = 0b000; // FRC Postscaler Select bits // [000] - 1:1