Hi,
I have written the c code for I2C for interfacing the SHT11(temp sensor) and PIC24F16KA102. but i m not getting the acknowledge from the SHT11 when i m writing through pic. i m pasting my code here. plz let me know where i m doing wrong if possible. thanks
#include <stdint.h>
#include <xc.h>
#include "main.h"
#include <p24Fxxxx.h>
// ICD Pin Placement Select (EMUC/EMUD share PGC3/PGD3)
//_FICD(ICS_PGx1)
/*
* File: main.c
* Author: jalpa
*
* Created on 7 February, 2014, 10:11 AM
*/
/*******************************************************************************************************************/
//Include section
/*******************************************************************************************************************/
#include "p24F16KA102.h"
#include "spi.h"
#include "i2c.h"
#include <timer.h>
/*******************************************************************************************************************/
//Define section
/*******************************************************************************************************************/
// for input use PORTBbits.RB7 notation and for output pin use LATBbits.LATB2.
//#define CE LATBbits.LATB2 //pin-6 // CE output pin, PORTB bit 2
//#define SDA_pin LATBbits.LATB9 //pin-22// Clock output pin, PORTB bit 11
//#define SCL_pin LATBbits.LATB8
//
//#define SDA_dir TRISBbits.TRISB9
//#define SCL_dir TRISBbits.TRISB8
/*******************************************************************************************************************/
//Declaration of variable
/*******************************************************************************************************************/
unsigned char msb;
unsigned char lsb;
unsigned char status;
/*******************************************************************************************************************/
//Declaration of functions
/*******************************************************************************************************************/
void i2c_init();
void reset_i2c_bus();
void delay_us(unsigned short us);
void i2c_start();
void i2c_restart();
char i2c_send_byte(int data);
char i2c_read_byte();
//#define SCK_dir TRISBbits.TRISB8
/*******************************************************************************************************************/
//Main function
/*******************************************************************************************************************/
void main(void)
{
// AD1PCFGbits.PCFG0=1;
// AD1PCFGbits.PCFG1=1;
AD1PCFG =0XFF;
//SCK_dir=0;
i2c_init();
i2c_start();
delay_us(2000);
status = i2c_send_byte(0x03);
delay_us(10000);
msb= i2c_read_byte();
lsb= i2c_read_byte();
reset_i2c_bus();
}
void i2c_init()
{
int temp;
I2C1BRG = 157;
I2C1CONbits.I2CEN = 0;
I2C1CONbits.DISSLW = 1;
I2C1CONbits.I2CEN= 1;
temp = I2C1RCV;
reset_i2c_bus();
}
void reset_i2c_bus() // reset is used before and after a packet i sent through the bus (release both sda and scl)
{
int x=0;
I2C1CONbits.PEN= 1;
while(I2C1CONbits.PEN)
{
delay_us(1);
x++;
if(x>20) break;
}
I2C1CONbits.RCEN=0;
IFS1bits.MI2C1IF=0;
I2C1STATbits.IWCOL=0;
I2C1STATbits.BCL=0;
delay_us(10);
}
void i2c_start(void)
{
int x = 0;
I2C1CONbits.ACKDT = 0; //Reset any previous Ack
delay_us(10);
I2C1CONbits.SEN = 1; //Initiate Start condition
Nop();
//the hardware will automatically clear Start Bit
//wait for automatic clear before proceding
while (I2C1CONbits.SEN)
{
delay_us(1);
x++;
if (x > 20)
break;
}
delay_us(2);
}
void i2c_restart(void)
{
int x = 0;
I2C1CONbits.RSEN = 1; //Initiate restart condition
Nop();
//the hardware will automatically clear restart bit
//wait for automatic clear before proceding
while (I2C1CONbits.RSEN)
{
delay_us(1);
x++;
if (x > 20) break;
}
delay_us(2);
}
char i2c_send_byte(int data)
{
int i;
while (I2C1STATbits.TBF) { }
IFS1bits.MI2C1IF = 0; // Clear Interrupt
I2C1TRN = data; // load the outgoing data byte
// wait for transmission
for (i=0; i<500; i++)
{
if (!I2C1STATbits.TRSTAT) break;
delay_us(1);
}
if (i == 500) {
return(1);
}
// Check for NO_ACK from slave, abort if not found
if (I2C1STATbits.ACKSTAT == 1)
{
reset_i2c_bus(); //error
return(1);
}
delay_us(2);
return(0);
}
char i2c_read_byte(void) //does not reset bus!!!
{
int i = 0;
char data = 0;
//set I2C module to receive
I2C1CONbits.RCEN = 1;
//if no response, break
while (!I2C1STATbits.RBF)
{
i++;
if (i > 2000) break;
}
//get data from I2CRCV register
data = I2C1RCV;
//set ACK to high
I2C1CONbits.ACKEN = 1;
//wait before exiting
delay_us(10);
//return data
return data;
}
void delay_us(unsigned short us)
{
unsigned short i;
// TIMER1 Period = PR1 x 2 x Tosc x Prescale second
// TIMER1 Period = 145 x 2 x 1/32000000 x 1 = 9 us // practically coming 12us
PR1=145; // Maximum Counter
T1CON=0x0000; // TIMER1 Off, Prescale 1:1 using the internal clock
for (i=0; i < us;i++) {
TMR1=0; // Reset TIMER1 Counter
IFS0bits.T1IF=0; // Clear TIMER1 Interrupt Flag
T1CONbits.TON=1; // Turn On TIMER1
while(IFS0bits.T1IF != 1); // Wait until TMR1 > PR1 (Overflow)
T1CONbits.TON=0; // Turn Off TIMER1
}
}