0
\$\begingroup\$

I am trying to to use I2C to communicate with a sensor. I have a 2.2k pull-up resistors to a 3.3V supply for my SDA/SCL. The microcontroller I am using is a PIC16F18324. In my tests I do not have the slave connected. Apparently, my SDA line is being pulled low by the microcontroller and I am unable to transmit any data through the lines.

Here are two references I have been using: https://www.8051projects.net/wiki/I2C_Implementation_on_PIC https://electrosome.com/i2c-pic-microcontroller-mplab-xc8/

#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);

    }
}
\$\endgroup\$
  • \$\begingroup\$ TRISC = 1 only sets RC0 as a tri-stated input. Try changing that to TRISC = 0b11 instead. \$\endgroup\$ – Roger Rowland Mar 28 '17 at 6:54
  • \$\begingroup\$ Ah whoops I messed that up. That actually fixed my pull down problem. However, I still cannot see any being transmitted on the line. \$\endgroup\$ – Kevin Ly Mar 29 '17 at 2:06
1
\$\begingroup\$

I2C_Master_Write(0x05); //7 bit address + Write

Check this line , instead of writing the value you are reading the value.

\$\endgroup\$
0
\$\begingroup\$

The problem is on the line ACKDT = (a)?0:1;. Try ACKDT = 1; instead.

/*********************************************************************/
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;
   }
\$\endgroup\$
0
\$\begingroup\$

Here is another problem:

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

Only RC0 is an input. Try this:

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

And please remember to switch the port to digital:

ANSELC = 0x00; // Enable TrisC RC0-SCL/RC1-SDA
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.