I2C bus timing simulation (I)-deep understanding of bus protocols
# Include <reg52.h> # define uchar unsigned charsbit SDA = P2 ^ 0; sbit SCL = P2 ^ 1; // use two I/O Ports of the microcontroller to simulate the I2C interface uchar; **************************************** *********************************** void delay () // simple latency function {;;} **************************************** *********************************** void start () // when the start signal is at the high level, a descent edge of SDA indicates the start signal {SDA = 1; // release SDA bus delay (); SCL = 1; delay (); SDA = 0; delay ();}************************** **************************************** * ******** Void stop () // during the high-level period, when the SDA is stopped, a rising edge indicates the stop signal {SDA = 0; delay (); SCL = 1; delay (); SDA = 1; delay ();} **************************************** ********************************** void respons () // The SDA is pulled from the device to a low level during the high level of the response SCL, indicating the response {uchar I; SCL = 1; delay (); While (SDA = 1) & (I <250) I ++; SCL = 0; delay ();} **************************************** *********************************** voi D Init () // initialize the bus before pulling the bus up and releasing the bus to send the startup signal. That is, the start signal is sent only when the bus is idle. {SDA = 1; delay (); SCL = 1; delay ();} **************************************** ********************************** void write_byte (uchar date) // write a byte {uchar I, temp; temp = date; for (I = 0; I <8; I ++) {temp = temp <1; SCL = 0; // lower the check box because changes are allowed only when the clock signal is low; at this time, a rising edge delay (); SDA = Cy; delay (); SCL = 1 is formed along with the CL = 1 of the previous cycle. // increase the height of the SCL, in this case, the data on the SDA is stable delay ();} SCL = 0; // The data is pulled down to make preparations for the next data transmission. Delay (); SDA = 1; // release the SDA bus, which is then controlled by the slave device. For example, after the data is received from the slave device, the SDA is lowered as the response signal delay ();} **************************************** *********************************** uchar read_byte () // read one byte {uchar I, K; SCL = 0; delay (); SDA = 1; delay (); for (I = 0; I <8; I ++) {SCL = 1; // when the rising edge is reached, the IIC device places the data on the SDA line, and the data is stable during the high level. You can receive the delay (); k = (k <1) | SDA; SCL = 0; // lower the SCL so that the sender can put the data on SDA delay ();} return K ;} **************************************** * ********************************** void write_add (uchar address, uchar date) // write a byte {start () at any address; // start write_byte (0xa0); // send the respons () from the device address (); // wait for the response from the device to write_byte (Address); // send out the in-chip address respons (); // wait for the response from the device to write_byte (date ); // send data respons (); // wait for the response from the device to stop (); // stop }************************************ ************************************* uchar read_add (uchar address) // read a self {uchar date; Start (); // start write_byte (0xa0); // send the write operation from the device address respons (); // wait for the response from the device write_byte (Address); // Send the address respons () in the chip; // wait for the response from the device to start (); // start write_byte (0xa1); // send the read operation respons () from the device address; // wait for the response from the device date = read_byte (); // get data stop (); // stop return date; // return data}