I2C not working on 18F25K20

(instructions, reset, WDT, specifications...) PIC17Cxx, PIC18Fxxx

I2C not working on 18F25K20

Postby Ray » Wed Jul 23, 2014 2:05 pm

Hi,

I'm new to this forum, and any help would be appreciated.

I have I2C code for a DS3232 clock that was compiled with the XC8 compiler and runs fine on a 18F2520. However I can get it to work on a 18F25K20. I think I am missing something re the I/O setup. Is there anything special necessary to enable the C3 and C4 pins to use the MSSP in I2C mode?


ds3232.c
Code: Select all
////////////////////////////////////////////////////////////////////////////////
///                               DS3232.C                                   ///
///                     Driver for Real Time Clock                           ///
///                                                                          ///
/// ds3232_init() - Enable oscillator without clearing the seconds register -///
///                 used when PIC loses power and DS1307 run from 3V BAT     ///
///               - Disable squarewave output                                ///
///                                                                          ///
/// ds3232_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   ///
///                                                                          ///
/// ds3232_get_date(day,mth,year,dow)               Get the date             ///
///                                                                          ///
/// ds3232_get_time(hr,min,sec)                     Get the time             ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////

#include "device.h"
#include <plib\i2c.h>

#define RTC_SDA  PIN_C4
#define RTC_SCL  PIN_C3

int bin2bcd(int binary_value);
int bcd2bin(int bcd_value);

void ds3232_init(void)
{
   BYTE seconds = 0;

   OpenI2C(MASTER, SLEW_OFF);
 
   StartI2C();
   WriteI2C(0xD0);      // WR to RTC
   WriteI2C(0x00);      // REG 0
   RestartI2C();
   WriteI2C(0xD1);      // RD from RTC
   seconds = bcd2bin(ReadI2C()); // Read current "seconds" in DS1307
   // NotAckI2C();
    StopI2C();
   seconds &= 0x7F;

   delay_us(3);

   StartI2C();
   WriteI2C(0xD0);      // WR to RTC
   WriteI2C(0x00);      // REG 0
   WriteI2C(bin2bcd(seconds));     // Start oscillator with current "seconds value
   RestartI2C();
   WriteI2C(0xD0);      // WR to RTC
   WriteI2C(0x0E);      // Control Register
   WriteI2C(0x00);     // Set to 0x00
   NotAckI2C();
   StopI2C();

}

void ds3232_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  StartI2C();
  WriteI2C(0xD0);              // I2C write address
  WriteI2C(0x00);              // Start at REG 0 - Seconds
  WriteI2C(sec);               // REG 0 ** Modified
  WriteI2C(min);               // REG 1 ** Modified
  WriteI2C(hr);                // REG 2 ** Modified
  WriteI2C(bin2bcd(dow));      // REG 3
  WriteI2C(day);               // REG 4 ** Modified
  WriteI2C(mth);               // REG 5 ** Modified
  WriteI2C(year);              // REG 6 ** Modified
//  i2c_write(0x80);            // REG 7 - Disable squarewave output pin
  StopI2C();
}

void ds3232_get_date(int *day, int *mth, int *year, int *dow)
{
  StartI2C();
  WriteI2C(0xD0);
  WriteI2C(0x02);            // Start at REG  - Day of week
  RestartI2C();
  WriteI2C(0xD1);
  *dow  = bcd2bin(ReadI2C() & 0x7f);   // REG 3
  AckI2C();
  *day  = bcd2bin(ReadI2C() & 0x3f);   // REG 4
  AckI2C();
  *mth  = bcd2bin(ReadI2C() & 0x1f);   // REG 5
  AckI2C();
  *year = bcd2bin(ReadI2C());            // REG 6
  NotAckI2C();
  StopI2C();
}

void ds3232_get_time(int *hr, int *min, int *sec)
{
  StartI2C();
  WriteI2C(0xD0);
  WriteI2C(0x00);            // Start at REG 0 - Seconds
  RestartI2C();
  WriteI2C(0xD1);
  *sec = bcd2bin(ReadI2C() & 0x7f);
  AckI2C();
  *min = bcd2bin(ReadI2C() & 0x7f);
  AckI2C();
  *hr  = bcd2bin(ReadI2C() & 0x3f);
  NotAckI2C();
  StopI2C();

}

int bin2bcd(int binary_value)
{
  int temp;
  int retval;

  temp = binary_value;
  retval = 0;

  while(1)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
int bcd2bin(int bcd_value)
{
  int temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
Last edited by ric on Wed Jul 23, 2014 2:36 pm, edited 1 time in total.
Reason: Added "code" tags around the code.
Ray
 
Posts: 2
Joined: Wed Jul 23, 2014 1:51 pm
PIC experience: Professional 5+ years with MCHP products

Re: I2C not working on 18F25K20

Postby ric » Wed Jul 23, 2014 2:43 pm

How exactly is it failing?
Are the SCL/SDA pins toggling at all when you try to output a START?
The "K" version does have an extra register (SSPMSK), but the default value in there should work fine for you.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 398
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: I2C not working on 18F25K20

Postby Ray » Wed Jul 23, 2014 3:32 pm

ric,

I don't have a hardware monitor, however when I run the code on a 18F2520, I can see the correct values in the variables. When I run the code on a 18F25k20, the values are all 0 as if the ds3232 did not respond, or the pgm did not read the response from the ds3232.

Do you know of any other working I2C code for the 25K20 that I might have a look at? Do you know of anything special to enable the I2C pins? I had a look at the SSPMSK register, how ever I don't see any problems there.
Ray
 
Posts: 2
Joined: Wed Jul 23, 2014 1:51 pm
PIC experience: Professional 5+ years with MCHP products

Re: I2C not working on 18F25K20

Postby ric » Wed Jul 23, 2014 10:01 pm

Do you have a PICkit3 or ICD3?
Single step the code, and use a meter to check if the SDA and SCL pins are high before StartI2C();
and low after.
If they are low all the time, you may have forgotten the pullup resistors.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 398
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: I2C not working on 18F25K20

Postby DavidBLit » Thu Jul 24, 2014 2:12 am

Ray wrote:ric,

I don't have a hardware monitor, however when I run the code on a 18F2520, I can see the correct values in the variables. When I run the code on a 18F25k20, the values are all 0 as if the ds3232 did not respond, or the pgm did not read the response from the ds3232.

Do you know of any other working I2C code for the 25K20 that I might have a look at? Do you know of anything special to enable the I2C pins? I had a look at the SSPMSK register, how ever I don't see any problems there.


Are you sure the 'K device is even running correctly? There's more of a difference between the two devices than just the "K" wedged in there might suggest: http://ww1.microchip.com/downloads/en/DeviceDoc/41310A.pdf.

You just might want to back up, blink an LED, and make sure you understand the differences between the two devices... ;)

(FYI: the SSPMSK register has no effect on I2C Master operation.)
User avatar
DavidBLit
 
Posts: 12
Joined: Fri May 30, 2014 12:37 pm
Location: The Land of Confusion
PIC experience: Professional 2-5 years with MCHP products

Re: I2C not working on 18F25K20

Postby shaddai » Sun Dec 28, 2014 11:09 am

I know I'm way late to the party, but is SSPCON's SSPEN bit set?

todd
shaddai
 
Posts: 1
Joined: Sun Dec 28, 2014 10:57 am


Return to 16-Bit Core

Who is online

Users browsing this forum: No registered users and 1 guest

cron