/*********File name: i2c_ee.h**********/
/* Define to prevent recursive inclusion ------------------------------------ */
#ifndef __I2C_EE_H
#define __I2C_EE_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/* Exported macro ------------------------------------------------------------*/
#define ADDR_24CXX 0xA0
#define SCLH GPIOB->BSRR = GPIO_Pin_6
#define SCLL GPIOB->BRR = GPIO_Pin_6
#define SDAH GPIOB->BSRR = GPIO_Pin_7
#define SDAL GPIOB->BRR = GPIO_Pin_7
#define SCLread GPIOB->IDR & GPIO_Pin_6
#define SDAread GPIOB->IDR & GPIO_Pin_7
/* Exported functions ------------------------------------------------------- */
void I2C_EE_Init(void);
uint8_t I2C_EE_BufferWrite(uint8_t *psrc_data,uint8_t adr,uint8_t nbyte);
uint8_t I2C_EE_BufferRead(uint8_t *pdin_data,uint8_t adr,uint8_t nbyte);
#endif /* __I2C_EE_H */
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/*********File name: i2c_ee.c**********/
#include "i2c_ee.h"
enum ENUM_TWI_REPLY
{
TWI_NACK=0
,TWI_ACK=1
};
enum ENUM_TWI_BUS_STATE
{
TWI_READY=0
,TWI_BUS_BUSY=1
,TWI_BUS_ERROR=2
};
void I2C_EE_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// Configure I2C1 pins: SCL and SDA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void TWI_delay(void)
{
uint8_t i=10; //i=10 delay 1.5us//The speed can be optimized here. After testing, it can still be written to the lowest 5
while(i--);
}
/**************************************************************************
Delay
ms: delay in milliseconds
CYCLECOUNTER / 72000000
***************************************************************************/
void DelayMs(uint16_t ms)
{
uint16_t iq0;
uint16_t iq1;
for(iq0 = ms; iq0 > 0; iq0--)
{
for(iq1 = 11998; iq1 > 0; iq1--); // ( (6*iq1+9)*iq0+15 ) / 72000000
}
}
uint8_t TWI_Start(void)
{
SDAH;
SCLH;
TWI_delay();
if(!SDAread)return TWI_BUS_BUSY; //If the SDA line is low, the bus is busy, exit
SDAL;
TWI_delay();
if(SDAread) return TWI_BUS_ERROR; //If the SDA line is high, the bus is wrong and exit
SCLL;
TWI_delay();
return TWI_READY;
}
/*void TWI_Stop(void)
{
SCLL;
TWI_delay();
SDAL;
TWI_delay();
SCLH;
TWI_delay();
SDAH;
TWI_delay();
}*/
void TWI_Stop(void)
{
SDAL;
SCLL;
TWI_delay();
SCLH;
TWI_delay();
SDAH;
TWI_delay();
}
void TWI_Ack(void)
{
SCLL;
TWI_delay();
SDAL;
TWI_delay();
SCLH;
TWI_delay();
SCLL;
TWI_delay();
}
void TWI_NoAck(void)
{
SCLL;
TWI_delay();
SDAH;
TWI_delay();
SCLH;
TWI_delay();
SCLL;
TWI_delay();
}
uint8_t TWI_WaitAck(void) //Return: =1 for ACK, =0 for no ACK
{
SCLL;
TWI_delay();
SDAH;
TWI_delay();
SCLH;
TWI_delay();
if(SDAread)
{
SCLL;
return 0;
}
SCLL;
return 1;
}
void TWI_SendByte(uint8_t SendByte) //Data from high to low //
{
uint8_t i=8;
while(i--)
{
SCLL;
TWI_delay();
if(SendByte&0x80)
SDAH;
else
SDAL;
SendByte<<=1;
TWI_delay();
SCLH;
TWI_delay();
}
SCLL;
}
uint8_t TWI_ReceiveByte(void) //Data from high to low //
{
uint8_t i=8;
uint8_t ReceiveByte=0;
SDAH;
while(i--)
{
ReceiveByte <<= 1;
SCLL;
TWI_delay();
SCLH;
TWI_delay();
if(SDAread)
{
ReceiveByte |= 0x01;
}
}
SCLL;
return ReceiveByte;
}
//Return: 3 write successful; 0 write device address error, 1 bus busy, 2 error
//Write 1 byte of data SendByte: data to be written WriteAddress: address to be written
uint8_t TWI_WriteByte(uint8_t SendByte, uint8_t WriteAddress)
{
uint8_t i;
uint16_t j;
i = TWI_Start();
if(i)
return i;
TWI_SendByte( ADDR_24CXX & 0xFE); //Write device address Write: the lowest bit of the address is 0, read: the lowest bit of the address is 1
if(!TWI_WaitAck())
{
TWI_Stop();
return 0;
}
TWI_SendByte(WriteAddress); //Set the starting address
TWI_WaitAck();
TWI_SendByte(SendByte); //Write data
TWI_WaitAck();
TWI_Stop();
//Note: Because we need to wait for the EEPROM to finish writing, we can use the query or delay method (10ms)
DelayMs(12); //Write delay 12ms Write cycle greater than 10ms
return 3;
}
//Return: 0 error in writing device address, 1 bus busy, 2 error,
//Read 1 byte of data
//ReadAddress: address to be read
uint8_t TWI_ReadByte( uint8_t ReadAddress)
{
uint8_t i,temp;
i = TWI_Start();
if(i)
return i;
TWI_SendByte((ADDR_24CXX & 0xFE)); //Write the device address and perform a dummy write operation first
if(!TWI_WaitAck())
{
TWI_Stop();
return 0;
}
TWI_SendByte(ReadAddress); //Set the starting address
TWI_WaitAck();
TWI_Start();
TWI_SendByte((ADDR_24CXX & 0xFE)|0x01); //Read device address Write: the lowest bit of the address is 0, read: the lowest bit of the address is 1
TWI_WaitAck();
//*pDat = TWI_ReceiveByte();
temp = TWI_ReceiveByte();
TWI_NoAck();
TWI_Stop();
return temp; // If the returned value is 0, 1, or 2, it is the same as the error code. Consider this again.
}
/***************************************************************************
Write multiple bytes to 24c256
psrc_data: pointer to the data array to be written
adr: the first address of the data to be written in 24c256
nbyte: The number of bytes written
Return value: 0: Execution completed; 1: Execution error occurred
In the formal parameters: C02 has only one address adr; C256 has a high address hadr and a low address ladr
***************************************************************************/
uint8_t I2C_EE_BufferWrite(uint8_t *psrc_data,uint8_t adr,uint8_t nbyte)
{
uint8_t i;
for(;nbyte!=0;nbyte--)
{
i = TWI_Start();
if(i)
return i;
TWI_SendByte( ADDR_24CXX & 0xFE); //Write device address
if(!TWI_WaitAck())
{
TWI_Stop();
return 0;
}
TWI_SendByte(adr); //Set the starting address
TWI_WaitAck();
TWI_SendByte(*psrc_data); //Write data
TWI_WaitAck();
psrc_data++; //Pointer to the data to be written plus 1
adr++; //Add 1 to the operation address of 24C08
TWI_Stop();
//Note: Because we need to wait for the EEPROM to finish writing, we can use the query or delay method (10ms)
DelayMs(12); //Write delay 12ms Write cycle greater than 10ms
}
return 0;
}
/***************************************************************************
Read multiple bytes from 24c02
pdin_data: pointer to the array where the read data is to be stored
adr: the first address of the data to be read in 24c02
nbyte: the number of bytes read
Return value: 0: Execution completed; 1: Execution error occurred
***************************************************************************/
uint8_t I2C_EE_BufferRead(uint8_t *pdin_data,uint8_t adr,uint8_t nbyte)
{
uint8_t i;
i = TWI_Start();
if(i)
return i;
TWI_SendByte((ADDR_24CXX & 0xFE)); //Write the device address and perform a dummy write operation first
if(!TWI_WaitAck())
{
TWI_Stop();
return 0;
}
TWI_SendByte(adr); //Set the starting address
TWI_WaitAck();
TWI_Start();
TWI_SendByte((ADDR_24CXX & 0xFE)|0x01); //Read device address Write: the lowest bit of the address is 0, read: the lowest bit of the address is 1
TWI_WaitAck();
while(nbyte!=1) //Read the first (nbyte-1) bytes
{
*pdin_data = TWI_ReceiveByte(); //Loop to read data from 24C02 and store it in the memory pointed to by pdin_data
TWI_Ack(); //IIC response
pdin_data++; //Pointer to the memory where the read data is stored plus 1
nbyte--; //The remaining bytes to be read minus 1
};
*pdin_data = TWI_ReceiveByte(); //Read the last byte
TWI_NoAck(); //IIC no response operation
TWI_Stop();
return 0;
}
/*
void TWI_24CXX_Write(uint8_t* pDat, uint8_t nAddr, uint8_t nLen)
{
uint16_t i;
for(i=0;i { TWI_WriteByte(*(pDat+i), nAddr+i); } } void TWI_24CXX_Read(uint8_t* pDat, uint8_t nAddr, uint8_t nLen) { uint16_t i; for(i=0; i *(pDat+i) = TWI_ReadByte(nAddr+i); } */
Previous article:Summary of the process of reading and writing EEPROM using I2C in STM32
Next article:STM32 GPIO and the first STM32 program (marquee)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- 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
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Sandia Labs develops battery failure early warning technology to detect battery failures faster
- The joys and sorrows of UWB (Ultra-Wideband)
- EEWORLD University Hall ---- Computer Control Technology Harbin Institute of Technology Guo Ben
- Type-C dual battery fast charging solution
- About circuit power management
- DIY nucleic acid sampling registration system——lugl43138200
- [ST MEMS waterproof pressure sensor LPS27HHW review] + analysis and use of routines
- Free RF design tools.
- HuaDa Semiconductor MCU M0+ Series Product IAP Reference
- [Social Recruitment] [Campus Recruitment] China Electronics Technology Group Corporation Recruitment for Embedded Software Development
- EEWORLD University Hall----Live Replay: TI's new generation Sitara? AM62 processor revolutionizes human-computer interaction-accelerates the development of edge AI