PROBLEM WITH DS1307

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

PROBLEM WITH DS1307

9,819 Views
ganimides
Contributor I
Hi guys!
 
I have several problems with DS1307 programming.
 
First, it would seem that the information appearing on my LCD screen does not match with the information programmed within the code.
I put by default the following:
 
 Seconds = 0;
 Minutes = 0x10;
 Hours = 0x12;
 Day = 4;      // day of week;
 Date = 0x11;
 Month = 5;
 Year = 6;
 
When it starts up On the LCD appears like this:
 
H: 18 m: 16: s:00 ------->.I think this not OK.
    
Second ,the seconds remain updating but do not stop when it reachs up to 59 seconds.It remains counting to 80 seconds and minutes do not increment.--->
 
why is it?
 
Third, how should be the hardware configured for proper working?.I pulled up the SDA pin at PORT C of 68HC908GP32.
 
If someone needs the code that I`m talking about to be able tocheck it out,please tell me.
 
Thank you so much!.
 
Ganimides.
Labels (1)
0 Kudos
9 Replies

684 Views
mke_et
Contributor IV

When I did my 1307 routines, I did the 'bit-test' stuff I needed to do 'up front'

and masked that off the data.  Then took the 'number' portion of the data and

dropped that into my BCD_to_BIN routine. 

 

When I had to set the data, I did it very similar.  Did the BIN_to_BCD on the

data, then 'or' in the other bits and write it back. 

 

It's not rocket science, but if you don't modularize what you're doing with

specific 'in and out' routines, you can get messed real quick.

 

0 Kudos

684 Views
UK_CF_FAE
NXP Employee
NXP Employee

Hi Ganimides,

I don't see the problem. Your H, M, S variables are initialised in HEX, and displayed in decimal.

Minutes = 0x10; //converts to 16 decimal

Hours = 0x12; //converts to 18 decimal

I did not check your code but I imagine that the software has a data-type issue which is stopping the seconds wrapping round and minutes updating.

Mark

0 Kudos

684 Views
ganimides
Contributor I

Hi guys!.

Thank you for taking time to see my code!.

Yes you are right,yesterday night I looked around much better my code I realized that I`m displaying my data in BCD format because of the jumps that it has.

The problem is that I just need to make some routine to convert BCD to binary data so that I can send it out to LCD display.

 

Greetings!

Ganimides.

 

 

0 Kudos

684 Views
bigmac
Specialist III

Hello Ganimides,

It may be simpler to convert each BCD digit to its ASCII value, and place the characters at the appropriate positions within a string (array).  The string could then be directly sent to the LCD.

unsigned char upper_chr (unsigned char value)
{
  return ((value >> 4) + 0x30);
}

unsigned char lower_chr (unsigned char value)
{
  return ((value & 0x0F) + 0x30);
}

Regards,
Mac

 

0 Kudos

684 Views
ganimides
Contributor I
Hi Bigmac!.
 
