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

DS1307 interface
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

DS1307 interface
PostPosted: Sat Apr 04, 2015 3:13 pm     Reply with quote

Dear all,

I am trying to work with my RTC DS1307 module and it does not work. The main program is this:

Code:
#include <program.h>

#define LCD_RS_PIN      PIN_A3
#define LCD_RW_PIN      PIN_A2
#define LCD_ENABLE_PIN  PIN_A1
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7   

#include <lcd.c>
#include <ds1307.C>


int count1 = 0;

//timeclock variables

BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;







#INT_EXT
void  EXT_isr(void)
{
if (PIN_A4)
{
   output_toggle(PIN_E2);
   
}


}



void main()
{
   
   lcd_init();
 
   lcd_putc("\fReady...\n");
   enable_interrupts(INT_EXT);
   ds1307_init();
   delay_ms(1000);
   ds1307_set_date_time(15,6,5,2,15,20,55);
   enable_interrupts(GLOBAL);

  printf("done");

  while(TRUE)
   {
   delay_ms(1000);
   
       
    ds1307_get_date(day,month,yr,dow);
    ds1307_get_time(hrs,min,sec);
     
    printf( "\f\%02d/\%02d/\%02d\r\n",day,month,yr);
    printf( "\%02d:\%02d:\%02d", hrs,min,sec);

   }

}


and the driver is:

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_D7
#define RTC_SCL  PIN_D6

#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));
}


now since I already have the MAX517 on pins C4 and C3 (hardware I2C) I used a software I2C for the RTC as can be seen on the RTC driver. But the LCD remains "Ready..." and on the hyperterminal nothing is being displayed. The module I am using is shown here:

http://www.instructables.com/id/Arduino-Shower-Monitor-2/

the module has built in 3k3 on I2C bus that's why I used a seperate i2c ports.
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Sat Apr 04, 2015 9:06 pm     Reply with quote

You should use direct code to display lcd & read RTC no using interrupt & do it step by step, display any your info on lcd ok, then read RTC to display LCD, don't forgot enable internal oscillate of RTC, can you check it

Regards,
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Apr 04, 2015 10:17 pm     Reply with quote

Quote:
#define LCD_RS_PIN PIN_A3
#define LCD_RW_PIN PIN_A2
#define LCD_ENABLE_PIN PIN_A1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7


#define RTC_SDA PIN_D7
#define RTC_SCL PIN_D6

You are using the same pins for the LCD and the ds1307.
Don't do that.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun Apr 05, 2015 2:19 am     Reply with quote

Dear all, thanks for your replies. Actually i removed all the enable_interrupts including the global one and it worked perfectly even on the same max517 i2c bus line C3 and C4 pins. What could be the problem?
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Sun Apr 05, 2015 11:58 am     Reply with quote

Maybe, your code at the programs interrupt no ok, therefore programs can not return to main programs ==> can not read RTC to display LCD
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Sun Apr 05, 2015 12:06 pm     Reply with quote

Is there any pattern or sequence where i should list the enable interrupts e.g. at the beginning of the main routine or after the initialization of the drivers? Or it does not make any difference?
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Sun Apr 05, 2015 1:17 pm     Reply with quote

try to put this code look like below
Code:

#include <program.h>
#include <lcd.c>
#include <ds1307.C>

#INT_EXT
void  EXT_isr(void)
{
if (PIN_A4)
  {
   output_toggle(PIN_E2);
   
  }


}

you put interrupt code wrong position maybe interrupt no active, check it again
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 05, 2015 1:29 pm     Reply with quote

This won't work:
Quote:
if (PIN_A4)


To read a pin, you must use the input() function. Example:
Code:

if(input(PIN_A4))
  {
   output_toggle(PIN_E2);
  }
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Mon Apr 06, 2015 12:50 am     Reply with quote

Ooops...yes you are right! I will update the code and try again.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Mon Apr 06, 2015 3:16 am     Reply with quote

Dear All,

continue to working on the "strange" situation that I have on my code regaring the #INT statements! This is the code.

Code:
#include <program.h>
#include <MAX517.C>
#include <ds1307.C>



#define LCD_RS_PIN      PIN_A3
#define LCD_RW_PIN      PIN_A2
#define LCD_ENABLE_PIN  PIN_A1
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7   

#include <lcd.c>

//timeclock variables

BYTE sec;
BYTE min;
BYTE hrs;
BYTE day;
BYTE month;
BYTE yr;
BYTE dow;



void main()
{
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);      //104 ms overflow
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_TBE);
   enable_interrupts(GLOBAL);
   ds1307_init();
   delay_ms(400);
   lcd_init();
   delay_ms(400);
   
   while(true)
   {
   
   
    ds1307_get_date(day,month,yr,dow);
    ds1307_get_time(hrs,min,sec);
    lcd_gotoxy(0,0); 
    printf(lcd_putc, "Date: \%02d/\%02d/\%02d\r\n",day,month,yr);
    lcd_gotoxy(0,1);
    printf(lcd_putc, "Time: \%02d:\%02d:\%02d", hrs,min,sec);
   
   
   }

}


This code is working 100% but when I insert the following code just after the timeclock variables the program hangs:

Code:
#INT_TIMER1
void  TIMER1_isr(void)
{



}

#INT_EXT
void  EXT_isr(void)
{
 


}

#INT_RDA
void  RDA_isr(void)
{

}

#INT_TBE
void  TBE_isr(void)
{



}


I tried to put one statement at a time, and also change the place where i put this code, but it was in vain. Sorry but I need to use all the interrupts that's why I put them all.
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Mon Apr 06, 2015 3:18 am     Reply with quote

sorry forgot to mention, I am using PIC18F4520 with crystal 20MHz
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

PostPosted: Mon Apr 06, 2015 3:44 am     Reply with quote

Maybe there is a char in the RX reg and it keeps on firing the INT_RDA, try reading the RX reg and try.

When you tried adding them one at a time you did disable the interrupts that
didn't had any handler.

Just suggestions.

Regards
Ttelmah



Joined: 11 Mar 2010
Posts: 19551

View user's profile Send private message

PostPosted: Mon Apr 06, 2015 4:21 am     Reply with quote

Of course it would.....

Alan has given the first potential part. An INT_RDA handler _must_ always read a character, or the code will hang forever if this triggers. However even if this doesn't trigger there is a second problem.

The second part is INT_TBE. This _must_ only be enabled, when you have characters to send. Look at how ex_stisr works. The interrupt is disabled in the handler, once the last character is sent. INT_TBE says 'I want a character to transmit'. Unless you transmit one, the interrupt _will_ trigger again instantly.

You can never enable INT_TBE, until you have data waiting to send. The handler needs to either load a character, or disable the interrupt, or it can never exit.
huynhhai



Joined: 04 Apr 2015
Posts: 39

View user's profile Send private message

PostPosted: Tue Apr 07, 2015 12:54 am     Reply with quote

Are you forgot setup for priority interrupt? test one interrupt actived
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

PostPosted: Tue Apr 07, 2015 1:08 am     Reply with quote

thanks for everyone. Now everything is sorted regarding this issue.
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  Next
Page 1 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