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

MAX6900 Realtime Clock (RTC)

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



Joined: 14 Jan 2004
Posts: 88
Location: Aurora, Ontario, Canada

View user's profile Send private message Visit poster's website

MAX6900 Realtime Clock (RTC)
PostPosted: Thu Feb 26, 2004 6:01 pm     Reply with quote

Hello.
I have a MAX6900 Realtime clock connected to the I2C port of a PIC18F6720. I can now read the time, set the time, but I can only set the time after a power cycle of the MAX6900. This is a tad annoying, and I would like to fix it so I can set the time anytime I want to.

if anyone has any ideas, I would be very greatful Smile

Kasper

PCWH 3.185,MPLAB 6.4, ICD2, WinXP ProSP1, AMD 3200+ 1GB RAM

( the Set_Seconds... Set_Year values contain BCD numbers to set the time with )


Code:

void Set_Time_MAX6900(void)
{
   output_float(eeprom_scl);
   output_float(eeprom_sda);
   delay_us(4);

     i2c_start();
     i2c_write(0xA0);
     i2c_write(0x8E);// control register
     i2c_write(0x00); // clear the write protect bit, bit 7
     i2c_stop();
    delay_ms(3); // after any read or write operation, do not talk to it for 2.5ms
     i2c_start();
     i2c_write(0xA0);
     i2c_write(0xBE);
    i2c_write(Set_Second);
    i2c_write(Set_Minute);
    i2c_write(Set_Hour);
    i2c_write(Set_Date);
    i2c_write(Set_Month);
    i2c_write(Set_Day);
    i2c_write(Set_Year);
    i2c_write(0x00);
     i2c_stop();
}
Kasper



Joined: 14 Jan 2004
Posts: 88
Location: Aurora, Ontario, Canada

View user's profile Send private message Visit poster's website

PostPosted: Fri Mar 19, 2004 4:00 pm     Reply with quote

*Bump*

I am assuming that I for whatever reason am not succeeding in clearing the write protect bit with my code.
Anyone has any ideas how to clear the write protect on it, if the above code does not appear to do anything?

Perhaps I should just go for another chip.. any suggestions for an I2C realtime clock, which is known and well supported with CCS?

Thanks in advance

Kasper
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 19, 2004 5:48 pm     Reply with quote

