Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] PIC18F4550 2IC can not send ack to slave

Status
Not open for further replies.

embedded_galaxy

Newbie level 4
Joined
Sep 12, 2015
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
79
hi,


working with TMP275 temperature sensor interfacing with pic18f4550.

my code is as follows :

Code:
// I2C Bus Control Definition
#define I2C_DATA_ACK 0
#define I2C_DATA_NOACK 1
#define I2C_WRITE_CMD 0
#define I2C_READ_CMD 1

#define I2C_START_CMD 0
#define I2C_REP_START_CMD 1
#define I2C_REQ_ACK 0
#define I2C_REQ_NOACK 0

unsigned char config;
unsigned char temp_low;
signed char temp_high;
unsigned int fraction;
int device_found = 0;


int init_temperature_sensor(void)
{
    TRISBbits.TRISB0 = 1; //SET OIN AS A INPUT
    TRISBbits.TRISB1 = 1; //SET OIN AS A INPUT


       // the configuration of the functions of port pins
      ADCON1=0b00001111;      // digital port configured


    SSPSTAT=0x80;   // SLEW RATE CONTROL DISABLED FOR std mode (100khz)
    SSPCON1=0x28;   // i2c master mode, serial synch enable
    SSPCON2=0x00;
    SSPADD = 19;    // 8MHZ for 100Khz

}



void i2c_idle(void)
{
  // Wait I2C Bus and Status Idle (i.e. ACKEN, RCEN, PEN, RSEN, SEN)
  while (( SSPCON2 & 0x1F ) || ( SSPSTATbits.R_W));
}

void i2c_start(unsigned char stype)
{
  i2c_idle();                     // Ensure the I2C module is idle
  if (stype == I2C_START_CMD) {
    SSPCON2bits.SEN = 1;          // Start I2C Transmission
    while(SSPCON2bits.SEN);
  } else {
    SSPCON2bits.RSEN = 1;         // ReStart I2C Transmission
    while(SSPCON2bits.RSEN);
  }
}

void i2c_stop(void)
{
  // Stop I2C Transmission
  SSPCON2bits.PEN = 1;
  while(SSPCON2bits.PEN);
}

unsigned char i2c_slave_ack(void)
{
  // Return: 1 = Acknowledge was not received from slave
  //         0 = Acknowledge was received from slave
  return(SSPCON2bits.ACKSTAT);
}

void i2c_write(unsigned char data)
{
  // Send the Data to I2C Bus
  SSPBUF = data;
  if (SSPCON1bits.WCOL)         // Check for write collision
    return;  

  while(SSPSTATbits.BF);        // Wait until write cycle is complete
  i2c_idle();                   // Ensure the I2C module is idle
}

void i2c_master_ack(unsigned char ack_type)
{
  SSPCON2bits.ACKDT = ack_type;   // 1 = Not Acknowledge, 0 = Acknowledge
  SSPCON2bits.ACKEN = 1;          // Enable Acknowledge                  
  while (SSPCON2bits.ACKEN == 1);
}

unsigned char i2c_read(void)
{
  // Ensure the I2C module is idle
  i2c_idle();                         

  // Enable Receive Mode
  SSPCON2bits.RCEN = 1;           // Enable master for 1 byte reception
  while(SSPSTATbits.BF);         // Wait until buffer is full
  return(SSPBUF);
}

void Write_TMP275(unsigned char reg_addr,unsigned char data) {
  // Start the I2C Write Transmission
  i2c_start(I2C_START_CMD);   

  // Write TMP275 I2C OP Code
  i2c_write(TMP275_ADDRESS|I2C_WRITE_CMD);    

  // Sending the Register Address
  i2c_write(reg_addr);

  // Write data to TMP275 Register
  i2c_write(data);        

  // Stop I2C Transmission
  i2c_stop();
} 

unsigned char Read_TMP275(unsigned char reg_addr,unsigned char *dval) {
  unsigned char hidata,lodata;
  char decval[]={0,25,50,75};     

    /*SEND REG_ADDR*/
  // Start the I2C Write Transmission
  i2c_start(I2C_START_CMD);   
  // Write TMP275 I2C ddress
  i2c_write(TMP275_ADDRESS|I2C_WRITE_CMD);    
  // Sending the Register Address
  i2c_write(reg_addr);
  // Stop I2C Transmission
  i2c_stop();
 // i2c_idle();
  delay(55);  //10bits resolution 55ms


/*READ*/

  // Start the I2C Write Transmission
  i2c_start(I2C_START_CMD);        

  // Read tmp275 I2C Temp Sensor Control Byte - Read
  i2c_write(TMP275_ADDRESS|I2C_READ_CMD);        
   // Sending the Register Address
   i2c_write(reg_addr);

  // Get the High Byte of TMP275 I2C Temp Sensor
  hidata=i2c_read();   

  // Send Acknowledge to the Slave
     [HTML] [B]i2c_master_ack(I2C_DATA_ACK);[/B] [/HTML]    

  // Get the Low Byte of TMP275 I2C Temp Sensor
  lodata=i2c_read();      

  // Send No Acknowledge to the Slave
  i2c_master_ack(I2C_DATA_NOACK);     

  // Stop I2C Transmission
  i2c_stop();     

  // Return 10-bit Temp Sensor Data
  *dval=decval[lodata >> 6];           // Convert lower data to decimal.

  return(hidata);
}


