Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
03/12/10 06:30
Read: times


 
#174029 - DS1307 interface issues with silabs 8051f340
I am trying to interface RTC DS1307 with c8051f340 chip working at 48 MHz. I am clocking SCL through 25ms timer. I have isolated the code into a separate program to make sure that no other code is affecting my RTC_read. This code has only RTC and timer routines.
The problem is that, RTC registers are reading 0xff. But, when I scale down the system clock to 12 MHz, (while maintaining the same delay of 25 ms) then I am able to read the RTC. Delay routine is just a loop that checks the timer. I loop in the delay loop for 25 milliseconds to clock the RTC. I have also tried with other delays – 10 microseconds for 100 KHz operation – but to no avail. Things are fine at 12MHz, but at 48, it doesn’t work, even though I am maintaining the same timings!!
Please guide as to where the code is going wrong. I have also posted this in Silabs also.
Code is as below (controller clock = 48MHz):
---------------------------------------------------------

#define SYSCLK 48000000 // sysclk on which oscillator is configured
typedef unsigned char uint8;
#define LED_TOGGLE_RATE 250 // LED toggle rate in milliseconds
#define TIMER_PRESCALER 48 // Based on Timer CKCON settings
#define TIMER_TICKS_PER_MS SYSCLK/TIMER_PRESCALER/10000 // 48000000/48/10000= 1000000/10000 = 100
#define AUX1 TIMER_TICKS_PER_MS //
#define AUX2 -AUX1 //
#define TIMER0_RELOAD_HIGH AUX2 // Reload value

sbit SDA = P0^2; // connect to SDA pin (Data)
sbit SCL = P0^3; // connect to SCL pin (Clock)
bit rtc_check;
#define ACK 1
#define NO_ACK 0
#define SLAVE 0xD0
#define WRITE 0x00
#define READ 0x01
#define ERR_ACK 0x01


unsigned char RTC_ARR[7];
unsigned char HOURS;
unsigned char MINUTES;
unsigned char SECONDS;
unsigned char DATE1;
unsigned char YEAR;
unsigned char WEEK_NO;
unsigned char MONTH_NO;

void rtc_function(void);
void delay(void);
void ReadRTC(unsigned char * buff);
void WriteRTC(unsigned char * buff);
unsigned char ReadI2C(bit ACK_Bit);
void WriteI2C(unsigned char Data);
uint8 rtc_stage = 0;

void main (void)
{
PCA0MD &= ~0x40;
EA = 1;
PORT_init();
SYSCLK1_Init();
Timer0_Init();
while(1)
{
rtc_stage = 1;
rtc_function ();
}


}
void Timer0_ISR (void) interrupt 1
{
static int counter =0,timerout,rtc_count_check; // timer delay is 25 msec

if((counter++) == LED_TOGGLE_RATE)
{
// TL0 = TH0;
counter = 0; // if counter == LED_TOGGLE_RATE
TH0 = TIMER0_RELOAD_HIGH; // Init Timer0 High register
TL0 = TH0;
timerout++; // reset the counter increment timerout


if(rtc_check == 1)
{
rtc_count_check++;
if(rtc_count_check >1)
{
rtc_count_check = 0;
rtc_check = 0;
}
}

}


}
void rtc_function (void)
{


if(rtc_stage == 0) // if rtc_stage == 0 the stage to write new values to RTC
{
// ReadRTC(&RTC_ARR[0]);
RTC_ARR[0] = SECONDS & 0x7F; // enable oscillator (bit 7=0)
RTC_ARR[1] = MINUTES ; // minute = 59
RTC_ARR[2] = HOURS; // hour = 05 ,24-hour mode(bit 6=0)
RTC_ARR[3] = WEEK_NO; // Day = 1 or sunday
RTC_ARR[4] = DATE1; // Date = 30
RTC_ARR[5] = MONTH_NO ; // month = August
RTC_ARR[6] = YEAR ; // year = 05 or 2005
WriteRTC(&RTC_ARR[0]); // Set RTC
rtc_stage = 1; //after writing new values to RTC make rtc_stage = 1
}
// the format that rtc outputs the data seconds:minutes:hours:date:month:year(00- 99)

if(rtc_stage == 1) // if rtc_stage == 1 reading the parameters of RTC
{
ReadRTC(&RTC_ARR[0]); // call read function
WEEK_NO = RTC_ARR[3]; // read the week number from rtc (starting sunday as 0)
HOURS = RTC_ARR[2]; // read the hour from rtc clock.
MINUTES = RTC_ARR[1]; // read the minutes from rtc clock
SECONDS = RTC_ARR[0]; // read the seconds from rtc clock
DATE1 = RTC_ARR[4]; // read the date from rtc
MONTH_NO = RTC_ARR[5]; // read the month of the year.
YEAR = RTC_ARR[6]; // read the year from rtc bytes.

//rtc_stage = 3; // make rtc_stage == 3 for extracting seconds minutes hours from the bytes
}
}

