I2C en el microcontrolador PIC

0

Estoy intentando usar I2C para comunicarme con un sensor. Tengo un resistor de pull-up de 2.2k a un suministro de 3.3V para mi SDA / SCL. El microcontrolador que estoy usando es un PIC16F18324. En mis pruebas no tengo al esclavo conectado. Al parecer, el microcontrolador está agotando mi línea SDA y no puedo transmitir ningún dato a través de las líneas.

Aquí hay dos referencias que he estado usando: enlace enlace

#include <xc.h>
#include <stdint.h>
#include <stdbool.h>

#define _XTAL_FREQ  4000000 //4 Mhz

uint16_t count = 0;

void I2C_Master_Init(const unsigned long c)
{
    TRISC = 1; // Enable TrisC RC0-SCL/RC1-SDA

    SSP1STAT |= 0b10000000;
    SSP1CON1 = 0b00101000; //Configure for master mode
    SSP1CON2 = 0b00000000;
    SSPADD = (_XTAL_FREQ/(4*c))-1;
}

void I2C_Master_Wait()
{
  while ((SSP1STAT & 0b00000100) || (SSP1CON2 & 0x00011111)); //Check if busy
}

void I2C_Master_Start()
{
  //I2C_Master_Wait();    
  SEN = 1;             //Initiate start condition
  while(SEN);
}

void I2C_Master_RepeatedStart()
{
  //I2C_Master_Wait();
  RSEN = 1;           //Initiate repeated start condition
  while(RSEN);
}

void I2C_Master_Stop()
{
  //I2C_Master_Wait();
  PEN = 1;           //Initiate stop condition
  while(PEN);
}

void I2C_Master_Write(unsigned data)
{

  SSP1BUF = data;         //Write data to SSP1BUF
  while(BF);
  I2C_Master_Wait();
}

unsigned short I2C_Master_Read(unsigned short a)
{
  unsigned short temp;
  RCEN = 1;
  while(!BF);
  temp = SSP1BUF;      //Read data from SSP1BUF
  I2C_Master_Wait();
  ACKDT = (a)?0:1;    //Acknowledge bit
  ACKEN = 1;          //Acknowledge sequence
  return temp;
}

void main(void)
{     
    OSCCON1 = 0x60; // HFINTOSC   Higher, faster
    OSCFRQ = 0x03;  // HFFRQ 4_MHz; Enables 4Mhz for Register HFINTOSC

    I2C_Master_Init(100000); //Initialize I2C Master w/ 100Khz Clock

    while (1)
    {
        I2C_Master_Start();         //Start condition
        I2C_Master_Write(0x05);     //7 bit address + Write
        I2C_Master_Write(0xFF);     //Write data
        I2C_Master_Stop();          //Stop condition
        __delay_ms(200);

    }
}
    
pregunta Kevin Ly

2 respuestas

0

El problema está en la línea ACKDT = (a)?0:1; . Prueba ACKDT = 1; en su lugar.

/*********************************************************************/
void I2C_Master_Wait(void)
    {
   while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));
    }
/*********************************************************************/
void I2C_Master_Start(void)
    {
    I2C_Master_Wait();
    SEN = 1;
    }
/*******************************************************************/
void I2C_Master_Stop(void)
    {
    I2C_Master_Wait();
    PEN = 1;
    }
/******************************************************************/
unsigned unint8 I2C_Master_Read(unsigned short a)
   {
   unsigned unint8 temp;
   I2C_Master_Wait();
   RCEN = 1;
   I2C_Master_Wait();
   temp = SSPBUF;
   I2C_Master_Wait();
   //ACKDT = (a)?0:1; //This occurs problem
   ACKDT = 1;  //SHOULD TRY THIS
   ACKEN = 1;
   return temp;
   }
    
respondido por el Bulent
0

Aquí hay otro problema:

TRISC = 1; // Enable TrisC RC0-SCL/RC1-SDA

Solo RC0 es una entrada.  Prueba esto:

TRISC = 0x03; // Enable TrisC RC0-SCL/RC1-SDA

Y recuerde cambiar el puerto a digital:

ANSELC = 0x00; // Enable TrisC RC0-SCL/RC1-SDA
    
respondido por el Mike

Lea otras preguntas en las etiquetas