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 bcd to decimal why add 48?

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



Joined: 29 Sep 2020
Posts: 17

View user's profile Send private message

ds1307 bcd to decimal why add 48?
PostPosted: Fri Nov 06, 2020 6:46 am     Reply with quote

hello everyone
The code I have shown below is the part of the conversion from bcd to decimal to ds1307..

Why did we add 48 after converting bcd to binary code?
time[12] = second % 10 + 48;
pls explain me?

for example: second is bcd 48
48 binary: 0011 0000
0011 0000 >> 4
0000 0011 : 03
3x10= 30

0011 0000 & 0000 1111
0000 0000

30+0 =30

and our second : decimal = 30

so why we are add to 48?

Code:
char time[] = "TIME:  :  :  ";
char calendar[] = "DATE:  /  /20  ";
unsigned int8  second, minute, hour, date, month, year, day;
void ds1307_display(){
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour = (hour >> 4) * 10 + (hour & 0x0F);
  date = (date >> 4) * 10 + (date & 0x0F);
  month = (month >> 4) * 10 + (month & 0x0F);
  year = (year >> 4) * 10 + (year & 0x0F);
  // End conversion
  time[12]     = second % 10  + 48;
  time[11]     = second / 10  + 48;
  time[9]      = minute % 10  + 48;
  time[8]      = minute / 10  + 48;
  time[6]      = hour % 10  + 48;
  time[5]      = hour / 10  + 48;
  calendar[14] = year % 10 + 48;
  calendar[13] = year / 10  + 48;
  calendar[9]  = month % 10 + 48;
  calendar[8]  = month / 10 + 48;
  calendar[6]  = date % 10 + 48;
  calendar[5]  = date / 10 + 48;
  lcd_gotoxy(1, 1);                              // Go to column 1 row 1
  printf(lcd_putc, time);                        // Display time
  lcd_gotoxy(1, 2);                              // Go to column 1 row 2
  printf(lcd_putc, calendar);                    // Display calendar
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Nov 06, 2020 6:53 am     Reply with quote

Look at the codes for the number 0 in this table:
https://en.cppreference.com/w/cpp/language/ascii
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Nov 06, 2020 8:09 am     Reply with quote

As I pointed out to another poster in a recent thread, it is critical to
understand that the ASCII digit '0', is not the 'number' 0.

Conversion between the two involves an offset (in decimal), of '48'.

The table PCM_Programmer points you to, shows the numeric values for
characters, and gives this offset....
akay



Joined: 29 Sep 2020
Posts: 17

View user's profile Send private message

PostPosted: Fri Nov 06, 2020 4:57 pm     Reply with quote

i know this is not related in this topic, but there is an issue i cannot solve..
when i push "asagi" (enter to switch menu) the numbers are mixed up and the program freezes...
it works normally when there is no menu(switch case menu) ..
i think there is an mistake in the transition from decimal to bcd..


Code:
#define LCD_ENABLE_PIN  PIN_D0                                    ////
#define LCD_RS_PIN      PIN_D2                                    ////
#define LCD_RW_PIN      PIN_D1                                    ////
#define LCD_DATA4       PIN_D4                                    ////
#define LCD_DATA5       PIN_D5                                    ////
#define LCD_DATA6       PIN_D6                                    ////
#define LCD_DATA7       PIN_D7                                    ////

#include <16F877a.h>
#device adc=10    //adc yi 10 bit olarak kullandik YANI 0-5V ARASINI 2uzeri10 parcaya boler         2 uzeri 10 = 1023 olur         5V/1023=0,00488758553V
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NODEBUG
#define use_portd_lcd TRUE

#use delay(clock = 8000000)
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
#include <lcd.c>

int8 menu=0, menu_say=0, set_m=0;

#define YUKARI PIN_C2
#define ASAGI PIN_C5
char zaman[] = "saat:  :  :  ";
char takvim[] = "tarih:  /  /  ";
unsigned int8  saniye, dakika, saat, gun, ay, yil, haftaningunu;

///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
void ana_ekran()
{
  saniye = (saniye >> 4) * 10 + (saniye & 0x0F);
  dakika = (dakika >> 4) * 10 + (dakika & 0x0F);
  saat = (saat >> 4) * 10 + (saat & 0x0F);
  gun = (gun >> 4) * 10 + (gun & 0x0F);
  ay = (ay >> 4) * 10 + (ay & 0x0F);
  yil = (yil >> 4) * 10 + (yil & 0x0F);
  // End conversion
  zaman[12]     = saniye % 10  + 48;
  zaman[11]     = saniye / 10  + 48;
  zaman[9]      = dakika % 10  + 48;
  zaman[8]      = dakika / 10  + 48;
  zaman[6]      = saat % 10  + 48;
  zaman[5]      = saat / 10  + 48;
  takvim[13] = yil % 10 + 48;
  takvim[12] = yil / 10  + 48;
  takvim[10]  = ay % 10 + 48;
  takvim[9]  = ay / 10 + 48;
  takvim[7]  = gun % 10 + 48;
  takvim[6]  = gun / 10 + 48;
lcd_gotoxy(1,1);                              // Go to column 1 row 1
  printf(lcd_putc,zaman);                        // Display time
  lcd_gotoxy(1,2);                              // Go to column 1 row 2
  printf(lcd_putc,takvim); 
}
///////////////////////////////////////////////////////////////////////////////
void ds1307_veriyaz(unsigned int8 adres, datalar)
{
  i2c_start();                                   // Start I2C protocol
  i2c_write(0xD0);                               // DS1307 address
  i2c_write(adres);                            // Send register address
  i2c_write(datalar);                              // Write data to the selected register
  i2c_stop();                                    // Stop I2C protocol
}

void ds1307_okuma()
{
   i2c_start();                         // Start I2C
   i2c_write(0xD0);                     // DS1307 address
   i2c_write(0x00);                        // Send register address
   i2c_start();                         // Restart I2C
   i2c_write(0xD1);                     // Initialize data read
   saniye =i2c_read(1);                 // Read seconds from register 0
   dakika =i2c_read(1);                 // Read minuts from register 1
   saat = i2c_read(1);                  // Read hour from register 2
   haftaningunu = i2c_read(1);                   // Read day from register 3
   gun = i2c_read(1);                  // Read date from register 4
   ay = i2c_read(1);                 // Read month from register 5
   yil = i2c_read(0);                  // Read year from register 6
   i2c_stop();                          // Stop I2C
}
////////////////////////////////////////////////////////////////////////////////
void main(){
  lcd_init();               
  lcd_putc('\f');
 
  while(TRUE)
  {
  ds1307_okuma();                       // Read data from DS1307 RTCC
  delay_ms(20);
   IF ((menu==0))
{ ana_ekran (); }
 
if (input(ASAGI)&&(menu==0)) // ENTER A BASILIRSA VE MENU=0 ISE
   {
   delay_ms(300);
   printf(lcd_putc,"\f");
   menu=1;                    // MENU LOJIK 1 OLUR                 
   menu_say=0;               // MENU_SAY LOJIK 0 OLUR                // M_SN LOJIK 0 OLUR
   }
   
   if (menu>0)   // MENU 0'DAN BUYUK VE SET_M LOJIK 0 ISE
   {     
   switch(menu_say)
            {
            case 0:
            printf(lcd_putc,"\f");
               lcd_gotoxy(1,1);
               printf(lcd_putc,"Software&Circuit");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"Akay AYDIN");//EGER ENTER'A BASILIR VE M_SN 0 DAN BUYUKSE set menüye git
               break;
            case 1:
            printf(lcd_putc,"\f");
              lcd_gotoxy(1,1);
              printf(lcd_putc,"Dakika AYARI");
              lcd_gotoxy(1,2);
              printf(lcd_putc,"%02u", dakika);
              if(input(YUKARI)) dakika++;
              if(dakika > 59)
              dakika = 0;
               break;
            case 2:
            printf(lcd_putc,"\f");
               lcd_gotoxy(1,1);
               printf(lcd_putc,"Saat AYARI");
               lcd_gotoxy(1, 2);                     
               printf(lcd_putc,"%02u", saat);
               if(input(YUKARI)) saat++;
               if(saat > 23)
               saat = 0;
               break;
            case 3:
               printf(lcd_putc,"\f");
               lcd_gotoxy(1,1);
               printf(lcd_putc,"Gun AYARI");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"%02u", gun);
               if(input(YUKARI)) gun++;
               if(gun > 31)
               gun = 1;
               
               break;
            case 4:
            printf(lcd_putc,"\f");
            lcd_gotoxy(1,1);
               printf(lcd_putc,"Ay AYARI");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"%02u", ay);
               if(input(YUKARI)) ay++;
               if(ay > 12)
               ay = 1;   
            break;
            case 5:
            printf(lcd_putc,"\f");
             lcd_gotoxy(1,1);
               printf(lcd_putc,"YIL AYARI");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"%02u", yil);
               if(input(YUKARI)) yil++;
               if(yil > 99)
               yil = 20;   
               BREAK;
                case 6:
                 printf(lcd_putc,"\f");
             lcd_gotoxy(1,1);
               printf(lcd_putc,"Gun AYARI");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"akay");
               if(input(YUKARI)) haftaningunu++;
               if(haftaningunu > 6)
               haftaningunu = 0;   
               BREAK;
                CASE 7:
                printf(lcd_putc,"\f");
                DELAY_MS(20);
                menu=0;
            } 
            if(input(ASAGI)&&(menu_say<8)) //EGER ASAGI TUSUNA BASILIR VE MENU_SAY 4'DEN KUCUK USE
               {
               DELAY_MS(25);
               menu_say=menu_say+1;
               if(menu_say==8)
               ana_ekran();
               DELAY_MS(20);
               }
               IF(MENU==1){
      // Convert decimal to BCD
      dakika = ((dakika / 10) << 4) + (dakika % 10);         
      saat = ((saat / 10) << 4) + (saat % 10);
      gun = ((gun / 10) << 4) + (gun % 10);
      ay = ((ay / 10) << 4) + (ay % 10);
      yil = ((yil / 10) << 4) + (yil % 10);
      // End conversion
     // Write minute value to DS1307
   ds1307_veriyaz(1, dakika);
      ds1307_veriyaz(2, saat);
      ds1307_veriyaz(4, gun);
      ds1307_veriyaz(5, ay);
      ds1307_veriyaz(6, yil);
      ds1307_veriyaz(0, 0);                        //Reset seconds and start oscillator
      delay_ms(200);
                }
   }
               
}
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Sat Nov 07, 2020 2:56 am     Reply with quote

