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

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jinggy



Joined: 20 May 2008
Posts: 9
Location: malaysia

View user's profile Send private message MSN Messenger

DS1307
PostPosted: Sun Jun 29, 2008 5:15 am     Reply with quote

hello all.

I tried the DS1307 driver from this link:
http://www.ccsinfo.com/forum/viewtopic.php?t=23255&highlight=ds1307

The only changes I made are as below:
Code:

#define RTC_SDA PIN_B0
#define RTC_SCL PIN_B1


And this is my code.
Code:

#include <18F4550.h>
#fuses HSPLL,USBDIV,PLL5,CPUDIV1,VREGEN,NOWDT,NOPROTECT,NOLVP
#use delay(clock=48000000) //,RESTART_WDT

#include <ds1307.c>

#include <lcd.c>

#define LCD_RS PIN_D0
#define LCD_RW PIN_D1
#define LCD_E PIN_D2
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7

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

lcd_init();
ds1307_init();


// Set date for -> 29 June 2008 Sunday
// Set time for -> 17:36:09
ds1307_set_date_time(29,6,8,7,17,36,9);

while(1)
{
delay_ms(1000);

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

lcd_putc(sec);

}
}

I want to display sec on LCD, but I couldnt get number. Instead I have a black block blinking on my LCD screen. I saw the original codes. It uses #device adc=8 but I didn't use it because when I compile the code, that line caused error.

Anybody has any idea why it's not working?

thanks in advance!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Jun 29, 2008 6:32 am     Reply with quote

The returned seconds are ranging from 0 to 59. Writing these to the LCD with a PUTC command means you are writing raw ASCII codes to the lcd, not readable text.

Try something like:
Code:
printf(lcd_putc, "\f%d", sec);
the '\f' will clear the screen and the %d converts the seconds to a readable text string.

Quote:
i saw the original codes. it uses #device adc=8 but i didnt use it because when i compile the code, that line caused error.
As long as you don't use the A/D ports you can leave out the above mentioned line.
jinggy



Joined: 20 May 2008
Posts: 9
Location: malaysia

View user's profile Send private message MSN Messenger

PostPosted: Sun Jun 29, 2008 9:37 am     Reply with quote

thanks ckielstra. it works perfectly now Smile
MegatroniC



Joined: 08 Dec 2009
Posts: 35

View user's profile Send private message ICQ Number

PostPosted: Wed Mar 31, 2010 2:53 am     Reply with quote

Hello,
I'm sorry I raised old theme.
I also use this driver.
My problem is: call function time_data() from main but I can not go back to main
or at least a few clicks of the button is obtained once.

Is it possible is the time delay?

Code:
void time_data(void)                                               
{
  // Set date for -> 15 June 2005 Tuesday
  // Set time for -> 15:20:55
  //ds1307_set_date_time(15,6,5,2,15,20,55);
 
 do 
   {
   
    delay_ms(200);
   
    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);

    //lcd_gotoxy(10,2);
    //lcd_putc("summer");
   
   }While(!select_click);
}


thanks Smile
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Mar 31, 2010 3:32 am     Reply with quote

Have you got the pull up resistors on the two I2C lines?.
Without these, the I2C commands will hang, and never return...

Best Wishes
MegatroniC



Joined: 08 Dec 2009
Posts: 35

View user's profile Send private message ICQ Number

PostPosted: Wed Mar 31, 2010 4:01 am     Reply with quote

ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 31, 2010 5:23 am     Reply with quote

Don't connect SQW/OUT (pin 7) of the DS1307 directly to ground. This is an open collector output so probably nothing will be destroyed, but it makes no sense and you are wasting power. Remove the connection to ground and optionally you can get rid of R13 to save a component and a little bit power.

The problem of detecting multiple keys can not be caused by the 200ms delay, this is too short to press multiple keys.

How do you detect the keys? Is it interrupt based?
If possible post the routine for detecting the keys.
MegatroniC



Joined: 08 Dec 2009
Posts: 35

View user's profile Send private message ICQ Number

PostPosted: Wed Mar 31, 2010 6:00 am     Reply with quote

Thanks for the tips.

I think the problem comes from the delay and the method of detection of buttons.
But this delay is necessary for ds1307?
I try this:
if(counter>=xxx)
{
...
ds1307_get_time();
...
counter=0;
}
else counter++;


to avoid delay, but did not get.

I use this code for the buttons.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 31, 2010 11:08 am     Reply with quote

The delay is not required for the DS1307. You can leave it out if you want and should make no difference. I think the original author put it in to remove stress from the LCD; looping at maximum speed you could be doing thousands of display updates per second and the user most likely sees this as a flickering or dimmed display.
Why update at full speed if the clock only changes state every second?

The routine for scanning the keys works in the background based on a timer interrupt. This should be fine.

Quote:
... but I can not go back to main or at least a few clicks of the button is obtained once.
This sounds suspicious to me. The switch routine does not support multiple clicks, so what are you doing in your program?

You've made a small error somewhere, and without a complete program it is impossible to tell where.

Post a complete program demonstrating your problem by stripping down your program to a maximum of about 50 lines. If you have not modified the switch.c file you can just include this in your demo program and I'll copy it from the other thread.
MegatroniC



Joined: 08 Dec 2009
Posts: 35

View user's profile Send private message ICQ Number

PostPosted: Wed Mar 31, 2010 12:10 pm     Reply with quote

Here's part of it:

Code:
#include <16F917.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES PUT                      //Power Up Timer
#FUSES PROTECT                  //Code protected from reads
#FUSES CPD                      //Data EEPROM Code Protected
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES NODEBUG                  //No Debug mode for ICD

#use delay(clock=4MHz)

