MCU + I2C communication response signal is abnormal
[Copy link]
Use Proteus to simulate the I2C communication between 89C52 and 24C02, and read the data written into 24C02 to light up the LED controlled by P1; it is found that the LED light in Proteus cannot light up normally according to the written data, but it is normal when downloaded to the development board. The waveform of the response signal SDA is shown in the figure; the simulation diagram is shown in the figure.
The main questions are as follows:
① According to the response waveform shown in the figure, SDA changes (pulls high) during the falling edge of SCL. Is this normal? According to the I2C response timing diagram, SDA should change after a period of time after SCL is pulled low. Looking at the waveform, it should be that 24c02 generates a normal response, but when SCL is pulled low, SDA is released early.
② Debug the code. After commenting out the delay while((sda==1)&&(i<250))i++; in the response signal below, the simulation can light up the LED normally (but the response waveform remains the same). Why does this code cause an exception?
Thanks for your advice!
void respons() //Response
{
uchar i;
scl=1;
delay();
// while((sda==1)&&(i<250))i++; // It works normally after commenting out this line of code.
scl=0;
delay();
}
Complete IIC code:
***************************************************
#include<reg52.h>
#define uchar unsigned char
sda=P2^0;
sbit scl=P2^1;
uchar a;
void delay()
{ ;; }
void start() //Start signal
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
s cl=0;
delay();
}
void stop() //Stop
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
// scl=0;
// delay();
}
void responses() //Response
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
//void Send_ responses() //Send a response signal, that is, send 0 to the slave. If there is no response, send 1. Just don't add this program to the main program
.
//{
// sda=0;
// delay();
// scl=1;
// delay();
// scl=0;
// delay();
//}
void init()
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
delay();
sda=CY;
delay();
scl=1;
delay();
scl=0;
}
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void delay1(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
void write_add(uchar address,uchar date)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_add(uchar address)
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
delay1(100);
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
void main()
{
init();
write_add(23,0xaa);
delay1(100);
P1=read_add(23);
while(1);
}
|