We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
hi I want to interface a SERIAL REAL-TIME CLOCK (M41T0). The problem comes reading from the build-in registers, that's what I think. The code looks like this. The master device in this case is P89C51RC2BA chip. I think I have to work on BCD values as well thanks.
// Routine: i2c_start void i2c_start(void) { SDA = HIGH; // Set data line high SCL = HIGH; // Set clock line high SDA = LOW; // Set data line low (START SIGNAL) SCL = LOW; // Set clock line low } // Routine: i2c_stop void i2c_stop (void) { unsigned char input_var;
SCL = LOW; // Set clock line low SDA = LOW; // Set data line low SCL = HIGH; // Set clock line high SDA = HIGH; // Set data line high (STOP SIGNAL) input_var = SDA; // Put port pin into HiZ }
//------------------------------------------------------------------------------ // Routine: i2c_write //------------------------------------------------------------------------------ void i2c_write (unsigned char output_data) { unsigned char index;
for(index = 0; index < 8; index++) // Send 8 bits to the I2C Bus { // Output the data bit to the I2C Bus SDA = ((output_data & 0x80) ? 1 : 0); output_data <<= 1; // Shift the byte by one bit SCL = HIGH; // Clock the data into the I2C Bus SCL = LOW; }
index = SDA; // Put data pin into read mode SCL = HIGH; // Clock the ACK from the I2C Bus SCL = LOW; } //------------------------------------------------------------------------------ // Routine: i2c_read //------------------------------------------------------------------------------
unsigned char i2c_read (void) { unsigned char index, input_data;
index = SDA; // Put data pin into read mode
input_data = 0x00; for(index = 0; index < 8; index++) // Send 8 bits to the I2C Bus { input_data <<= 1; // Shift the byte by one bit SCL = HIGH; // Clock the data into the I2C Bus input_data |= SDA; // Input the data from the I2C Bus SCL = LOW; }
return input_data; }
void main() { //After Initializing CPU, set default values to the //registers ......
i2c_start(); i2c_write (0xD0); //start condition followed by the //correct slave address(D0h). ////////////////////////////////////////// //The 8 bytes contained in the device can then be ///accessed sequentially in the following order: //1. Seconds Register //2. Minutes Register //3. Century/Hours Register //4. Day Register //5. Date Register //6. Month Register //7. Years Register //8. Control Register ////////////////////////////////////////// i2c_write(0x00); // Write 00 to seconds word i2c_write(0x59); // Write 59 to minutes word i2c_write(0x23); // Write 23 to century/hours word i2c_write(0x05); // Write 05 to day word i2c_write(0x10); // Write 10 to date word i2c_write(0x11); // Write 11 to month word i2c_write(0x05); // Write 05 to year word i2c_write(0x00); // Write 00 to control word i2c_stop(); // Issue stop signal i2c_start(); // Issue start signal i2c_write(0xD0); // Address M41T0 To Write i2c_write(0x00); // Start address 0 (Seconds) i2c_start(); // Issue start signal i2c_write(0xD1); // Address M41T0 To Read cksec = i2c_read(); // Read Seconds from RTC ckmin = i2c_read(); // Read Minutes from RTC ckhrs = i2c_read(); // Read Hours from RTC ckday = i2c_read(); // Read Days from RTC ckdat = i2c_read(); // Read Seconds from RTC ckmth = i2c_read(); // Read Minutes from RTC ckyer = i2c_read(); // Read Hours from RTC ckctl = i2c_read(); // Read Days from RTC i2c_stop(); // Issue stop signal arr[0] = (char)cksec;//type cast BCD value to char arr[1] = (char)ckmin; arr[2] = (char)ckhrs; arr[3] = '\0'; Printf(0xB4,0x10,arr); //prints value on LCD