user572575
user572575

Reputation: 1049

I can't show time from DS1307 with PIC16f88

I write program so long code for alarm clock. I use CCS compile which use ROM =80% RAM=8%-51% . I simulate my program in proteus it work. but when I use in real hardware it show time = 00:00:80 and not run second. My code read time from DS1307. I change battery 3V of DS1307 but it show same time. when I push button it not show anything too. I think if my code wrong it should can't run in proteus. How to fix it ? please help me.

This is my code.

#include <16F886.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)

#include "flex_LCD.c"
#use I2C(master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#define ADDR_DS1307  0xD0 //Address DS1307

int set_hr=24;
int set_min=60;
short int f_next = FALSE;
short int delay_chk=FALSE;
int cnt;

typedef struct{
   BYTE sec;     // seconds
   BYTE min;     // minute
   BYTE hr;      // hour
   BYTE day;
   BYTE date;
   BYTE month;
   BYTE year;
}DS1307_RTC;

DS1307_RTC RTC;

typedef struct{

   int min;     // minute
   int hr;      // hour
   int sec_delay;
}time_feed;

time_feed t_feed;


void DS1307_Write(unsigned char ctl, unsigned char dat);
BYTE DS1307_Read(unsigned char ctl);
void DS1307_WriteDate(void);
void DS1307_WriteTime(void);

void DS1307_ReadDate(void);
void DS1307_ReadTime(void);
void Set_Voice();


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

   /*******************************************************/
void DS1307_Write(unsigned char ctl, unsigned char dat){
   i2c_start();
   i2c_write(ADDR_DS1307);
   i2c_write(ctl);
   i2c_write(dat);
   i2c_stop();
}

/*******************************************************/
BYTE DS1307_Read(unsigned char ctl){

   BYTE dat;

   i2c_start();
   i2c_write(ADDR_DS1307);
   i2c_write(ctl);

   i2c_start();
   i2c_write(ADDR_DS1307+1);
   dat = i2c_read(0);
   i2c_stop();
   return(dat);
}

/*******************************************************/
void DS1307_WriteDate(void){
   DS1307_Write(0x04,RTC.date);
   DS1307_Write(0x05,RTC.month);
   DS1307_Write(0x06,RTC.year);
}

/*******************************************************/
void DS1307_WriteTime(void){
   DS1307_Write(0x00,RTC.sec);
   DS1307_Write(0x01,RTC.min);
   DS1307_Write(0x02,RTC.hr);
}

/*******************************************************/
void DS1307_ReadDate(void){
   RTC.date = DS1307_Read(0x04);
   RTC.month = DS1307_Read(0x05);
   RTC.year = DS1307_Read(0x06);
}

/*******************************************************/
void DS1307_ReadTime(void){
   RTC.sec = DS1307_Read(0x00);
   RTC.min = DS1307_Read(0x01);
   RTC.hr = DS1307_Read(0x02);
}

void DS1307_SetTime(int hr, int min){

   RTC.hr = bin2bcd(hr);
   RTC.min = bin2bcd(min);
   RTC.sec = 0x00;
}

/************* Delay *************/
void delay(){
int sec_delay;

  for(sec_delay=t_feed.sec_delay;sec_delay>0;sec_delay--){
     output_high(pin_C5);
     lcd_gotoxy(1,2);
     delay_ms(1000);
     printf(lcd_putc,"\r Food = %d sec " sec_delay);
  }
   output_low(pin_C5);
}

void clr_voice(){
   output_high(pin_C0);
   output_high(pin_C1);
   output_high(pin_C2);
   delay_ms(1000);
   output_float(pin_C0);
   output_float(pin_C1);
   output_float(pin_C2);
}

/************* time **************/
void time(){

   int hr=bcd2bin(RTC.hr);
   int min=bcd2bin(RTC.min);

    delay_ms(50);
    lcd_gotoxy(1,2);
    //printf(lcd_putc,"\r    -- : --    ");
    printf(lcd_putc,"\r    %02d : %02d    ", hr,min);
    delay_ms(50);

while(1){

if(input(PIN_B1)==0){

   delay_ms(100);
   hr++;

if(hr>=24){hr=0;}

    delay_ms(100);
    lcd_gotoxy(1,2);

    printf(lcd_putc,"\r    %02d : %02d   ", hr,min);
    delay_ms(50);


}else if(input(PIN_B2)==0){

   delay_ms(100);
   min++;

if(min>=60){min=0;}

    delay_ms(100);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r    %02d : %02d   ", hr,min);
    delay_ms(50);

}

if(input(PIN_B3)==0){

    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r Time : %02d:%02d ", hr,min);
    delay_ms(50);


   DS1307_SetTime(hr,min);
   DS1307_WriteTime();

   break;

}
}  // while hr

}