Learn to actually indent your code so the indentation reflects what is actually happening. Then 'think'.
Code:

#define LCD_ENABLE_PIN  PIN_D0                                    ////
#define LCD_RS_PIN      PIN_D2                                    ////
#define LCD_RW_PIN      PIN_D1                                    ////
#define LCD_DATA4       PIN_D4                                    ////
#define LCD_DATA5       PIN_D5                                    ////
#define LCD_DATA6       PIN_D6                                    ////
#define LCD_DATA7       PIN_D7                                    ////
#include <16F877a.h>
#device adc=10    //adc yi 10 bit olarak kullandik YANI 0-5V ARASINI 2uzeri10 parcaya boler         2 uzeri 10 = 1023 olur         5V/1023=0,00488758553V
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NODEBUG
#define use_portd_lcd TRUE
#use delay(clock = 8000000)
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
#include <lcd.c>

int8 menu=0, menu_say=0, set_m=0;

#define YUKARI PIN_C2
#define ASAGI PIN_C5

char zaman[] = "saat:  :  :  ";

char takvim[] = "tarih:  /  /  ";
unsigned INT8  saniye, dakika, saat, gun, ay, yil, haftaningunu;

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void ana_ekran()
{
   saniye = (saniye >> 4) * 10 + (saniye&0x0F);
   dakika = (dakika >> 4) * 10 + (dakika&0x0F);
   saat = (saat >> 4) * 10 + (saat&0x0F);
   gun = (gun >> 4) * 10 + (gun&0x0F);
   ay = (ay >> 4) * 10 + (ay & 0x0F);
   yil = (yil >> 4) * 10 + (yil&0x0F);

   // End conversion
   zaman[12] = saniye % 10 + 48;
   zaman[11] = saniye / 10 + 48;
   zaman[9] = dakika % 10 + 48;
   zaman[8] = dakika / 10 + 48;
   zaman[6] = saat % 10 + 48;
   zaman[5] = saat / 10 + 48;
   takvim[13] = yil % 10 + 48;
   takvim[12] = yil / 10 + 48;
   takvim[10] = ay % 10 + 48;
   takvim[9] = ay / 10 + 48;
   takvim[7] = gun % 10 + 48;
   takvim[6] = gun / 10 + 48;
   lcd_gotoxy(1,1);                              // Go to column 1 row 1
   printf (lcd_putc, zaman);      // Display time
   lcd_gotoxy (1, 2);       // Go to column 1 row 2
   printf (lcd_putc, takvim);
}

