DS1307 Read error I2C by bit banging. - Page 1
Forum section: electronics / beginners

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: July 02, 2020, 07:50:58 am
content: 1. I have written below code, have to just read the times from RTC. So I read all registers starting from 0x00.I always zero from RTC DS1307.2. Time is set by Arduino board separately and I can read back by arduino correctly. So no error seems in RTC board.But now I have to implement in another MCU with bit banging only.3. Have checked all pull up values ok and pin scl and scd getting high and low for output_low or output_high.Code:#define ACK 0x00#define NACK 0x80#define RTC_WR 0xD0 // WRITE instruction#define RTC_RD 0xD1 // READ instructionvoid rtc_init(void){scl_high();sda_high();sda_output();scl_output();}void read_rtc_registers(uint8_t time_arr[]){uint8_t temp;uint8_t val1,val2,val3;i2c_start(); // generate Start COnditioni2c_wr(NAU7802_WR); // send WRITE commandi2c_wr( 0x00U ); // address from 0x00 i.e seconfsi2c_start(); // generate Start COnditioni2c_wr(RTC_RD); // send READ commandtemp=i2c_rd(ACK); // read data from buffertemp=i2c_rd(ACK); // read data from buffertemp=i2c_rd(ACK); // read data from buffertemp=i2c_rd(ACK); // read data from buffertemp=i2c_rd(ACK); // read data from buffertemp=i2c_rd(ACK); // read data from buffertemp=i2c_rd(NACK); // read data from bufferi2c_stop(); // send Stop Condition}void rtc_wr_byte(uint8_t addr , uint8_t data){i2c_start(); // generate Start COnditioni2c_wr(RTC_WR); // send WRITE commandi2c_wr( addr ); // address MSBi2c_wr(data); // send datai2c_stop(); // initiate Stop Conditionack_poll(RTC_WR); // ACK polling}uint8_t rtc_rd_byte(uint8_t addr){uint8_t data;i2c_start(); // generate Start COnditioni2c_wr(RTC_WR); // send WRITE commandi2c_wr( addr ); // address MSBi2c_start(); // generate Start COnditioni2c_wr(RTC_RD); // send READ commanddata=i2c_rd(NACK); // read data from bufferi2c_stop(); // send Stop Conditionreturn data; // return data from I2C buffer}void i2c_start(void){sda_input();scl_high();sda_output();sda_low();__no_operation();__no_operation();scl_low();}void i2c_stop(void){scl_low();sda_output();sda_low();__no_operation();__no_operation();__no_operation();scl_high();sda_input();__no_operation();__no_operation();__no_operation();scl_low();}void bit_out(uint8_t data){scl_low();sda_output();if(data >> 7U){sda_high();}else{sda_low();}__no_operation();__no_operation();scl_high();__no_operation();__no_operation();__no_operation();scl_low();}void bit_in(uint8_t *data){scl_low();sda_input();scl_high();__no_operation();__no_operation();__no_operation();if(sda_read()){*data |= 0x01;}scl_low();}uint8_t i2c_wr(uint8_t data){uint8_t i; // loop counteruint8_t ack; // ACK bitack = 0U;for(i = 0U ; i < 8U ; i++) // loop through each bit{bit_out(data); // output bitdata = data << 1; // shift left for next bit}bit_in(&ack); // input ACK bitreturn ack;}uint8_t i2c_rd(uint8_t ack){uint8_t i; // loop counteruint8_t ret = 0U; // return valuefor(i = 0U ; i < 8U ; i++) // loop through each bit{ret = ret << 1; // shift left for next bitbit_in(&ret); // input bit}bit_out(ack); // output ACK/NAK bitreturn ret;}void ack_poll(uint8_t control){uint8_t result = 1U;while(result){i2c_start(); // generate Restart conditionresult = i2c_wr(control); // send control byte (WRITE command)}i2c_stop(); // generate Stop condition}

author: 0-8-15 User
author_rank: Regular Contributor
timestamp: July 02, 2020, 09:05:39 am
content: I would give this library a try:http://www.rinkydinkelectronics.com/library.php?id=34,I'm using the DS3231 variant of it and it works great via 'software serial'.

author: greenpossum
author_rank: Frequent Contributor
timestamp: July 02, 2020, 09:20:22 am
content: Make sure you don't bang too fast, i2C protocol has specified timing for speed tiers. If the times due to the MCU instructions are too short, the device may not respond in time.

author: garethw
author_rank: Regular Contributor
timestamp: July 02, 2020, 08:31:32 pm
content: In the 'read_rtc_registers(uint8_t time_arr[])' functionCode:i2c_wr(NAU7802_WR); // send WRITE commandShould this line read ...Code:i2c_wr(RTC_WR); // send WRITE command...like this?