//-------------------------------
// start I2C
//-------------------------------
void Start(void)
{
SCL = 1;
SDA = 1;
delay();delay();
SDA = 0;
delay();delay();
SCL = 0;
delay();delay();
}
//In I2c stop pulse SDA line has to go low to high transmission
//-------------------------------
// stop I2C
//-------------------------------
void Stop(void)
{
SDA = 0;
delay();delay();
SCL = 1;
delay();delay();
SDA = 1;
}
// for writing into I2c
//-------------------------------
// Write I2C
//-------------------------------
void WriteI2C(unsigned char Data)
{
uint8 in;

for (in=0;in<8;in++) // for writing one byte of data
{
SDA = (Data & 0x80) ? 1:0; // take the right most bit
SCL=1; // make SCl = 1 and SCl = 0
Data<<=1;
// shift the data to rigth one bit

SCL=0; //delay();
delay(); delay();
}



SCL = 1;
delay();delay();
SCL = 0;

}

//-------------------------------
// Read I2C
//-------------------------------
unsigned char ReadI2C(bit ACK_Bit)
{

unsigned char Data=0,in;

SDA = 1; // make SDA line = 1;
for (in = 0; in < 8; in++) // for reading 8 bits from I2c bus
{
SCL = 1; // make SCl = 1;
Data<<= 1; //shift the data right once
Data = (Data | SDA); // to get the data or data dta got from data line with SDA
// make SCl = 0
// call a delay
SCL = 0;
delay(); delay();
}

if (ACK_Bit == 1) // if ACK bit == 1 means vallid data has recived by the master
SDA = 0; // Send ACK // then make SDA =0
else
SDA = 1; // Send NO ACK // send SDA = 1;

delay(); delay();
SCL = 1; // make SCl = 1 after reading all 8bits from DATA line
delay(); delay();
SCL = 0; //make SCL = 0

return Data; // return the 1 byte of data
}
// for reading the all the bytes from RTC
//-------------------------------
// Read RTC (all real time)
//-------------------------------
void ReadRTC(unsigned char * buff)
{

Start(); // call start i2c function
WriteI2C(0xD0); // write the slave address to the I2c
WriteI2C(0x00);
// stop();

Start(); // send satrt pulse
WriteI2C(0xD1);
// WriteI2C(0x00); // then send read command on the bus
*(buff+0)=ReadI2C(ACK); // Second // read the seconds from RTC to the buffer
*(buff+1)=ReadI2C(ACK); // Minute // read the minutes from RTC to the buffer
*(buff+2)=ReadI2C(ACK); // hour // read the seconds from RTC to the buffer
*(buff+3)=ReadI2C(ACK); // Day // read the no of the day from the RTC
*(buff+4)=ReadI2C(ACK); // date // read the date from RTC to the buffer
*(buff+5)=ReadI2C(ACK); // month // read the month from RTC to the buffer
*(buff+6)=ReadI2C(NO_ACK); // year // read the year from RTC to the buffer
Stop();
}

//-------------------------------
// Write RTC// for writing the new values to RTC
//-------------------------------
void WriteRTC(unsigned char *buff)
{

Start(); // send start pulse
WriteI2C(0xD0); // send write command along with slave address
WriteI2C(0x00); // send next byte as 0x00
WriteI2C(*(buff+0)); // write seconds byte to RTC
WriteI2C(*(buff+1)); // write the minutes byte to RTC
WriteI2C(*(buff+2)); // write the Hour byte to the RTC
WriteI2C(*(buff+3));
WriteI2C(*(buff+4)); // write the new date byte to the RTC
WriteI2C(*(buff+5)); //write the month byte to the RTC
WriteI2C(*(buff+6)); //write the year byte to the RTC
Stop(); // send the stop pule

}


void delay(void)
{

rtc_check = 1;
while(1)
{
if(rtc_check == 0)
break;
}

}



List of 5 messages in thread
TopicAuthorDate
DS1307 interface issues with silabs 8051f340            01/01/70 00:00      
   Timing            01/01/70 00:00      
      other things checking            01/01/70 00:00      
         How to post legible source code            01/01/70 00:00      
         But did you check...?            01/01/70 00:00      

Back to Subject List