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
Hello "pagfit ranjesh". You are really too funny to be a real person.