@Vindhyachal Takniki It depends on what your notion of correct is. Yours will be different than mine. If you're satisfied with it, then what difference does it make what I think. You don't need my seal of approval to go forth and be prosperous.
/* AT89C55WD, 12Mhz crystal, 1us inst time */
sbit sda = P1^7;
sbit scl = P1^6;
#define i2c_speed_kbps 50
#define half_bit_delay_us 10 /* ( (1*1000000) / (i2c_speed_kbps*1000) )/ 2 */
#define delay_10us() _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
#define delay_5us() _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
#include "regx55.h"
#include "i2c.h"
static uint8_t eeprom_write_mutiple_bytes(uint8_t address , uint8_t byte[] , uint8_t no_bytes)
{
uint8_t cnt;
uint8_t cnt2;
uint8_t err = 0U;
cnt = 10U;
/* write to eeprom */
i2c_start();
while( (1U == i2c_write_byte(0xa0U)) && (--cnt) )
{
/* stop */
i2c_stop();
/* delay 100ms */
for(cnt2 = 0U ; cnt2 < 20U ; cnt2++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
i2c_start();
}
if(0U == cnt)
{
err = 1U;
}
/* if no error */
if(0U == err)
{
/* address */
i2c_write_byte(address);
for(cnt = 0U ; cnt < no_bytes ; cnt++)
{
(void)i2c_write_byte(byte[cnt]);
}
/* stop */
i2c_stop();
}
/* delay 100ms */
for(cnt = 0U ; cnt < 15U ; cnt++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
return err;
}
static uint8_t eeprom_read_mutiple_bytes(uint8_t address , uint8_t byte[] , uint8_t no_bytes)
{
uint8_t cnt;
uint8_t cnt2;
uint8_t err = 0U;
cnt = 10U;
/* write to eeprom */
i2c_start();
while( (1U == i2c_write_byte(0xa0U)) && (--cnt) )
{
/* stop */
i2c_stop();
/* delay 100ms */
for(cnt2 = 0U ; cnt2 < 20U ; cnt2++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
i2c_start();
}
if(0U == cnt)
{
err = 1U;
}
/* if no error */
if(0U == err)
{
/* address */
i2c_write_byte(address);
/* restart */
i2c_restart();
i2c_write_byte(0xa1U);
/* address */
byte[0] = i2c_read_byte();
for(cnt = 1U ; cnt < no_bytes ; cnt++)
{
i2c_send_ack();
byte[cnt] = i2c_read_byte();
}
/* nack */
i2c_send_nack();
/* stop */
i2c_stop();
}
/* delay 100ms */
for(cnt = 0U ; cnt < 15U ; cnt++)
{
wait_delay_us_complete(DELAY_10000_US_TH , DELAY_10000_US_TL);
}
return err;
}
static void i2c_start(void)
{
scl = 1U;
sda = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
sda = 0U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
static void i2c_restart(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
}
static void i2c_stop(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
}
static void i2c_send_ack(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
static void i2c_send_nack(void)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
sda = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
static uint8_t i2c_write_byte(uint8_t byte)
{
uint8_t cnt;
for(cnt = 0U ; cnt < 8U ; cnt++)
{
scl = 0U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
if( (byte << cnt) & 0x80U )
{
sda = 1U;
}
else
{
sda = 0U;
}
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
}
/* get ack from slave */
scl = 0U;
sda = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
scl = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
return sda;
}
static uint8_t i2c_read_byte(void)
{
uint8_t cnt;
uint8_t rxdata = 0U;
uint8_t temp;
for(cnt = 0U ; cnt < 8U ; cnt++)
{
scl = 0U;
sda = 1U;
/* half bit delay for 50kbps which is 10us for 12Mhz it is 10 nops */
delay_10us();
scl = 1U;
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
temp = sda;
rxdata = rxdata | (temp << (7U - cnt));
/* half bit delay/2 for 50kbps which is 5us for 12Mhz it is 5 nops */
delay_5us();
}
return rxdata;
}
Thread starter | Similar threads | Forum | Replies | Date |
---|---|---|---|---|
![]() |
Bit-banging SPI .. #2 | Microcontrollers | 1 | |
V | DS1307 Read error I2C by bit banging. | Programming & Languages | 2 | |
V | I2C bit banging and interfacing analog ADC | Microcontrollers | 5 | |
C | Bit-banging SPI | Microcontrollers | 26 | |
![]() |
Serial data out, bit banging and threading in c# | Programming & Languages | 2 |