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 support@ccsinfo.com

I2C Help!!
Goto page 1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

I2C Help!!
PostPosted: Tue Jan 19, 2010 1:28 pm     Reply with quote

Hello!!
I'm new to programming in C, made a program to work with the DS1307 and DS1631 and PIC 16F877A on the same I2C bus,PIn C3 and C4 of the PIC 16F877A, but does not work!
I've been reading all the CCS forum and found nothing that helps me to
You can check, which has errors and correcting the program please!

The program source, and libraries is attached !!

Thank you very much .

Source program

Code:


#include <16f877A.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)
//#use i2c(master,sda=PIN_C4,scl=PIN_C3,FORCE_HW)// DS1307
#include <RTC_DS1307.c>// RTC DS1307
#include <flex_lcd.c>
#include <DS1631.c>

#use standard_io (b)
#use standard_io (a)
#use standard_io(c)
#use standard_io(D)

void main()
{
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;

float value;

lcd_init();
delay_ms(50);
init_temp();
delay_ms(50);

ds1307_init();
delay_ms(50);

lcd_putc("\f testing");
delay_ms(500);

ds1307_set_date_time(10,10,10,0,10,10,00);
while(1)
{

delay_ms(1000);

ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);

printf(lcd_Putc,"\f \%02d/\%02d/\%02d\r\n",day,month,yr);
printf(lcd_Putc," %02d:\%02d:\%02d", hrs,min,sec);
delay_ms(500);
value = (float)read_full_temp();
value /= 100.0;
value=(value-32)/1.8;
lcd_gotoxy(15,1);
printf(lcd_putc,"temp.%03.1f", value);


}
}




Library for a Dallas DS 1631 and DS1307
Code:

//// Library for a Dallas 1631 Temperature chip ////
//// ////




#define read_temp read_full_temp // for backwards compatability

#use i2c(master, sda=DAL_SDA, scl=DAL_SCL)


void temp_config(BYTE data) {

i2c_start();
i2c_write(0x92);
i2c_write(0xac);
i2c_write(data);
i2c_stop();
}


void init_temp() {
output_high(DAL_SDA);
output_high(DAL_SCL);
i2c_start();
i2c_write(0x92);
i2c_write(0x51);
i2c_stop();
temp_config(0xc);
}


signed long read_full_temp() { // Returns hundreths of degrees F (-67 to 257)
long datal; //long datal;
signed long datah, data;


i2c_start();
i2c_write(0x92);
i2c_write(0xaa);
i2c_start();
i2c_write(0x93);
datah=i2c_read();
datal=i2c_read(0);
i2c_stop();

data = datah * 100;
data += (datal << 8) / 655;
data=data*9;
data = (data / 5) + 3200;

return(data);
}

/// DS1307.C ///
/// Driver for Real Time Clock ///

#define DAL_SCL PIN_C3
#define DAL_SDA PIN_C4
#use i2c(master, sda=DAL_SDA, scl=DAL_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(0x01); // 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(0x01); // 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));
}

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 2:04 pm     Reply with quote

Tell us what you mean by "does not work". What output do you get ?

Do you have 4.7K pull-up resistors on the SDA and SCL lines ?

What is your compiler version ?
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 3:55 pm     Reply with quote

PCM programmer wrote:
Tell us what you mean by "does not work". What output do you get ?

Do you have 4.7K pull-up resistors on the SDA and SCL lines ?

What is your compiler version ?


"It does not work", that is to not show anything on the LCD, the temperature, clock and calendar! with the two chips (DS1631 + DS1307) connected on the same bus!
I have 47K pull-up resistors on the SDA and SCL lines because I changed the 10K but is the same!
My compiler version is 4.068

I thank you help
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 4:06 pm     Reply with quote

Quote:
lcd_putc("\f testing");

Here you have a line that should display "testing". Do you see that ?
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 4:38 pm     Reply with quote

PCM programmer wrote:
Quote:
lcd_putc("\f testing");

Here you have a line that should display "testing". Do you see that ?


yes, it shows in the LCD,yes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 5:12 pm     Reply with quote

Change your code and your hardware so it tests only the ds1307.
Get that working first. Disconnect the ds1631 chip from the i2c bus
completely.