void set_conversion_bit(unsigned char conversion)
{
    Write_TMP275(CONFIGURATION_REGISTER,conversion);
}

void Read_TEMERATURE(void)
{
    unsigned char recievebytes[2];    
    //write pointer register 00000000 to select temp register to read temperature
    /*Read high byte of temperature and  Read low byte of temperature*/
    Read_TMP275(TEMPERATURE_REGISTER,recievebytes);
        
    temp_high =recievebytes[0];     // high byte
    temp_low = recievebytes[1];         //low byte
        
    fraction=(temp_low>>4)*625/1000;//calculate fraction part of temperature from LSB
}

      
    Write_TMP275(CONFIGURATION_REGISTER,POWER_UP); // read device
    if(I2CRead_Buffer[0] == 0)
    {
            //device found
            device_found = 1;
    }
    set_conversion_bit(12);        
}
pull up resistors are on slave device , this slave device is perfectly working with some CM4 device.

issue :
my data is send ok to slave but while reading data master can not send ACK BIT to slave
it will stuck in i2c_master_ack(I2C_DATA_ACK);


thanks,

Embedded_galaxy
 
Last edited by a moderator:

Hi,

my data is send ok to slave but while reading data master can not send ACK BIT to slave
What does that mean? Why it can not send ACK?

The only valid case can be that the slave is busy and thus keeps the SCL at GND level ... until it is ready.
The master software should take care of this case.

Klaus
 

Show the full code. What Compiler are you using ? What is your Crystal frequency ? What is the I2C Clock frequency ? If 100 kHz, do you have 4.7k pullup resistors on I2C lines ?

If you are using the Hi-Tech PICC18 Compiler then show the CONFIG bits settings. If you are using Hi-Tech PICC18 Compiler then why don't you use i2c.h library ?

What is the distance between Sensor and PIC ?
 

here is my config. settings and main function :


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#pragma config PLLDIV   = 2         // (8 MHz crystal on PICDEM FS USB board)
#pragma config CPUDIV   = OSC1_PLL2
#pragma config USBDIV   = 2         // Clock source from 96MHz PLL/2
#pragma config FOSC     = HSPLL_HS
#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config PWRT     = ON
#pragma config BOR      = ON
#pragma config BORV     = 3
#pragma config VREGEN   = ON      //USB Voltage Regulator
#pragma config WDT      = OFF
#pragma config WDTPS    = 32768
#pragma config MCLRE    = ON
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
#pragma config CCP2MX   = ON
#pragma config STVREN   = ON
#pragma config LVP      = OFF
#pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
#pragma config XINST    = OFF       // Extended Instruction Set
#pragma config CP0      = OFF
#pragma config CP1      = OFF
#pragma config CP2      = OFF
#pragma config CP3      = OFF
#pragma config CPB      = OFF
#pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
#pragma config WRT2     = OFF
#pragma config WRT3     = OFF
#pragma config WRTB     = OFF       // Boot Block Write Protection
#pragma config WRTC     = OFF
#pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
#pragma config EBTR2    = OFF
#pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF
 
#define SYSTEM_TIMER_RESOLUTION 10 // ms
//----------------------------------------------------------------------------
 
//----------------------------------------------------------------------------
// Main routine
 
char hellostr[] = "Health_Monitor  ";
 
void
main ()
{
    OSCCON = 0b01110010; 
    init_timer0();  
 
    /*buzzer init*/
    BUZZER_DIR
    BUZZER_OFF
    delay(1);
 
    /*lcd init*/
    LCD_Init();
    delay(1);
 
    /*init temperature sensor*/
//  init_temperature_sensor();
 
    /*init gsm Module*/
    GSM_init();
 
  while (1)
    {
    //  LCD_WriteString(hellostr);
        delay(100);
    //  LCD_ClearScreen();
        delay(200);
    //  Read_TEMERATURE();
        delay(500);
    //  LCD_ClearScreen();



using c-18 compiler.
the distance between sensor and pic is nearly 80mm
i2c clock is set to 100khz : SSPADD = 19; // 8MHZ for 100Khz
u mean to say 4.7k on pic sda and scl lines?
but i have pull up resistors on my slave device.

thanks
 
Last edited by a moderator:

please consider init_temperature_sensor(); and Read_TEMERATURE();
functions are uncomment
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top