[cpp] view plain copy
print ?
Keywords:I2C
Reference address:I2C Bus Timing Simulation (Part 2) - Deepen your understanding of the bus protocol
- /****************************************************** *******************
- This program is the underlying C subroutine of the I2C operating platform (master mode software platform), such as sending data
- And receive data, send the response bit, and provide several operating functions directly facing the device, it is very convenient
- Connect with user programs and expand...
- Note: This function uses software delay to generate SCL pulses.
- Some modifications....(This example is 1us machine cycle, that is, the crystal frequency must be less than 12MHZ)
- *************************************************** ******************/
- #include
/*Include header file*/ - #include
- #define uchar unsigned char /*macro definition*/
- #define uint unsigned int
- #define _Nop() _nop_() /*define null instruction*/
- /* Constant, variable definition area */
- /*Port bit definition*/
- sbit SDA=P1^3; /*Simulate I2C data transmission bit*/
- sbit SCL=P1^2; /*Simulated I2C clock control bit*/
- /*Status flag*/
- bit ack; /*Response flag*/
- /****************************************************** ******************
- Start bus function
- Function prototype: void Start_I2c();
- Function: Start the I2C bus, that is, send the I2C start condition.
- *************************************************** ******************/
- void Start_I2c()
- {
- SDA=1; /*Send the data signal of the start condition*/
- _Nop();
- SCL=1;
- _Nop(); /*Start condition establishment time is greater than 4.7us, delay*/
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=0; /*Send start signal*/
- _Nop(); /* Start condition lock time is greater than 4μs*/
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SCL=0; /*Clamp the I2C bus and prepare to send or receive data */
- _Nop();
- _Nop();
- }
- /****************************************************** ******************
- End bus function
- Function prototype: void Stop_I2c();
- Function: End the I2C bus, that is, send the I2C end condition.
- *************************************************** ******************/
- void Stop_I2c()
- {
- SDA=0; /*Send data signal of end condition*/
- _Nop(); /*Send the clock signal of the end condition*/
- SCL=1; /*End condition establishment time is greater than 4μs*/
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- SDA=1; /*Send I2C bus end signal*/
- _Nop();
- _Nop();
- _Nop();
- _Nop();
- }
- /****************************************************** ******************
- Byte data transfer function
- Function prototype: void SendByte(uchar c);
- Function: Send data c, which can be an address or data, wait for a response after sending, and
- This status bit operates. (No response or non-response makes ack=0 false)
- If data is sent normally, ack=1; ack=0 means the controlled device has no response or is damaged.
- *************************************************** ******************/
- void SendByte(uchar c)
- {
- uchar BitCnt;
- for(BitCnt=0;BitCnt<8;BitCnt++) /*The length of the data to be transmitted is 8 bits*/
- {
- if ((c<
- ; /*Judge the sending position*/
- else SDA=0;
- _Nop();
- SCL=1; /*Set the clock line high to notify the controlled device to start receiving data bits*/
- _Nop();
- _Nop(); /*Ensure that the clock high level period is greater than 4μs*/
- _Nop();
- _Nop();
- _Nop();
- SCL=0;
- }
- _Nop();
- _Nop();
- SDA=1; /*Release the data line after sending 8 bits, and prepare to receive the response bit*/
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop();
- _Nop();
- if(SDA==1)ack=0;
- else ack=1; /*Judge whether the response signal is received*/
- SCL=0;
- _Nop();
- _Nop();
- }
- /****************************************************** ******************
- Byte data transfer function
- Function prototype: uchar RcvByte();
- Function: Used to receive data from the device and determine bus errors (no response signal is sent).
- Please use the reply function after sending.
- *************************************************** ******************/
- uchar RcvByte()
- {
- uchar retc;
- uchar BitCnt;
- retc=0;
- SDA=1; /*Set the data line to input mode*/
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- _Nop();
- SCL=0; /*Set the clock line low and prepare to receive data bits*/
- _Nop();
- _Nop(); /*Clock low level period is greater than 4.7μs*/
- _Nop();
- _Nop();
- _Nop();
- SCL=1; /*Set the clock line high to make the data on the data line valid*/
- _Nop();
- _Nop();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; /*Read data bit, and put the received data bit into retc */
- _Nop();
- _Nop();
- }
- SCL=0;
- _Nop();
- _Nop();
- return(retc);
- }
- /****************************************************** *******************
- Response subfunction
- Prototype: void Ack_I2c(bit a);
- Function: The master controller sends a response signal (which can be a response or non-response signal)
- *************************************************** ******************/
- void Ack_I2c(bit a)
- {
- if(a==0)SDA=0; /*Send a response or non-response signal here */
- else SDA=1;
- _Nop();
- _Nop();
- _Nop();
- SCL=1;
- _Nop();
- _Nop(); /*Clock low level period is greater than 4μs*/
- _Nop();
- _Nop();
- _Nop();
- SCL=0; /*Clear the clock line and clamp the I2C bus to continue receiving*/
- _Nop();
- _Nop();
- }
- /****************************************************** ******************
- Send byte data function to a device without subaddress
- Function prototype: bit ISendByte(uchar sla,ucahr c);
- Function: The whole process from starting the bus to sending address, data, and ending the bus, slave device address sla.
- If 1 is returned, the operation is successful, otherwise the operation is wrong.
- Note: The bus must be terminated before use.
- *************************************************** ******************/
- bit ISendByte(uchar sla,uchar c)
- {
- Start_I2c(); /*Start the bus*/
- SendByte(sla); /*Send device address*/
- if(ack==0)return(0);
- SendByte(c); /*send data*/
- if(ack==0)return(0);
- Stop_I2c(); /*End the bus*/
- return(1);
- }
- /****************************************************** ******************
- Send multi-byte data function to a sub-address device
- Function prototype: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
- Function: From starting the bus to sending address, sub-address, data, and ending the bus, the slave device
- Address sla, subaddress suba, the content to be sent is the content pointed to by s, and no bytes are sent.
- If 1 is returned, the operation is successful, otherwise the operation is wrong.
- Note: The bus must be terminated before use.
- *************************************************** ******************/
- bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
- {
- uchar i;
- Start_I2c(); /*Start the bus*/
- SendByte(sla); /*Send device address*/
- if(ack==0)return(0);
- SendByte(suba); /*Send device subaddress*/
- if(ack==0)return(0);
- for(i=0;i
- {
- SendByte(*s); /*send data*/
- if(ack==0)return(0);
- s++;
- }
- Stop_I2c(); /*End the bus*/
- return(1);
- }
- /****************************************************** ******************
- Read byte data function to a device without subaddress
- Function prototype: bit IRcvByte(uchar sla,ucahr *c);
- Function: From starting the bus to sending the address, reading the data, and ending the bus, the whole process is from the device ground
- Address sla, return value is in c.
- If 1 is returned, the operation is successful, otherwise the operation is wrong.
- Note: The bus must be terminated before use.
- *************************************************** ******************/
- bit IRcvByte(uchar sla,uchar *c)
- {
- Start_I2c(); /*Start the bus*/
- SendByte(sla+1); /*Send device address*/
- if(ack==0)return(0);
- *c=RcvByte(); /*Read data*/
- Ack_I2c(1); /*Send not-acknowledge bit*/
- Stop_I2c(); /*End the bus*/
- return(1);
- }
- /****************************************************** ******************
- Function to read multi-byte data from a sub-address device
- Function prototype: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
- Function: From starting the bus to sending address, sub-address, reading data, and ending the bus, the slave device
- Address sla, subaddress suba, the read content is placed in the storage area pointed to by s, and no bytes are read.
- If 1 is returned, the operation is successful, otherwise the operation is wrong.
- Note: The bus must be terminated before use.
- *************************************************** ******************/
- bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
- {
- uchar i;
- Start_I2c(); /*Start the bus*/
- SendByte(sla); /*Send device address*/
- if(ack==0)return(0);
- SendByte(suba); /*Send device subaddress*/
- if(ack==0)return(0);
- Start_I2c();
- SendByte(sla+1);
- if(ack==0)return(0);
- for(i=0;i
- {
- *s=RcvByte(); /*Send data*/
- Ack_I2c(0); /*send the answer bit*/
- s++;
- }
- *s=RcvByte();
- Ack_I2c(1); /*Send no response bit*/
- Stop_I2c(); /*End the bus*/
- return(1);
- }
- /* Done */
Previous article:I2C bus learning ends, SPI bus learning begins
Next article:I2C bus serial input and output structure
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
MoreDaily News
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
Guess you like
- How does FPGA adjust the volume of the buzzer?
- [Repair] Repaired a data cable
- How long will the battle between community owners and communication base stations last?
- Please tell me the winding method and other parameters of the EE8 transformer that can increase 0.7V to 7V
- Conversion between CC2640R2F projects
- Pengfeng Technology RVBoards-Nezha (RISC-V SBC) Allwinner Development Board Introduction Part 3
- [Repost] A few simple steps to help you understand the MCU timing diagram
- Cadence Certus Closure Solution is a new generation chip-level convergence solution. Welcome to learn more!
- What is the progress of domestic NPU chips?
- How is JTAG used for chip testing?