Try to make your program as close as possible to the test program
shown in the ds1307 driver link:
http://www.ccsinfo.com/forum/viewtopic.php?t=23255
But don't use the "\r" in the printf statement. You'll note that I've edited
that out below. Also, your posted code had the #use i2c statement
commented out. I've put it back in. Also, I've removed the "FORCE_HW"
parameter. It's safer to start with a software i2c master. You have
NOBROWNOUT below. If you're using a "wall wart" transformer, it's
better to have BROWNOUT in there. You'll note that I removed your
settings for the date and time, and I put in the settings from the sample
code in the ds1307 link. Try to keep everything as close to his code
as possible, because it presumably works. Get it working that way first.

With respect to your hardware, make sure you have a 32.768 KHz
watch crystal connected to the ds1307's crystal pins. No capacitors
are used with this crystal. Also, make sure you have a 3 volt lithium
battery connected to the Vbat pin. Don't substitute some other voltage.
Code:

#include <16f877A.h>
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

#include <RTC_DS1307.c>
#include <flex_lcd.c>

void main()
{
BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;

lcd_init();
ds1307_init();

lcd_putc("\f testing");
delay_ms(500);

// Set date for -> 15 June 2005 Tuesday
// Set time for -> 15:20:55
  ds1307_set_date_time(15,6,5,2,15,20,55);

while(1)
 {
  delay_ms(1000);

  ds1307_get_date(day,month,yr,dow);
  ds1307_get_time(hrs,min,sec);

  printf(lcd_Putc,"\f \%02d/\%02d/\%02d\n",day,month,yr);
  printf(lcd_Putc," %02d:\%02d:\%02d", hrs,min,sec);
  }

}
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 5:42 pm     Reply with quote

PCM I made the changes and now the DS1307 works very, very good! But only with the DS1307!

Then I made only with the DS1631 and does not work, the problem is in the code of the DS1631, where is the error? can help me in this code?
Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 5:54 pm     Reply with quote

Quote:
#use i2c(master, sda=DAL_SDA, scl=DAL_SCL)

Post the lines that #define the i2c pins used for the ds1631.

Here are the lines from the CCS driver file, ds1631.c. It defaults to
using pins B0 and B1. Is it possible that you left this code in there,
you're accidently using pins B0 and B1 ?
Quote:
#ifndef DAL_SCL
#if defined(__PCD__)
#define DAL_SCL PIN_D0
#define DAL_SDA PIN_D1
#else
#define DAL_SCL PIN_B0
#define DAL_SDA PIN_B1
#endif
#endif



Quote:
void temp_config(BYTE data) {

i2c_start();
i2c_write(0x92);
i2c_write(0xac);
i2c_write(data);
i2c_stop();
}

In the code above you are using 0x92 as the base address for the
ds1631. But, the CCS ds1631.c driver uses 0x90, as shown below:
Code:

void temp_config(BYTE data

   i2c_start();
   i2c_write(0x90);
   i2c_write(0xac);
   i2c_write(data);
   i2c_stop();
}

What connections do you have to the A0, A1, and A2 pins of the ds1631
chip on your board ? These pins set the slave address.
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 6:16 pm     Reply with quote

I used the same lines of the DS1307, or # use i2c (master, sda = PIN_C4, scl = PIN_C3)

The address of the DS1631 use A2 = 0, A1 = 0, A0 = 1.
Also tested A2 = 0, A1 = 0, A0 = 0, and does not work
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 6:33 pm     Reply with quote

Quote:
The address of the DS1631 use A2 = 0, A1 = 0, A0 = 1.

That means you have pin A0 connected to +5v, and pins A1 and A2
connected to ground. Is that true ?


Post your current driver file and test program for the ds1631.
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 6:56 pm     Reply with quote

PCM programmer wrote:
Quote:
The address of the DS1631 use A2 = 0, A1 = 0, A0 = 1.

That means you have pin A0 connected to +5v, and pins A1 and A2
connected to ground. Is that true ?


Exactly!

The driver file and test program for the ds1631is.

Code:

#include <16f877A.h>                                   
 
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT 
#use delay(clock=4000000)                           
#use i2c(master,sda=PIN_C4,scl=PIN_C3)
#include <flex_lcd.c>
#include <DS1631.c>

                                       
#use standard_io (b)                                         
#use standard_io (a)
#use standard_io(c)                                                 
#use standard_io(D)     

void main()
{

   float value; 
 
 lcd_init();                                                                       
    delay_ms(100); 
             
                     init_temp();                                             
                        delay_ms(100);
                             
  while(1)
  {

     delay_ms(1000);                                                                                                                         
     value = read_full_temp();   
       value /= 100.0;                                                                     
       value=(value-32)/1.8;
       lcd_gotoxy(15,1);                   
        printf(lcd_putc,"\f temp.%04.1f", value);                           
         delay_ms(100);                                                                   
       }
  }


Code:

//// Library for a Dallas 1631 Temperature chip ////
//// ////


//#use i2c(master,sda=PIN_C4,scl=PIN_C3)

#define read_temp read_full_temp // for backwards compatability

void temp_config(BYTE data) {

i2c_start();
i2c_write(0x92);
i2c_write(0xac);
i2c_write(data);
i2c_stop();
}


void init_temp() {
output_high(DAL_SDA);
output_high(DAL_SCL);
i2c_start();
i2c_write(0x92);
i2c_write(0x51);
i2c_stop();
temp_config(0xc);
}


signed long read_full_temp() { // Returns hundreths of degrees F (-67 to 257)
long datal; //long datal;
signed long datah, data;


i2c_start();
i2c_write(0x92);
i2c_write(0xaa);
i2c_start();
i2c_write(0x93);
datah=i2c_read();
datal=i2c_read(0);
i2c_stop();

data = datah * 100;
data += (datal << 8) / 655;
data=data*9;
data = (data / 5) + 3200;

return(data);
}

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jan 19, 2010 7:24 pm     Reply with quote

What values are displayed on the LCD ?


Did you use the CCS driver to make your driver ? I was comparing your
routine for read_full_temp() to the CCS driver code, and your routine
looks like the CCS code, except it's been heavily edited. I would put
the ds1631.c driver back the way it was. Use it in the non-edited form.
See what you get.
Ttelmah
Guest







PostPosted: Wed Jan 20, 2010 3:18 am     Reply with quote

fiasgardone wrote:
PCM programmer wrote:
Tell us what you mean by "does not work". What output do you get ?

Do you have 4.7K pull-up resistors on the SDA and SCL lines ?

What is your compiler version ?


"It does not work", that is to not show anything on the LCD, the temperature, clock and calendar! with the two chips (DS1631 + DS1307) connected on the same bus!
I have 47K pull-up resistors on the SDA and SCL lines because I changed the 10K but is the same!
My compiler version is 4.068

I thank you help


Go lower.
Read the I2C specs. 10K, gives you a maximum allowed bus capacitance of 80pF, for 'standard' speed operation. Most of the diagrams don't even go as high as 10K. The minimum value allowed for 5v, is 1.75K, and typical 'likely to work' values will fall in the area between 2.2K, and 4.7K.
It is worth getting the resistor into the proper range, before looking for other causes to the problem.
With two devices on the bus, you _need_ to be able to cope with a reasonable amount of capacitance...
PCM programmer suggested 4.7K, and this is the sort of level you should be using.

Best Wishes
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Wed Jan 20, 2010 4:42 am     Reply with quote

Quote:
PCM programmer suggested 4.7K, and this is the sort of level you should be using.


Yes, I am using the 4.7K Pull-up resistors !!
Thanks!
fiasgardone



Joined: 19 Jan 2010
Posts: 71

View user's profile Send private message

PostPosted: Wed Jan 20, 2010 5:50 am     Reply with quote

I tested the code with the driver of the CCS,and also does not work!
I used the pins D0 and D1 of the PIN PIC, did not use pins B0 and B1 because the use for the LCD, but does not show the temperature on the LCD, where the errors are?

The address of the DS1631 is now A2 = 0, A1 = 0, A0 = 0 in hardware

See below;

Code:

#include <16f877A.h>

#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT
#use delay(clock=4000000)
#use i2c(master,sda=PIN_D1,scl=PIN_D0)
#include <flex_lcd.c>
#include <DS1631.c>


#use standard_io (b)
#use standard_io (a)
#use standard_io(c)
#use standard_io(D)

void main()
{

float value;

lcd_init();
delay_ms(100);

init_temp();
delay_ms(100);

while(1)
{

delay_ms(1000);
value = read_full_temp();
value /= 100.0;
value=(value-32)/1.8;
lcd_gotoxy(15,1);
printf(lcd_putc,"\f temp.%04.1f", value);
delay_ms(100);
}
}


Last edited by fiasgardone on Thu Jan 21, 2010 10:24 am; edited 1 time in total
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 1, 2, 3, 4, 5  Next
Page 1 of 5

 
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