Im using I2C bitbang and Im facing an issue. I think I need a delay between SCL and SDA lines. Im not sure how much the delay needs to be. Can someone check my I2C code to see if everything checks out? I want to make sure its not a software mistake.
#include <at89c51ic2.h> #include <stdio.h> #define SDA P0_0 #define SCL P0_1 void I2CInit(){ SDA = 1; SCL = 1; } void I2CStart(){ SCL = 1; I2CDelay(); SDA = 0; I2CDelay(); SCL = 0; I2CDelay(); } void I2CRestart(){ SDA = 1; SCL = 1; SDA = 0; SCL = 0; } void I2CStop(){ SDA = 0; I2CDelay(); SCL = 1; I2CDelay(); SDA = 1; I2CDelay(); } void I2CAck(){ I2CDelay(); SDA = 0; I2CDelay(); SCL = 1; I2CDelay(); SCL = 0; I2CDelay(); SDA = 1; I2CDelay(); } void I2CNak(){ SDA = 1; SCL = 1; SCL = 0; SDA = 1; } void I2CSend(unsigned char Data){ unsigned char i; for (i = 0; i < 8; i++) { if ((Data & 0x80) == 0) SDA = 0; else SDA = 1; SCL = 1; I2CDelay(); SCL = 0; I2CDelay(); Data <<= 1; } SDA = 1; I2CDelay(); SCL = 1; I2CDelay(); if (SDA) SCL = 0; I2CDelay(); SDA = 1; SCL = 1; } char I2CRead(unsigned char lastone){ // last one == 1 for last byte; 0 for any other byte char i, Data=0; for (i = 0; i < 8; i++){ SCL = 1; I2CDelay(); if(SDA) Data |=1; if(i<7) Data<<=1; SCL = 0; I2CDelay(); } SDA = lastone; SCL = 1; I2CDelay(); SCL = 0; SDA = 1; SCL = 1; I2CDelay(); return Data; } void I2CSendAddr(unsigned char addr, unsigned char rd){ I2CStart(); I2CSend(addr+rd); } void I2CDelay(){ unsigned int i; for (i = 0; i < 4000; i++); return; }
Im not sure how much the delay needs to be.</i?
I2C Specification: www.nxp.com/.../UM10204.pdf
Done that before, but decades ago. What I have learned at that time, take an oscilloscope and inspect the signals; which is not too hard, as there are only two of them and the signal frequency is pretty low.
There were some topics I have never thought about (at that time) like signal rise time on an 8051 port pin.
I would recommend, look at the signals, compare it with the specification and then think again about the software.
And by the way, if you really think you need software delay loops, don't do that in C, do it in assembler. Why? The C compiler if free to optimize your code here to none and nothing; and that would be legal to do so.
www.8052.com/.../162556
thnx for the advice