I2C bit banding and interfacing analog ADC - Page 1
Forum section: electronics / beginners

author: Vindhyachal.takniki
author_rank: Frequent Contributor
timestamp: June 13, 2020, 07:30:04 am
content: 1. I need to interface NAu7802 datasheet attached.2. MCU is operating at 16Mhz, writing I2C code by bit banding.3. took reference from Microchip AN1488 note for bit banding and wrote below code.4. When i tested on hardware, it runs but nau7802_rd_byte(0x1f) don not return 0x0f, which is id .5. What is wrong in this code6. One thing I dont understand in nau7802_wr_byte() function is sending ack_poll(NAU7802_WR); , what does it do?Why sending address again ?7. is there anything wrong in code below?Code:#define NAU7802_REG_PU_CTRL0x00#define NAU7802_REG_CTRL10x01#define NAU7802_BIT_PU_CTRL_PUA0x04#define NAU7802_BIT_PU_CTRL_PUD0x02#define NAU7802_BIT_PU_CTRL_RR0x01#define NAU7802_BIT_VLDO_3V30x20void nau7802_init(void){uint8_t temp;scl_output();scl_high();/* Send Reset command into NAU7802 */nau7802_wr_byte(NAU7802_REG_PU_CTRL , NAU7802_BIT_PU_CTRL_RR);//waitfor 2000usdelay_us(2000)/* Enable PUD to power on the chip digital logic */nau7802_wr_byte(NAU7802_REG_PU_CTRL , NAU7802_BIT_PU_CTRL_PUD);/* Wait power up ready */do{temp = nau7802_rd_byte(NAU7802_REG_PU_CTRL);}while( 0U == (temp & (1U << 3U) ) );temp = nau7802_rd_byte(0x1f);if(temp == 0x0f){//ok;}while(1){}}#define ACK 0x00#define NACK 0x80#define NAU7802_WR 0x54 // WRITE instruction#define NAU7802_RD 0x55 // READ instructionvoid nau7802_wr_byte(uint8_t addr , uint8_t data){i2c_start(); // generate Start COnditioni2c_wr(NAU7802_WR); // send WRITE commandi2c_wr( addr ); // address MSBi2c_wr(data); // send datai2c_stop(); // initiate Stop Conditionack_poll(NAU7802_WR); // ACK polling}uint8_t nau7802_rd_byte(uint8_t addr){uint8_t data;i2c_start(); // generate Start COnditioni2c_wr(NAU7802_WR); // send WRITE commandi2c_wr( addr ); // address MSBi2c_start(); // generate Start COnditioni2c_wr(NAU7802_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: garethw
author_rank: Regular Contributor
timestamp: June 14, 2020, 06:03:47 am
content: AN1488 describes bit banging for a Microchip 24XXXX series EEPROM device. These devices support 'ACKNOWLEDGE POLLING' as a feature. This is described in the app note.Essentially, after the data byte has been sent to the EEPROM it takes a certain amount of time for the write to be performed. By resending a 'write' command and checking for the ACK response we can determine if the EEPROM has finished writing. If there is no ACK then the EEPROM is busy, if it acknowledges it means it is finished and the next byte can be sent.Your NAU7802 ADC device does not support this feature so you would need to modify your bit-banging routine. The NAU7802 uses a 'Data Ready' output pin to confirm the ADC conversion is complete, or you can poll register 0x00 bit 5, to check if the conversion is complete.Hope this helps

author: Siwastaja
author_rank: Super Contributor
timestamp: June 14, 2020, 02:07:39 pm
content: To make googling easier, do note that bit banging and bit banding both exist, but are two completely different things. Your code describes bit banging, but the subject field says bit banding.