/************* check same time **************/
int check_time(int hr[], int hr_ck, int min[], int min_ck,int count){
  int x;
  for(x=0;x<count;x++){

  if((hr[x]== hr_ck) && (min[x]== min_ck)){

    if((hr_ck==24)&& (min_ck==60)){

      return 0;
      break;

   }else{
      return 1;
      break;
   } 
  }
  }
   return 0;

}

/************ get now time ***************/
int16 getNow(){

   int16 now_hr,now_min;
   int16 now_all;

   DS1307_ReadTime();

   now_hr = bcd2bin(RTC.hr);
   now_min = bcd2bin(RTC.min);
   now_all = (now_hr*60)+now_min;

   //printf("\r\n n=%ld",now_all);
   return now_all;
}

/**************************************/
int16 next_time(int16 hr, int16 min, int pos){

int32 minimVal;
int i=0;
int16 now_all;
int32 all[5],t;
int16 hrk[5],mnk[5];
int n,j; 

hrk[pos] = hr;
mnk[pos] = min;
all[pos] =(hrk[pos]*60 + mnk[pos]) ; 

//minimVal2 = (hrk[0]*60) + mnk[0]; 
now_all = getNow();
//printf("\r\n pos=%d, n=%ld, ",pos,all[pos]);

n = sizeof(all)/sizeof(all[0]);

   /* bubble sort */
   for (i = pos; i > 0; i--) {
       for (j = 0; j < i; j++) {   /* move max (in [0] to [i]) to last ([i]) */
           if (all[j] > all[j+1]) {   /* exchange if bigger than next */
               t = all[j];
               all[j] = all[j+1];
               all[j+1] = t; } } }

               minimVal= all[0];

   for (i = 0; i < pos+1; i++) {
   //printf("\r\n%ld ", all[i]);

  if(all[i]>now_all){
  if(all[i]!=1500){
      minimVal= all[i];
      break;
  }
 }
   }

//printf("\r\n min %ld ", minimVal);

return minimVal;

}

/************* Show Menu **************/
void show_menu(){
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"[Next]      [OK]");
    delay_ms(50);
}

/************* feed time **************/
void feed_time(int count){


int hr[5],min[5];
int16 next;

while(1){

if(input(PIN_B1)==0){

delay_ms(250);       // delay for add hr
set_hr++;

if(set_hr>24){
   set_hr=0;
   set_min= 0;
}

if(set_hr==24){
    set_min=60;
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  -- : -- ",count+1);
    delay_ms(50);
}else{
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  %02d : %02d ", count+1, set_hr,set_min);
    delay_ms(50);
}

}else if(input(PIN_B2)==0){

   delay_ms(250);        // delay for add min
   set_min++;

if(set_min>=60){
  if(set_hr==24){set_hr=0;}
    set_min=0;

}
    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r F%d :  %02d : %02d " count+1, set_hr,set_min);
    delay_ms(50);

}

if(input(PIN_B3)==0){
   hr[count] = set_hr;
   min[count] = set_min;

    if(check_time(hr,set_hr,min,set_min,count)){

       delay_ms(50);
       lcd_gotoxy(1,1);
       //printf(lcd_putc,"\rn=%d ar= %d,va= %d" ,count, set_hr,set_min);
       printf(lcd_putc,"\r This is same. ");
       delay_ms(50);

     }

    else{

          next= next_time(hr[count],min[count],count);
          t_feed.hr=next/60;
          t_feed.min=next%60;

if(set_hr==24){

    delay_ms(50);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r F%d :  -- : -- ",count+1);
    delay_ms(50);

    lcd_gotoxy(1,2);
    printf(lcd_putc,"\r                  ");
    delay_ms(50);

    if((count+2)!=6){

       lcd_gotoxy(1,2);
       printf(lcd_putc,"\r F%d :  -- : -- ",count+2);
       delay_ms(50);
    }

}else{

    delay_ms(50);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r F%d :  %02d : %02d " count+1, set_hr,set_min);
    delay_ms(50); 

    if((count+2)!=6){
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\r F%d :  %02d : %02d ",count+2,set_hr,set_min);
       delay_ms(50);
    }

}
     f_next=TRUE;  
     break;

    }
    }

}  // while hr

}