#define SET_SWITCH_PIN        PIN_B7               
#define SELECT_SWITCH_PIN     PIN_B6               
#define SCROLL_SWITCH_PIN     PIN_B5               

  #include <switch.h>
  #include <switch.c>
  #include <lcd_drv16x2.c>
  #include <ds1307Driver.c>
  #include <DEF_bits16F914.h>

#define RTCC_PRESET  (140)

signed int32 temp;
int1 wink=0;
int1 set_click, select_click, scroll_click;                           
int1 set_hold;
int8 adc_channel;                                         

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

=============================================
#int_rtcc                                                         
void rtcc_isr(void)
{
set_rtcc(RTCC_PRESET);
update_switch_status();                                       

set_hold=0; set_click=0; select_click=0; scroll_click=0;
   if((set_button == SW_HELD)) set_hold=1;
   else if(set_button == SW_PRESSED) set_click=1;
   else if(select_button == SW_PRESSED) select_click=1;
   else if(scroll_button == SW_PRESSED) scroll_click=1;



===============================================

void time_data(void)                                               
{
  // Set date for -> 15 June 2005 Tuesday
  // Set time for -> 15:20:55
  //ds1307_set_date_time(15,6,5,2,15,20,55);
 
 do 
   {
    delay_ms(200);
 
    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);
   
    //lcd_gotoxy(10,2);
    //lcd_putc("summer");
  }While(!select_click);
}

==============================================
void detect_buttons1(void)                                               
{
 if(scroll_click)
  {
   switch(adc_channel)
    {
     case 0: adc_channel=1;       
       break;
     case 1: adc_channel=2;                         
       break;
     case 2: adc_channel=3;                 
       break;     
     case 3: adc_channel=0;                   
    }
  }
  if(select_click) time_data();
  if(set_hold) main_menu();
}

=============================================
void main()
{
   
   gc_old_switch_status = read_switches();         // Read and save the initial state of the switches
   
   setup_adc_ports(sAN0|sAN1|sAN2|sAN3|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(SPI_SS_DISABLED);
   setup_lcd(LCD_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);      //Setup the RTCC for the 30ms timer tick that runs the multi-tasking.
   set_rtcc(RTCC_PRESET);                         
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);


   portb=0;                                       
   porta=0;                                       
   portc=0;
   trisa=0x0F;                                   
   trisb=0xF0;                                   
   trisc=0x00;

   lcd_init();                                 
   ds1307_init();
   rb0=1;                                         //BackLight on 
   
   lcd_putc(" blablabla  "); 
   delay_ms(1000);
   lcd_clear();
   
   clear_interrupt(INT_RTCC);
   enable_interrupts(INT_RTCC);

   enable_interrupts(GLOBAL);
 
While(True)
 {
  detect_buttons1();
  switch(adc_channel)
    {
     case 0: lcd_gotoxy(1,1);
             lcd_putc("temp 1 is: \n");
             adc_convert(0,8,'k'); 
       break;
     case 1: lcd_gotoxy(1,1);
             lcd_putc(" temp 2 is: \n");
             adc_convert(1,8,'v');               
       break;
     case 2: lcd_gotoxy(1,1);
             lcd_putc(" temp 3 is:  \n");
             adc_convert(2,8,'t');             
       break;
     case 3: lcd_gotoxy(1,1);
             lcd_putc(" temp 4 is:\n");
             adc_convert(3,8,'a');                   
    }
 }
}   



Push button scroll - shows the temperature for each channel of the ADC.
Hold button set - enter the main menu. In the main menu, push button set - exit from the main menu.

Here to work without problems.

Push button select - shows date and time.
Push button select again - back to displaying the temperature.
But I press once and not returned, press a second time - again not be returned.
Sometimes returned Smile

Sorry for my bad English Embarassed
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Mar 31, 2010 4:19 pm     Reply with quote

I'm not sure but it might have to do with the frequency you are scanning the switches. You reduced the scan period from 10ms to 30ms. A button is detected as being pressed when at least scanned 2 times. Worst case timing you press the switch just after a scan, resulting in a worst case of almost 90ms. This is slow, a quick button press can be gone by this time.

Then there is the effect of the mechanical switch contacts bouncing. When you press the switch it will not make a perfect contact at once, but vibrate a bit and make several contacts/breaks before settling. This process can take anytime from 1ms up to 50ms, depending on the switch.

For the above reasons I suggest you reduce the scan time from 30ms down again to 10ms as in the original switch.c version.

A second improvement is to reduce the 200ms delay in the display loop. As I said, you can remove the delay at all, but to prevent possible side effects on the display you could do something like this:

Code:
void time_data(void)                                               
{
  BYTE sec;
  BYTE min;
  BYTE hrs;
  BYTE day;
  BYTE month;
  BYTE yr;
  BYTE dow;
  int8 count;
 
  // Set date for -> 15 June 2005 Tuesday
  // Set time for -> 15:20:55
  //ds1307_set_date_time(15,6,5,2,15,20,55);
 
  count = 0;
  do
  {
    // Update the display only every 200ms.
    if (count%20 == 0)
    {
      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);
   
      //lcd_gotoxy(10,2);
      //lcd_putc("summer");
    }
    count++;
    delay_ms(10);
  } while(!select_click);
}
Note how I moved the date and time variables into the function. By making these variables local to the function you make it more clear to future programmers looking at your code that these variables are only used here. This will help to prevent bugs and the compiler can do better memory optimization.
MegatroniC



Joined: 08 Dec 2009
Posts: 35

View user's profile Send private message ICQ Number

PostPosted: Wed Mar 31, 2010 11:32 pm     Reply with quote

Š¢hanks for the advice ckielstra.

Will work on them.

Variables on the time and date I made them global, because I wanted to use them elsewhere. But if it's better to be local in this function will move there and will think of others in their place.

Again, many thanks.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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