CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

I2C + 18F4550 + 2 slave 16F877A + DS1307 changing date,time.
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
andretrilegal



Joined: 07 Jan 2012
Posts: 12

View user's profile Send private message

temtronic
PostPosted: Sun Jan 08, 2012 10:15 am     Reply with quote

Work with one or two analog values works fine.
Either if i set the analogs to 0 or ie i put the lm35dz temp sensor in all ports they works fine too! the problem shows up when there's no sensors in the portA, and the analog values get crazy, because they change on the fly!!!
andretrilegal



Joined: 07 Jan 2012
Posts: 12

View user's profile Send private message

Ttelmah
PostPosted: Sun Jan 08, 2012 10:16 am     Reply with quote

Work with one or two analog values works fine.
Either if i set the analogs to 0 or ie i put the lm35dz temp sensor in all ports they works fine too! the problem shows up when there's no sensors in the portA, and the analog values get crazy, because they change on the fly!!!
andretrilegal



Joined: 07 Jan 2012
Posts: 12

View user's profile Send private message

I'm using this driver
PostPosted: Sun Jan 08, 2012 10:19 am     Reply with quote

Code:

////////////////////////////////////////////////////////////////////////////////
///                               DS1307.C                                   ///
///                     Driver for Real Time Clock                           ///
///                                                                          ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
///                 used when PIC loses power and DS1307 run from 3V BAT     ///
///               - Disable squarewave output                                ///
///                                                                          ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   ///
///                                                                          ///
/// ds1307_get_date(day,mth,year,dow)               Get the date             ///
///                                                                          ///
/// ds1307_get_time(hr,min,sec)                     Get the time             ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////

#define RTC_SDA  PIN_C1
#define RTC_SCL  PIN_C0

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE seconds = 0;
   
 
   
   
   

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();
   i2c_write(0xD1);      // RD from RTC
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
   i2c_stop();
   seconds &= 0x7F;

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x07);      // Control Register
   i2c_write(0x80);     // Disable squarewave output pin
   i2c_stop();

}

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

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

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);            // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));            // REG 6
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE 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.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE 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));
}
andretrilegal



Joined: 07 Jan 2012
Posts: 12

View user's profile Send private message

PostPosted: Sun Jan 08, 2012 10:47 am     Reply with quote

Someone can tell me how to try:

a. Send from the slave two bytes together;
b. Send from the slave half_byte;

Let me explain:

If the analog values are:

// Each analog port
//AN0,AN1,AN2,AN3,AN4,AN5,AN6,AN7
280,216,100,78,129,56,100,75

Can you realise that the first byte is 280=0xD0 (ds1307 address).

How can I change 280 before send to master?
Like send one-by-on integer values
2,8,0,2,1,6,1,0,0,7,8,1,2,9,5,6,1,0,0,7,5

Like this there's no way to slave send a code similar to ds1307 address!
Ttelmah



Joined: 11 Mar 2010
Posts: 19543

View user's profile Send private message

PostPosted: Sun Jan 08, 2012 12:07 pm     Reply with quote

If you look at the top of the driver, _it_ defines the I2C port it uses.
Lines 17 to 20.
The same apples for the one for the eeprom.

You _must_ repeat _must_ define the I2C first, and remove the I2C setups from these driver files.

The data byte being an address doesn't matter at all. In I2C, you always send 'start', then the address of the device, and then the sequence of bytes. Only the first byte after the start is checked for being a device address. Once this is sent, the following bytes can be anything you want.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group