Librería I2C de MikroC ?

Muy buenas tardes a todos y gracias por estar siempre ahí.

Resulta que necesito controlar un DS1881.
La comunicación con Arduino es efectiva, pero una vez lo intento con PIC no obtengo ningún resultado.
Se me ocurrió que podría comparar las transmisiones con los osciloscopios de Proteus y efectivamente aunque el 16F887 emite, no tienen nada que ver con el ATmega.

Los códigos usados respectivamente para Arduino y MikroC for PIC son los siguientes:

Arduino
PHP:
#include <Wire.h>
  void setup(){
  Wire.begin();
}

void loop(){  
delay(500);
  Wire.beginTransmission(0x28);  // if you have only one pot, just ground all three address lines and use this address
  Wire.write(B00000000 | 0);  // technically not necessary to or these together, just use pot0Val
  Wire.endTransmission(); 
delay(500);
}
MikroC
PHP:
void main(){
   ANSEL  = 0;                // Configure AN pins as digital I/O
   ANSELH = 0;
   PORTB = 0;
   TRISB = 0;                    // Configure PORTB as output
 I2C1_Init(100000);          // initialize I2C communication
       while(1){
delay_ms(500);
   I2C1_Start();                // issue I2C start signal
   I2C1_Wr(0x28);            // send byte via I2C  (device address + W)
   I2C1_Wr(0b00000000); // send byte (address of EEPROM location)
   I2C1_Wr(0);                 // send data (data to be written)
   I2C1_Stop();                // issue I2C stop signal
delay_ms(500);

}}
(El objetivo de que ambos programas se encuentren dentro de un bucle, es solo para facilitar la comprensión de los osciloscopios)

Lo que logro entender de la explicación de la biblioteca de MikroC, es que:
I2C1_Wr primero dirección del dispositivo
I2C1_Wr segundo especificación en el dispositivo
I2C1_Wr tercero valor a cargar

¿Es esto correcto ?
¿Dónde se encuentra la diferencia entre los programas?

Adjunto foto de Proteus.
Muchas gracias, saludos.
 

Adjuntos

  • Sin título.jpg
    Sin título.jpg
    101 KB · Visitas: 21
Última edición por un moderador:
soy Yo o me parece que en ésta linea hay un número decimal (enorme) , donde probablemente iría un binario no mayor a 255.

I2C1_Init(100000); // initialize I2C communication
 
Sabes que es (B00000000 | 0)?
Básicamente haces OR, que no es lo mismo ya que significa el dato de un byte o otro pero igual envías 0x00, mientras que en tu código Pic envías 2 bytes 0x0000 en realidad
 
Después de romperme mucho la cabeza sigo sin encontrar el problema.
decidí seguir la ejemplificación de MikroC al dedillo, agregando solamente una lcd y la conversión de variables para poder ver el resultado de la manera más fácil. Incluso acudí a un tutorial que hacia exactamente lo que yo.

resultados = 0

Código:
 // LCD module connections
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections

unsigned short lectura = 0x00;
char txt1[4];


void main(){
  ANSEL  = 0;                // Configure AN pins as digital I/O
  ANSELH = 0;
  PORTB = 0;
  TRISB = 0;                 // Configure PORTB as output

  
  Lcd_Init();                        // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);               // Clear display
  Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off



  I2C1_Init(100000);         // initialize I2C communication
  I2C1_Start();              // issue I2C start signal
  I2C1_Wr(0xA2);             // send byte via I2C  (device address + W)
  I2C1_Wr(2);                // send byte (address of EEPROM location)
  I2C1_Wr(0xAA);             // send data (data to be written)
  I2C1_Stop();               // issue I2C stop signal

  Delay_100ms();

  I2C1_Start();              // issue I2C start signal
  I2C1_Wr(0xA2);             // send byte via I2C  (device address + W)
  I2C1_Wr(2);                // send byte (data address)
  I2C1_Repeated_Start();     // issue I2C signal repeated start
  I2C1_Wr(0xA3);             // send byte (device address + R)
  lectura = I2C1_Rd(0u);       // Read the data (NO acknowledge)
  I2C1_Stop();               // issue I2C stop signal



  IntToStr(lectura, txt1);

  Lcd_Out(1,2,txt1);


}//main

Los datos enviados a la memoria no son para nada los que recibo de ella.
El reloj está a 4 MHz y la emisión del I2C a 100000Hz justo como el tutorial, la diferencia, a WR Kits le funciona.
También he probado cambiar las frecuencias de reloj y transmisión y nada

gracias a todos por responder
Si tenéis alguna otra solución o idea de dónde se aloja mi error, por favor, Háganmelo saber.
saludos
 

Adjuntos

  • Sin título.jpg
    Sin título.jpg
    99.2 KB · Visitas: 25
Última edición:
La ventaja de utilizar soft original es que cuando tenes esto problemas vas a la asistencia técnica y te brindan toda la ayuda, pero incluso podes consultar el foro de Microe. Porque he visto utilizar I2C con Mikroe sin ningún problema, en casa debo tener algo sobre eso, pero ahora estoy a 100km de allí
 
Hola, hace algun tiempo que vengo estudiado la posibilidad de usar el protocolo I2C, el problema es que muchos pics lo incorporan ya en el propio chip, por lo que se pierden otras funcionalidades como el protocolo SPI, chips por ejemplo como algunos de Silicon Labs como el si4713 implementan cualquiera de los 2, para no tener que sacrificar ninguno de los 2 la mejor elección es implementarlo por software, asi con solo asignar los 2 pines SCL y SDA se puede mover a cualquier pin y puerto de E/S la técnica usada suele ser Bit-banging con esto se hace universal y tansportable a cualquier marca y modelo de microcontrolador y evitamos en lo posible el uso de librerias propietarias que limitan que se puedan portar a otros compiladores, en esta página teneis una solución de libreria I2C por software para un micro PIC16F628A, pero la he probado con un PIC18F2550 y compilador Hi-Tech y funciona perfectamente, es de suponer que declarando los pines que queramos en MikroC debera funcionar sin problema.

Saeed's Blog: PIC16F628A i2c (bit banging) code + Proteus simulation

Un saludo
Mensaje automáticamente combinado:

Una cosa que debeis modificar tambien es la parte de los delays y adaptarlos a MikroC, de lo contrario daria error logicamente y quitar la libreria #include <htc.h> de Hi-Tech, tambien se podria implementar para XC8 cambiando a #include <xc.h>
 
Última edición:
Aunque se use el mismo módulo SSP (Synchronous Serial Port) para I2C y SPI, nada impide que puedan ser usados conjuntamente, o sea, en modo compartido.
Cada dispositivo responderá a su protocolo, no importando que compartan sus líneas.
Obviamente leerás o escribirás uno por uno, a fin de cuentas el microcontrolador es secuencial.
También puedes usar pseudo multitasking con RTOS para sincronizar los procesos.
 
Atrás
Arriba