I`m a little confused  with the method you described to me because I have some routine inside my LCD printig function doing something like you are mentioning.
 
I show you here the 2 functions that I`m using for as follows:
 
 
void printf_LCD_4bits(unsigned char fila, unsigned char columna, char *texto,char value)
{
 unsigned char adrs;
    adrs = columna - 1;
    if(fila == 2)
   adrs = adrs | 0x40;
   Ctrl4bits(adrs | 0x80);
   while(*texto)
  
 Datos4bits(*texto++);
 Datos4bits(':');
 Datos4bits( ((value%1000)/100)+0x30); <---look at this....
 Datos4bits( ((value%100)/10)+0x30);
 Datos4bits( (value%10)+0x30);

}
 
 
void main (void)
 
  {
 
 DDRA_DDRA4=1 ;
 
 DDRB_DDRB4=1 ;
 DDRB_DDRB5=1 ;
 DDRB_DDRB6=1 ;
 DDRB_DDRB7=1 ;
 
 DDRC_DDRC0=1 ;
 
 DDRC_DDRC3=1 ;
 DDRC_DDRC4=1 ;
 
 
//EnableInterrupts; /* enable interrupts */
 
 InitPLL();
 
 Config_LCD_4bits();
 
 
 Write_Control_reg(3);  // squarewave output 32.768kHz at RTC SQW pin;
 Init_Time_Default();
 WriteRTC();
 for(;:smileywink:
 {
   __RESET_WATCHDOG(); /* feeds the dog */
   
   Hours   = (ReadRTCbyte(2)+(0x30));
   Minutes = (ReadRTCbyte(1)+(0x30));
   Seconds = (ReadRTCbyte(0)+(0x30));  
    
   printf_LCD_4bits (1,1,"h",Hours);
   printf_LCD_4bits (1,6,"m",Minutes);
   printf_LCD_4bits (1,12,"s",Seconds);
 
   //PTA = RD_data;             // Show RTC info on LEDs;
   //PTB = RD_data;             // Show RTC info on LEDs;
   
   //wait_time(250);
   //asm nop;
   
 } /* loop forever */
    
 
You suggested this:
 
void upper_char (char value);
{
   return (value << 4 + 0x30);
}
 
void lower_char (char value);
{
   return (value | 0F + 0x30);
}
 
 
The questions would be.....where sould I set the code you mentioned to process the incoming BCD chars?.
 
 
Thank you very very much Big!!!
 
 
Ganimides
 

Message Edited by ganimides on 05-17-200608:57 AM

0 Kudos

684 Views
bigmac
Specialist III

Hello Ganimides,

Since the DS1307 registers are already in BCD format, it is simpler to do BCD to ASCII conversion, rather than BCD to binary conversion, followed by binary to ASCII conversion.  The following sequence within your code actually provides the binary to ASCII conversion, and would not be required with my proposal.

Datos4bits(((value%1000)/100)+0x30);
Datos4bits(((value%100)/10)+0x30);
Datos4bits((value%10)+0x30);

The DS1307 actually uses packed BCD format, with two digits represented by a single byte.  The purpose of the upper_chr() and lower_chr() functions is to unpack each BCD digit, and convert to an ASCII byte.

The suggested new and modified functions follow.  The printf_LCD_4bits() function would now only need to output a text string.

unsigned char upper_char (unsigned char value);
{
  return ((value >> 4) + 0x30);
}
 
unsigned char lower_char (unsigned char value);
{
  return ((value & 0x0F) + 0x30);
}

void printf_LCD_4bits(unsigned char fila, unsigned char columna, char *texto)
{
  unsigned char adrs;
  adrs = columna - 1;
  if(fila == 2)
     adrs = adrs | 0x40;
  Ctrl4bits(adrs | 0x80);

  while(*texto)
     Datos4bits(*texto++);
}

The following code could then be included within main(), or within another function.

unsigned char LCDtext[] = "xxh:xxm:xxs";
unsigned char Hours, Minutes, Seconds;

Hours   = ReadRTCbyte(2) & 0x3F; // 24hr format assumed
Minutes = ReadRTCbyte(1) & 0x7F; // Mask 7 bits only
Seconds = ReadRTCbyte(0) & 0x7F; // Mask 7 bits only
    
LCDtext[0] = upper_chr (Hours);
LCDtext[1] = lower_chr (Hours);
LCDtext[4] = upper_chr (Minutes);
LCDtext[5] = lower_chr (Minutes);
LCDtext[8] = upper_chr (Seconds);
LCDtext[9] = lower_chr (Seconds);
   
printf_LCD_4bits (1,1,LCDtext);

I hope this clarifies the situation.

Regards,
Mac


 

Message Edited by bigmac on 05-18-200605:51 PM

0 Kudos

684 Views
ganimides
Contributor I
Dear friend Bigmac:
 
Thank you very much for your support ,help and great explanation.I`ll get this in practice and I tell you later.Every day I learn something.
 
have a nice week!:smileywink:
 
 
 
Ganimides
0 Kudos

684 Views
Wings
Contributor I
Just want to add to what UKCFFAE said... the clock registers keep time in binary coded decimal (BCD) and you seem to be displaying the time registers as straight binary.

Also, it seems like your hardware must be set up correctly or you probably wouldn't be seeing anything at all from the clock registers.
0 Kudos

684 Views
ganimides
Contributor I
Hi guys ,here is the code of DS1307 that I`m implementing  above:
 
Code:
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */#include <MC68HC908GP32.h>//#include <lcd.h>#include <stdio.h>//#include <lcd.c>#define SDA  PTC_PTC6#define SCL  PTC_PTC5#define DIR_SDA  DDRC_DDRC6#define DIR_SCL  DDRC_DDRC5#define SPEED  4               #define HOLD   1#define SLAVE_ADDRESS   0xD0   #define LEN             58     byte temp, dummy, RD_data, WR_data, ACK_flag, w, i;byte own_sl_addr = 0xD0;  byte RAM_Data[LEN];byte RTC_reg[7] @0x60;    byte Cntr_reg   @0x67;typedef struct{  byte Sec;  byte Min;  byte Hrs;  byte Day;  byte Date;  byte Month;  byte Year;}sRTC;volatile sRTC RTC @0x60;    #define Seconds         RTC.Sec#define Minutes         RTC.Min#define Hours           RTC.Hrs#define Day             RTC.Day#define Date            RTC.Date#define Month           RTC.Month#define Year            RTC.Year#define RTC_REG_START   0x00#define NV_RAM_START    0x08  /* Function definition *///void Init_CPU(void);void Init_Time_Default(void);byte GetByte(void);void WriteIICbus(byte data);void Write_Control_reg(byte ctrl);void Read_ACK(void);void Write_ACK(void);void StartBit(void);void StopBit(void);void Wait_time(byte time);void Wait_sh(byte time);void InitPLL(void);extern void LCDdelay(void);extern void Ctrl8bits(unsigned char codigo);extern void Ctrl4bits(unsigned char codigo);extern void Datos4bits(unsigned char dato);extern void Config_LCD_4bits(void);extern void printf_LCD_4bits(unsigned char fila, unsigned char columna, char *texto,char value);  void InitPLL(void){  CONFIG1 = 0x01;  CONFIG2 = 0x00;  PCTL_BCS = 0;               PCTL_PLLON = 0;      /* Disable the PLL */ /* PCTL: PLLIE=0,PLLF=0,PLLON=0,BCS=0,PRE1=0,PRE0=0,VPR1=1,VPR0=0 */ PCTL = 0x02;              /* VCO Power-of-Two multiplier E=2 */ /* PMS: MUL11=0,MUL10=0,MUL9=1,MUL8=1,MUL7=1,MUL6=1,MUL5=0,MUL4=1,MUL3=0,MUL2=0,MUL1=0,MUL0=1 */ PMS = 0x03D1;           /* Feedback divider N=977 */ /* PMRS: VRS7=1,VRS6=1,VRS5=0,VRS4=1,VRS3=0,VRS2=0,VRS1=0,VRS0=0 */ PMRS = 0xD1;             /* VCO Linear multiplier L=208 */ /* PMDS: RDS3=0,RDS2=0,RDS1=0,RDS0=1 */ PMDS = 0x01;             /* Reference clock devider R=1 */ /* PBWC: AUTO=1,LOCK=0,ACQ=0,—–=0,˜™=0,??=0,??=0,??=0 */ PBWC = 0x80;             /* Select the operating modes */   /* PCTL: PLLON=1 */ PCTL_PLLON = 1;          /* Enable the PLL */ while(!PBWC_LOCK) {                  /* Wait */ } /* PCTL: BCS=1 */ PCTL_BCS = 1;            /* Select clock source from PLL */ __asm("nop"); __asm("nop"); }void Init_Time_Default(void)  // see datasheet of DS1338;{ Seconds = 0; Minutes = 0x10; Hours = 0x12; Day = 4;      // day of week; Date = 0x11; Month = 5; Year = 6;}//********************************************************************void Write_Control_reg(byte ctrl)  // writes Cntr_reg to RTC;{ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) {   StopBit();   return; } WriteIICbus(7);  // write address of the Control register; Read_ACK(); if(ACK_flag !=0) {   StopBit();   return; } WriteIICbus(ctrl);  // write value into Control register; Read_ACK(); if(ACK_flag !=0) {   StopBit();   return; } StopBit();}//********************************************************************void Read_Control_reg(void)   // reads Cntr_reg from RTC;{ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); // RW bit = 0; asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) {   StopBit();   return; } WriteIICbus(7);  // write address of the Control register; Read_ACK(); if(ACK_flag !=0) {   StopBit();   return; } StartBit(); WriteIICbus(SLAVE_ADDRESS | 1); // RW bit = 1; Read_ACK(); if(ACK_flag !=0) {   StopBit();   return; } DIR_SDA = 0; Cntr_reg = GetByte();  // read value from the Control register and save it; StopBit();}//********************************************************************void WriteRTC(void){ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) {   StopBit();   return; } WriteIICbus(0);  // Starts write from address "0" in RTC (Seconds); Read_ACK(); if(ACK_flag !=0) {   StopBit();   return; } for(i=0;i<7;i++) {   WriteIICbus(RTC_reg[i]);   Read_ACK();   if(ACK_flag !=0)   {     StopBit();     return;   } } StopBit();}//********************************************************************byte ReadRTCbyte(byte addr){ ACK_flag = 0; StartBit(); WriteIICbus(SLAVE_ADDRESS); // RW bit = 0; asm nop; Read_ACK(); asm nop; if(ACK_flag !=0) {   StopBit();   return 0; } WriteIICbus(addr); Read_ACK(); if(ACK_flag !=0) {   StopBit();   return 0; } StartBit(); WriteIICbus(SLAVE_ADDRESS | 1); // RW bit = 1; Read_ACK(); if(ACK_flag !=0) {   StopBit();   return 0; } DIR_SDA = 0; RD_data = GetByte(); StopBit(); return RD_data;}//********************************************************************byte GetByte(void){ byte tempb, i;  tempb = 0; for(i=0;i<8;i++) {   tempb = tempb << 1;   SCL = 1;   Wait_sh(SPEED);   tempb = tempb | SDA;   SCL = 0;   Wait_sh(SPEED - HOLD); } return tempb;}//********************************************************************void WriteIICbus(byte data){ byte tempb, i;  tempb = data; for(i=0;i<8;i++) {   SDA = ((tempb & 0x80)>>7);   tempb = tempb << 1;   Wait_sh(HOLD);   SCL = 1;   Wait_sh(SPEED);   SCL = 0;   Wait_sh(SPEED - HOLD); }}//********************************************************************void Read_ACK(void){ DIR_SDA = 0; Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); ACK_flag = SDA; SCL = 0; DIR_SDA = 1;}//********************************************************************void Write_ACK(void){ DIR_SDA = 1; SDA = 0; Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); SCL = 0; Wait_sh(HOLD);}//********************************************************************void StartBit(void){ SDA = 1; SCL = 1; DIR_SDA = 1; DIR_SCL = 1; Wait_sh(SPEED); Wait_sh(SPEED); SDA = 0; Wait_sh(SPEED); SCL = 0; Wait_sh(SPEED);}//********************************************************************void StopBit(void){ Wait_sh(HOLD); SCL = 1; Wait_sh(SPEED); SDA = 1;}//***************************************************************************void Wait_time(byte time){  const word k = 250;  word i, temp_t = (time*k);  for (i=0;i<temp_t;i++)     {     asm nop;     }}//********************************************************************void Wait_sh(byte time){  word i, temp_t = time;  for (i=0;i<temp_t;i++)     {     asm nop;     }}void main (void)   {  DDRA_DDRA4=1 ;  DDRB_DDRB4=1 ; DDRB_DDRB5=1 ; DDRB_DDRB6=1 ; DDRB_DDRB7=1 ;  DDRC_DDRC0=1 ;  DDRC_DDRC3=1 ; DDRC_DDRC4=1 ;  EnableInterrupts; /* enable interrupts */  InitPLL(); Config_LCD_4bits();   Write_Control_reg(3);  // squarewave output 32.768kHz at RTC SQW pin; Init_Time_Default(); WriteRTC(); for(;;) {   __RESET_WATCHDOG(); /* feeds the dog */      Hours   = ReadRTCbyte(2);   Minutes = ReadRTCbyte(1);   Seconds = ReadRTCbyte(0);             Datos4bits (0x01);   printf_LCD_4bits (1,1,"h",Hours);                           printf_LCD_4bits (1,6,"m",Minutes);   printf_LCD_4bits (1,12,"s",Seconds);   //PTA = RD_data;             // Show RTC info on LEDs;   //PTB = RD_data;             // Show RTC info on LEDs;      //wait_time(250);   //asm nop;    } /* loop forever */ /* please make sure that you never leave this function */}  

 
(Alban put code in SRC for lisibility) 
 

 
 
 
 
 
 

Message Edited by Alban on 05-16-2006 01:32 PM

0 Kudos