/************* Sec Period **************/
void sec_feed(){

//unsigned int sec=10;

while(input(PIN_B3)){

if(input(PIN_B1)==0){
   delay_ms(100);
   t_feed.sec_delay++;

   if(t_feed.sec_delay>=200){t_feed.sec_delay=200;}
       delay_ms(100);
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay);
       delay_ms(50);     
}

if(input(PIN_B2)==0){
   delay_ms(100);
   t_feed.sec_delay--;

   if(t_feed.sec_delay<=1){t_feed.sec_delay=1;}
       delay_ms(100);
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay);
       delay_ms(50);
}
}  // while sec
t_feed.sec_delay = t_feed.sec_delay;
//delay();

}

/************* Record **************/
void rec(){
int i;
//unsigned int sec=10;

while(input(PIN_B3)){

if(input(PIN_B0)==0){
    delay_ms(50);

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r Please Wait... ");
    delay_ms(50);


  for(i=0;i<10;i++){    //clear voice 10 Sec.
   output_low(pin_C0);
   output_high(pin_C1);
   output_high(pin_C2);
   lcd_gotoxy(1,2);
   delay_ms(1000);

  }

    for(i=10;i>0;i--){    //clear voice 10 Sec.
       output_high(pin_C0);
       output_low(pin_C1);        // record
       output_high(pin_C2);

       delay_ms(50);

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r   Say now  %d   ", i);
    delay_ms(50);
    delay_ms(850);
  }

   output_high(pin_C0);   // play
   output_high(pin_C1);
   output_low(pin_C2);
   delay_ms(500);

   clr_voice();

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r  Record Voice  ");
}

}  // while sec

}

/************* Set time **************/
void Set_Time(){

    delay_ms(50);
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r   Set Clock   ");

    show_menu();

while(1){

   if(input(PIN_B3)==0){

      delay_ms(250);
      time();
      break;
   }

   if(!input(PIN_B0)){

      break;
    }
}
}

/************* Set Feed Time **************/
void Set_Feed_Time(){
    int i;
    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r Set Feed Time ");

    show_menu();

while(1){

   if(input(PIN_B3)==0){

       delay_ms(50);
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\r F1 :  -- : -- ");


       delay_ms(250);


      for(i=0;i<5;i++){     // count feed time
         feed_time(i);
         delay_ms(250);
      }

      break;

}

   if(!input(PIN_B0)){

      break;
    }

}
}

/***************** Set Period Time *********************/

void Set_Period_Time(){

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\rSet Feed Period");

    show_menu();

while(1){

   if(input(PIN_B3)==0){

       delay_ms(50);
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\r Time : %d sec ",t_feed.sec_delay);

       delay_ms(250);
       sec_feed();

    break;
}

    if(!input(PIN_B0)){

      break;
    }
}
   }

/***************** Set Voice *********************/

void Play_Voice(){

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r  Play Voice  ");

    show_menu();

  while(1){

   if(input(PIN_B3)==0){
      delay_ms(250);



    output_high(pin_C0);
    output_high(pin_C1);
    output_low(pin_C2);
    delay_ms(500);

    clr_voice();
}

    if(!input(PIN_B0)){
      break;
    }
}

      if(f_next==TRUE){
          delay_ms(50);
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r Next : %02d:%02d  " ,t_feed.hr,t_feed.min);

          delay_ms(50);
      }else{
          delay_ms(50);
          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r                  ");
          delay_ms(50);
      }
   }

/***************** Rec Voice *********************/

void Rec_Voice(){

    lcd_gotoxy(1,1);
    printf(lcd_putc,"\r  Record Voice  ");

    show_menu();

while(1){

   if(input(PIN_B3)==0){

    delay_ms(50);
    lcd_gotoxy(1,2);
    printf(lcd_putc,"[REC]       [OK]");

    delay_ms(250);
    rec();

    break;
}

    if(!input(PIN_B0)){

      break;
    }


}


   }