I think you should post the complete driver, and your test program.
(including all #define statements and ALL pre-processor statements).
I don't have enough information from your post to solve the problem.
Kasper



Joined: 14 Jan 2004
Posts: 88
Location: Aurora, Ontario, Canada

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 22, 2004 12:57 pm     Reply with quote

Sorry.. here is all the code I have. the read time function works fine, and the set time function also works, but ONLY after a powercycle on the MAX6900 :(


as for a test program.. load up the set time variables, and call Set_time_max6900. I have these variables global right now, but once they work that way, I will switch them over to be passed to the function.

Code:

// Time is in BCD format
   Set_Second  = 0x00;
   Set_Minute  = 0x53;
   Set_Hour    = 0x13;
   Set_Date    = 0x22;
   Set_Month   = 0x03;
   Set_Day     = 0x00;
   Set_Year    = 0x04;
   Set_Century = 0x20;
   Set_Time_MAX6900();

This works, but only after a powercycle :(
Code:


#ifndef EEPROM_SDA
   #define EEPROM_SDA  PIN_C4
   #define EEPROM_SCL  PIN_C3
#endif

#define MAX6900_ADDRESS 0xA0 // 0b1010000 R/W
#define BURST_WRITE     0xBE
#define BURST_READ     0xBF
#define SECONDS_write 0x80
#define SECONDS_read  0x81
#define Minutes_write 0x82
#define Minutes_read  0x83
#define Hours_write   0x84
#define Hours_read    0x85
#define date_write    0x86
#define date_read     0x87
#define Month_write   0x88
#define Month_read    0x89
#define Day_write     0x8A
#define Day_read      0x8B
#define Year_write    0x8C
#define Year_read     0x8D
#define Control_write 0x8E
#define Control_read  0x8F
#define Century_write 0x92
#define Century_read  0x93

#define RAM0_write    0xC0
#define RAM0_read     0xC1
#define RAM1_write    0xC2
#define RAM1_read     0xC3
#define RAM2_write    0xC4
#define RAM2_read     0xC5
#define RAM3_write    0xC6
#define RAM3_read     0xC7
#define RAM4_write    0xC8
#define RAM4_read     0xC9
#define RAM5_write    0xCA
#define RAM5_read     0xCB
#define RAM6_write    0xCC
#define RAM6_read     0xCD
#define RAM7_write    0xCE
#define RAM7_read     0xCF


// temp variables for the time setting

int Set_Year                    = 0;
int Set_Month                   = 0;      
int Set_Day                     = 0;      
int Set_Date                     = 0;      
int Set_Hour                    = 0;      
int Set_Minute                  = 0;      
int Set_Second                  = 0;      
int Set_Century                  = 32;

//for the realtime Clock

int Century= 0;   
int Year   = 0;
int Month  = 0;
int Day    = 0;
int Hour   = 0;
int Date   = 0;
int Minute = 0;
int Second = 0;
int RTCcontrol =0;


// This function writes time and date info to the MAX6900
//
void Set_Time_MAX6900(void)
{
delay_ms(10);
  output_float(eeprom_scl);
   output_float(eeprom_sda);
   delay_us(4);

     i2c_start();
     i2c_write(MAX6900_ADDRESS);
     i2c_write(Control_write);// control register
     i2c_write(0x00); // clear the write protect bit, bit 7
     i2c_stop();
    delay_ms(3); // after any read or write operation, do not talk to it for 2.5ms
     i2c_start();
     i2c_write(MAX6900_ADDRESS);
     i2c_write(BURST_WRITE);
    i2c_write(Set_Second);
    i2c_write(Set_Minute);
    i2c_write(Set_Hour);
    i2c_write(Set_Date);
    i2c_write(Set_Month);
    i2c_write(Set_Day);
    i2c_write(Set_Year);
    i2c_write(0x00);// Control register
     i2c_stop();

    delay_ms(3); // after any read or write operation, do not talk to it for 2.5ms
     i2c_write(MAX6900_ADDRESS); // burst write does not write century info.
     i2c_write(Century_write);
     i2c_write(0x20); // year 2000 in BCD :)
    delay_ms(3);// after any read or write operation, do not talk to it for 2.5ms
}

//This function loads up the variables, from Second to Year with the current time
// using a burst read, which is the preferred read to make sure none of the registers
// overflowed while reading.
// This function is tested, and works fine.

void Get_Time_MAX6900(void) {

   output_float(eeprom_scl);
   output_float(eeprom_sda);
   delay_us(4);

// in burst mode, the MAX6900 does not read the century byte.
     i2c_start();
     i2c_write(0xA0);
     i2c_write(0xBF);
     i2c_start();
     i2c_write(0xA1);
    Second =  i2c_READ();
    Minute =  i2c_READ();
    hour   =  i2c_READ();
    Date   =  i2c_READ();   
    Month  =  i2c_READ();
    Day    =  i2c_READ();   
    Year   =  i2c_READ();
    RTCcontrol=  i2c_READ(1);
     i2c_stop();
    delay_ms(3); // after any read or write operation, do not talk to it for 2.5ms
   Century= 32; ///20Hex .. reading the century seems to be screwy.. so it is not year 2100 compatible :o\
//fprintf(PORT2,"\rControlReg:=[%X]",RTCcontrol);
}



Maxim Tech support was kind enough to email me some code, which they claimed worked, unfortunately not in CCS format. As far as I can tell, I am doing exactly the same as they are.



Code:

Here's the routine I have used to enter the time and date several times, with no power cycling:

void Initialize_MAX6900()       /* ----------------------------------------- */
/* Note: NO error checking is done on the user entries! */
{
uchar   yr, mn, dt, dy, hr, min, sec, day;

        start2w();
        writebyte2w(ADD6900);   /* slave address + write */
        writebyte2w(0x8e);              /* control register write address */
        writebyte2w(0x00);              /* clear write protect */
        stop2w();

        printf("\nEnter the year (0-99): ");
        scanf("%bx", &yr);
        printf("Enter the month (1-12): ");
        scanf("%bx", &mn);
        printf("Enter the date (1-31): ");
        scanf("%bx", &dt);
        printf("Enter the day (1-7): ");
        scanf("%bx", &dy);
        printf("Enter the hour (1-23): ");
        scanf("%bx", &hr);
        hr = hr & 0x3f; /* force clock to 24 hour mode */
        printf("Enter the minute (0-59): ");
        scanf("%bx", &min);
        printf("Enter the second (0-59): ");
        scanf("%bx", &sec);

        start2w();
        writebyte2w(ADD6900);   /* slave address + write */
        writebyte2w(0xbe);              /* clock burst write */
        writebyte2w(sec);
        writebyte2w(min);
        writebyte2w(hr);
        writebyte2w(dt);
        writebyte2w(mn);
        writebyte2w(dy);
        writebyte2w(yr);
        writebyte2w(0);         /* control */
        start2w();
        writebyte2w(ADD6900);   /* slave address + write */
        writebyte2w(0x92);
        writebyte2w(0x20);              /* century data */
        stop2w();
}



Any help is appreciated Smile
Ttelmah
Guest







PostPosted: Mon Mar 22, 2004 1:07 pm     Reply with quote

Look carefully at what they do.
They are not sending a 'stop' between the data body, and the 'write' command, instead they send a 'repeated start' operation.

Best Wishes
Kasper



Joined: 14 Jan 2004
Posts: 88
Location: Aurora, Ontario, Canada

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 22, 2004 1:47 pm     Reply with quote

oops.. yes.. I fixed that. ( slaps myself for not seeing that part) Thanks! Smile
It seems that I can now set the time, without doing a power cycle on the chip, BUT, once I have read from the chip, using the
Get_Time_MAX6900() routine, I cannot set the time anymore, untill the program has been reset.. Sad

Maxim gave me this code for reading, whic works ( yes, I double checked it this time Wink).
My code reads the time fine too, so I have not suspected it to be causing problems, untill now....

Code:

Here is a code fragment for reading in burst mode that I believe has
worked in our lab:
start2w();
writebyte2w(ADD6900); /* slave address + write */
writebyte2w(0xbf); /* clock burst read */
start2w();
writebyte2w(ADD6900 + 1); /* slave address + read */
Sec = readbyte2w(ACK); /* starts w/last address stored in register
pointer */
Min = readbyte2w(ACK);
Hrs = readbyte2w(ACK);
Dte = readbyte2w(ACK);
Mon = readbyte2w(ACK);
Day = readbyte2w(ACK);
Yr  = readbyte2w(ACK);
cy  = readbyte2w(NACK);
stop2w();
Kasper



Joined: 14 Jan 2004
Posts: 88
Location: Aurora, Ontario, Canada

View user's profile Send private message Visit poster's website

PostPosted: Mon Mar 22, 2004 2:39 pm     Reply with quote

OK.. I have a solution, though not a pretty one.

It seems that all is well if I call the set_time_MAX6900 function twice in a row, instead of the once I was doing before.. strange chip this MAX6900 Smile
This works, now just be sure you send it BCD values, not straignt integers, or it will be displaying the time in strange hex numbers Smile

.. I still wonder why I have to do this though :o\
Code:

// This function writes time and date info to the MAX6900
//
void Set_Time_MAX6900(void)
{
/////////////////////////////////////////////////////////////////////////////////////
//yes.. it is retarted, but you have to do this twice :o\////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
int i;
for(i=0;i<2;i++) {
delay_ms(10);
  output_float(eeprom_scl);
   output_float(eeprom_sda);
   delay_us(4);

     i2c_start();
     i2c_write(MAX6900_ADDRESS);
     i2c_write(Control_write);// control register 0x8E
     i2c_write(0x00); // clear the write protect bit, bit 7
     i2c_stop();
    delay_ms(3); // after any read or write operation, do not talk to it for 2.5ms

     i2c_start();
     i2c_write(MAX6900_ADDRESS);
     i2c_write(BURST_WRITE);
    i2c_write(Set_Second);
    i2c_write(Set_Minute);
    i2c_write(Set_Hour);
    i2c_write(Set_Date);
    i2c_write(Set_Month);
    i2c_write(Set_Day);
    i2c_write(Set_Year);
    i2c_write(0x00);// Control register
     //i2c_stop();
     i2c_start();
    //delay_ms(3); // after any read or write operation, do not talk to it for 2.5ms
     i2c_write(MAX6900_ADDRESS); // burst write does not write century info.
     i2c_write(Century_write); //0x92
     i2c_write(0x20); // year 2000 in BCD :)
    i2c_stop();
    delay_ms(3);// after any read or write operation, do not talk to it for 2.5ms
}
/////////////////////////////////////////////////////////////////////////////////////
Ttelmah
Guest







PostPosted: Mon Mar 22, 2004 5:04 pm     Reply with quote

I must admit, it does seem very 'odd'. It makes me glad I have stuck with the DS1307, seems to be a 'doddle' to drive in comparison!..

Best Wishes
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