///////////////////////////////////////////////////////////////////////////////
void ds1307_veriyaz(UNSIGNED int8 adres, datalar)
{
   i2c_start ();         // Start I2C protocol
   i2c_write (0xD0);        // DS1307 address
   i2c_write (adres);       // Send REGISTER address
   i2c_write (datalar);       // Write data to the selected REGISTER
   i2c_stop ();         // Stop I2C protocol
}

void ds1307_okuma()
{
   i2c_start ();      // Start I2C
   i2c_write (0xD0);     // DS1307 address
   i2c_write (0x00);      // Send REGISTER address
   i2c_start ();      // Restart I2C
   i2c_write (0xD1);     // Initialize data read
   saniye = i2c_read (1);    // Read seconds from REGISTER 0
   dakika = i2c_read (1);    // Read minuts from REGISTER 1
   saat = i2c_read (1);    // Read hour from REGISTER 2
   haftaningunu = i2c_read (1);     // Read day from REGISTER 3
   gun = i2c_read (1);    // Read date from REGISTER 4
   ay = i2c_read (1);    // Read month from REGISTER 5
   yil = i2c_read (0);    // Read year from REGISTER 6
   i2c_stop ();      // Stop I2C
}

////////////////////////////////////////////////////////////////////////////////
void main()
{
   lcd_init ();
   lcd_putc ('\f') ;

   WHILE (TRUE)
   {
      ds1307_okuma ();      // Read data from DS1307 RTCC
      delay_ms (20) ;

      IF ((menu == 0))
      { ana_ekran (); }
      IF (input(ASAGI)&&(menu==0)) // ENTER A BASILIRSA VE MENU=0 ISE
      {
         delay_ms (300) ;
         printf (lcd_putc, "\f") ;
         menu = 1;     // MENU LOJIK 1 OLUR
         menu_say = 0;    // MENU_SAY LOJIK 0 OLUR    // M_SN LOJIK 0 OLUR
      }

     
      IF (menu > 0) // MENU 0'DAN BUYUK VE SET_M LOJIK 0 ISE
      {
         SWITCH (menu_say)
         {
            CASE 0:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "Software&Circuit") ;
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, "Akay AYDIN"); //EGER ENTER'A BASILIR VE M_SN 0 DAN BUYUKSE set menüye git
            BREAK;

            CASE 1:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "Dakika AYARI") ;
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, " % 02u", dakika);
            IF (input (YUKARI)) dakika++;

            IF (dakika > 59)
               dakika = 0;

            BREAK;

            CASE 2:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "Saat AYARI") ;
            lcd_gotoxy (1, 2);
            printf (lcd_putc, " % 02u", saat);
            IF (input (YUKARI)) saat++;

            IF (saat > 23)
               saat = 0;

            BREAK;

            CASE 3:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "Gun AYARI") ;
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, " % 02u", gun);
            IF (input (YUKARI)) gun++;

            IF (gun > 31)
               gun = 1;

           
            BREAK;

            CASE 4:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "Ay AYARI") ;
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, " % 02u", ay);
            IF (input (YUKARI)) ay++;

            IF (ay > 12)
               ay = 1;

            BREAK;

            CASE 5:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "YIL AYARI") ;
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, " % 02u", yil);
            IF (input (YUKARI)) yil++;

            IF (yil > 99)
               yil = 20;

            BREAK;

            CASE 6:
            printf (lcd_putc, "\f") ;
            lcd_gotoxy (1, 1) ;
            printf (lcd_putc, "Gun AYARI") ;
            lcd_gotoxy (1, 2) ;
            printf (lcd_putc, "akay") ;
            IF (input (YUKARI)) haftaningunu++;

            IF (haftaningunu > 6)
               haftaningunu = 0;

            BREAK;

            CASE 7:
            printf (lcd_putc, "\f") ;
            DELAY_MS (20) ;
            menu = 0;
         }

         IF (input (ASAGI)&& (menu_say < 8)) //EGER ASAGI TUSUNA BASILIR VE MENU_SAY 4'DEN KUCUK USE
         {
            DELAY_MS (25) ;
            menu_say = menu_say + 1;

            IF (menu_say == 8)
               ana_ekran () ;

            DELAY_MS (20) ;
         }

         IF (MENU == 1)
         {
            // Convert decimal to BCD
            dakika = ( (dakika / 10) << 4) + (dakika % 10);
            saat = ( (saat / 10) << 4) + (saat % 10);
            gun = ( (gun / 10) << 4) + (gun % 10);
            ay = ( (ay / 10) << 4) + (ay % 10);
            yil = ( (yil / 10) << 4) + (yil % 10);

            // End conversion
            // Write minute value to DS1307
            ds1307_veriyaz (1, dakika);
            ds1307_veriyaz (2, saat);
            ds1307_veriyaz (4, gun);
            ds1307_veriyaz (5, ay);
            ds1307_veriyaz (6, yil);
            ds1307_veriyaz (0, 0);      //Reset seconds and start oscillator
            delay_ms (200) ;
         }
      }
   }
}


The big problem is that you set 'menu' to 1 the first time ASAGI is
pushed. It goes through the dakika setting, and then sets the clock chip.
The values used for all the other variables will be random numbers
depending on what the variables just happen to have in them at boot.
You then go through all the other settings, and the clock doesn't get
updated again. So when you get to case 8, and display the value,
you probably have garbage.....

The actual logic of your code is flawed.
akay



Joined: 29 Sep 2020
Posts: 17

View user's profile Send private message

PostPosted: Sat Nov 07, 2020 5:14 am     Reply with quote

thank u your valuable message..
so what can i do for fix this code?
could you pls help me to fix?
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Sat Nov 07, 2020 12:43 pm     Reply with quote

That's down to you writing your program correctly.

You need to input all the time/date fields, and write to the chip when all are
finished, not just after the first one.
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