#INT_EXT                         
void EXT_ISR(void)                
{
if(cnt==0){
    delay_ms(250);
    Set_Feed_Time();

    cnt=1;
}
 //ext_int_flag = TRUE;
}

/*******************************************************/

void main(){

lcd_init();

int16 next;
int tick_delay;
t_feed.sec_delay = 10;

clr_voice();

    enable_interrupts(GLOBAL);
    enable_interrupts(INT_EXT);  // Set external interrupt
    ext_int_edge(H_TO_L);        // External interrupt high to low edge

while(TRUE){
   delay_ms(50);

   if(cnt==1){
       delay_ms(250); 
       Set_Period_Time();
       delay_ms(250);
       Set_Time();
       delay_ms(250);

   cnt=0;
} 

   lcd_gotoxy(1,1);
   DS1307_ReadTime();

   if((t_feed.hr==bcd2bin(RTC.hr)) && (t_feed.min==bcd2bin(RTC.min))){
      if (delay_chk==0) {

       output_high(pin_C0);
       output_low(pin_C1);
       output_high(pin_C2);

        tick_delay=1;
        delay();
        delay_chk=1;

      next = next_time(24,60,5);
      t_feed.hr=next/60;
      t_feed.min=next%60;

          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r Next : %02d:%02d  " ,t_feed.hr,t_feed.min);
          delay_ms(50);

      }
   }else{
      delay_chk=0; 
   }

   if((tick_delay==1)&&(bcd2bin(RTC.sec)>=30)){
      clr_voice();
      tick_delay=0;
   }
      delay_ms(50);
      printf(lcd_putc,"\rTime : %2X:%2X:%2X\n", RTC.hr, RTC.min, RTC.sec);
      delay_ms(250);

   }
}

Now I remove external interrupt and change code like this. it can show menu when I push button but time still not run .

void main(){

lcd_init();

int16 next;
int tick_delay;
t_feed.sec_delay = 10;

clr_voice();

while(TRUE){
delay_ms(50);


if(input(PIN_B0)==0){
delay_ms(250);
    Set_Time();

    delay_ms(250); 
    Set_Period_Time();
    delay_ms(250);

    Rec_Voice();
    delay_ms(250);
    Play_Voice();
    delay_ms(250);
 Set_Feed_Time();

} 

   lcd_gotoxy(1,1);
   DS1307_ReadTime();
      printf(lcd_putc,"\rTime : %2X:%2X:%2X\n", RTC.hr, RTC.min, RTC.sec);
   delay_ms(100);

   if((t_feed.hr==bcd2bin(RTC.hr)) && (t_feed.min==bcd2bin(RTC.min))){
      if (delay_chk==0) {

   output_high(pin_C0);
   output_low(pin_C1);
   output_high(pin_C2);

     tick_delay=1;
     delay();
     delay_chk=1;

      next = next_time(24,60,5);
      t_feed.hr=next/60;
      t_feed.min=next%60;

          lcd_gotoxy(1,2);
          printf(lcd_putc,"\r Next : %02d:%02d  " ,t_feed.hr,t_feed.min);
          delay_ms(50);


      }
   }else{
   delay_chk=0; 
   }

   if((tick_delay==1)&&(bcd2bin(RTC.sec)>=30)){
   clr_voice();
   tick_delay=0;
   }
   }
}

Upvotes: 0

Views: 932

Answers (2)

Krista K
Krista K

Reputation: 21871

Wow, that IS a lot of code. I suggest breaking this down into the smallest parts of code you can compile and test with the hardware. THEN add functionality piece by piece to see what works or doesn't. Simulation is great however it is not at all the real world.

Check my post here for the code to talk to DS1307 via I2C. Using an Arduino, this was the most simple communication project I set out upon. Update: I got the RTC working on my PIC32 chipKIT uC32. I'm not sure what my malfunction was. :P I did implement pull-up resistors (2.7k?) and I2C / DS1307 does not get enough voltage if the board is fed 5V on the power connector. I can get RTC time if fed on USB power, though. Sadly, my uC32 gets way too hot on 9V or 12V, so I parallel off the 5V to feed the RTC.

Upvotes: 0

Alf
Alf

Reputation: 168

You must use for this device (DS1307) a 32.768kHz Quartz Crystal instead 20MHz Crystal. And don't forget to use the right capacitances. See datasheet of the device page 7.

Upvotes: 2

Related Questions