1. I am using AT89C55WD(40 pin DIP), with 12Mhz crystal.
Have to interface BL24C04 with it.
2. System is +5V powered & I have made bit banging code in C for it.
I have kept 50kbps speed. Took refereence from here while making code ( http://saeedsolutions.blogspot.in/2012/10/pic16f84a-i2c-bit-banging-code-proteus.html )
3. I have simualted code in proteus & seems to be working as values shown in its I2c debugger.
4. One issue I think may be its very small delay. At 50kbps , 1 bit delay is 20us, half bit delay is 10us & quarter bit delay is 5us. In codeI have used nop statements for 10us & 5us.
5. In link above, blogger has used quarter(5us)/half(10us) but delay at many places. I dont know why quarter(5us) bit delay is used. Below is code. Is it ok?
Have to interface BL24C04 with it.
2. System is +5V powered & I have made bit banging code in C for it.
I have kept 50kbps speed. Took refereence from here while making code ( http://saeedsolutions.blogspot.in/2012/10/pic16f84a-i2c-bit-banging-code-proteus.html )
3. I have simualted code in proteus & seems to be working as values shown in its I2c debugger.
4. One issue I think may be its very small delay. At 50kbps , 1 bit delay is 20us, half bit delay is 10us & quarter bit delay is 5us. In codeI have used nop statements for 10us & 5us.
5. In link above, blogger has used quarter(5us)/half(10us) but delay at many places. I dont know why quarter(5us) bit delay is used. Below is code. Is it ok?
C:
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_();
void all_tasks_manager(void)
{
uint8_t temp;
i2c_init();
/* write to eeprom */
i2c_start();
while( 1U == i2c_write_byte(0xa0U) )
{
i2c_start();
}
/* address */
i2c_write_byte(0x00U);
/* value */
i2c_write_byte(0x05U);
/* stop */
i2c_stop();
wait_delay_us(50000);
/* write to eeprom */
i2c_start();
while( 1U == i2c_write_byte(0xa0U) )
{
i2c_start();
}
/* address */
i2c_write_byte(0x00U);
i2c_restart();
i2c_write_byte(0xa1U);
temp = i2c_read_byte();
i2c_send_nack();
i2c_stop();
while(1);
} /* function ends here */
void i2c_init(void)
{
sda = 1U;
scl = 1U;
}
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();
}
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();
}
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();
}
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();
}
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();
}
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;
}
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;
}
Last edited by a moderator: