??? 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; } } |
Topic | Author | Date |
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 |