STM32F030 IIC2通用读写24C02、24C16、24C32、24C64等例程

前言:

咱们做嵌入式开发经常用到EEPROM,但是EEPROM的大小不同会需要不同代码来适配,这不利于快捷开发。在此本人分享自己优化总结后一段代码给大家,该代码通用读写24C02、24C16、24C32、24C64等EEPROM,只需在宏定义做相应芯片型号定义,则可使用。
注意!该代码适用于STM32F030的I2C2,如果需要用I2C1或者芯片型号是STM32F0XX其他系列的,需要做相应的驱动代码改动。


C文件代码:


/* Includes ------------------------------------------------------------------*/
#include "bs_iic.h"


uint32_t AT24Cxx_Timeout;
uint8_t AT24Cxx_Address=0;
uint8_t AT24Cxx_DataNum=0;


/*
主机模式
普通模式  100kHZ
I2C时钟频率32000KHz
使用模拟滤波器
不使用数字滤波器
上升时间100ns
下降时间10ns
*/
uint32_t AT24Cxx_TIMEOUT_UserCallback(void)
{
    /* Block communication and all processes */
  /*  while (1)
    {   
    }*/
	return AT24Cxx_FAIL;
}


void I2C2_Init(void)
{

	I2C_InitTypeDef I2C_InitStruct;
	GPIO_InitTypeDef GPIO_InitStructure;
   	I2C_DeInit(I2C1);
	//RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
//	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_1);
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_1);
	


    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    I2C_InitStruct.I2C_Ack=I2C_Ack_Enable;
    I2C_InitStruct.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
    I2C_InitStruct.I2C_AnalogFilter=I2C_AnalogFilter_Enable;
    I2C_InitStruct.I2C_DigitalFilter=0x00;
    I2C_InitStruct.I2C_Mode=I2C_Mode_I2C;
    I2C_InitStruct.I2C_OwnAddress1=0x00;//0x55;//
    I2C_InitStruct.I2C_Timing=0x30E32E44;//0x20D22E37;
    I2C_Init(I2C2,&I2C_InitStruct);
	
	//RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
	I2C_Cmd(I2C2, ENABLE);
}

void AT24CXX_Init(void)
{
    I2C2_Init();
    AT24Cxx_Address = AT24Cxx_HW_Address;
}

uint32_t AT24Cxx_WaitEepromStandbyState(void)      
{
    __IO uint32_t sEETrials = 0;

/* Configure CR2 register : set Slave Address and end mode */
    I2C_TransferHandling(AT24Cxx_I2C, 
                         AT24Cxx_Address,
                         0, 
                         I2C_AutoEnd_Mode,
                         I2C_No_StartStop);  

    do
    { 
        /* Initialize sEETimeout */
        AT24Cxx_Timeout = AT24Cxx_FLAG_TIMEOUT;

        /* Clear NACKF */
        I2C_ClearFlag(AT24Cxx_I2C, 
                      I2C_ICR_NACKCF | I2C_ICR_STOPCF);

        /* Generate start */
        I2C_GenerateSTART(AT24Cxx_I2C, ENABLE);

        /* Wait until timeout elapsed */
        while (AT24Cxx_Timeout-- != 0); 

        /* Check if the maximum allowed numbe of trials has bee reached */
        if (sEETrials++ == AT24Cxx_MAX_TRIALS_NUMBER)
        {
            /* If the maximum number of trials has been reached, exit the function */
            return AT24Cxx_TIMEOUT_UserCallback();
        }
    }

    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_NACKF) != RESET);

    /* Clear STOPF */
    I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_STOPCF);

    /* Return sEE_OK if device is ready */
    return AT24Cxx_OK;
}

uint32_t AT24Cxx_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
{
    uint32_t DataNum = 0;
#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64) 
    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 2, I2C_Reload_Mode, I2C_Generate_Start_Write);
#else
	I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
#endif
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;

    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) 
        {
            return AT24Cxx_TIMEOUT_UserCallback();
        }
    }

#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64) 
  /* Send MSB of memory address */
    I2C_SendData(AT24Cxx_I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));  

  /* Wait until TXIS flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;

    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) 
        {
            return AT24Cxx_TIMEOUT_UserCallback();
        }
    }
#endif

    /* Send LSB of memory address  */
    I2C_SendData(AT24Cxx_I2C, (uint8_t)(WriteAddr & 0x00FF));

    /* Wait until TCR flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TCR) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) 
        {
            return AT24Cxx_TIMEOUT_UserCallback();
        }
    }

    /* Update CR2 : set Slave Address , set write request, generate Start and set end mode */
    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, (uint8_t)(*NumByteToWrite), I2C_AutoEnd_Mode, I2C_No_StartStop);

    while (DataNum != (*NumByteToWrite))
    {      
        /* Wait until TXIS flag is set */
        AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
        while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET)
        {
        if((AT24Cxx_Timeout--) == 0) 
        {
          return AT24Cxx_TIMEOUT_UserCallback();
        }
        }  

        /* Write data to TXDR */
        I2C_SendData(AT24Cxx_I2C, (uint8_t)(pBuffer[DataNum]));

        /* Update number of transmitted data */
        DataNum++;   
    }  

    /* Wait until STOPF flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_STOPF) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) 
        {
            return AT24Cxx_TIMEOUT_UserCallback();
        }
    }   

    /* Clear STOPF flag */
    I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_STOPCF);
    return AT24Cxx_OK;
}




void AT24Cxx_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
    uint16_t NumOfPage = 0, NumOfSingle = 0, count = 0;
    uint16_t Addr = 0;

    Addr = WriteAddr % AT24Cxx_PAGESIZE;
    count = AT24Cxx_PAGESIZE - Addr;
    NumOfPage =  NumByteToWrite / AT24Cxx_PAGESIZE;
    NumOfSingle = NumByteToWrite % AT24Cxx_PAGESIZE;

    /*!< If WriteAddr is sEE_PAGESIZE aligned  */
    if(Addr == 0) 
    {
        /*!< If NumByteToWrite < sEE_PAGESIZE */
        if(NumOfPage == 0) 
        {
            /* Store the number of data to be written */
            AT24Cxx_DataNum = NumOfSingle;
            /* Start writing data */
            AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));
            AT24Cxx_WaitEepromStandbyState();
        }
        /*!< If NumByteToWrite > sEE_PAGESIZE */
        else  
        {
            while(NumOfPage--)
            {
                /* Store the number of data to be written */
                AT24Cxx_DataNum = AT24Cxx_PAGESIZE;        
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum)); 
                AT24Cxx_WaitEepromStandbyState();
                WriteAddr +=  AT24Cxx_PAGESIZE;
                pBuffer += AT24Cxx_PAGESIZE;
            }

            if(NumOfSingle!=0)
            {
                /* Store the number of data to be written */
                AT24Cxx_DataNum = NumOfSingle;          
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));
                AT24Cxx_WaitEepromStandbyState();
            }
        }
    }
    /*!< If WriteAddr is not sEE_PAGESIZE aligned  */
    else 
    {
        /*!< If NumByteToWrite < sEE_PAGESIZE */
        if(NumOfPage== 0) 
        {
            /*!< If the number of data to be written is more than the remaining space 
            in the current page: */
            if (NumByteToWrite > count)
            {
                /* Store the number of data to be written */
                AT24Cxx_DataNum = count;        
                /*!< Write the data conained in same page */
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));
                AT24Cxx_WaitEepromStandbyState();      

                /* Store the number of data to be written */
                AT24Cxx_DataNum = (NumByteToWrite - count);          
                /*!< Write the remaining data in the following page */
                AT24Cxx_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&AT24Cxx_DataNum));
                AT24Cxx_WaitEepromStandbyState();        
            }      
            else      
            {
                /* Store the number of data to be written */
                AT24Cxx_DataNum = NumOfSingle;         
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));
                AT24Cxx_WaitEepromStandbyState();        
            }     
        }
        /*!< If NumByteToWrite > sEE_PAGESIZE */
        else
        {
            NumByteToWrite -= count;
            NumOfPage =  NumByteToWrite / AT24Cxx_PAGESIZE;
            NumOfSingle = NumByteToWrite % AT24Cxx_PAGESIZE;

            if(count != 0)
            {  
                /* Store the number of data to be written */
                AT24Cxx_DataNum = count;         
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));
                AT24Cxx_WaitEepromStandbyState();
                WriteAddr += count;
                pBuffer += count;
            } 

            while(NumOfPage--)
            {
                /* Store the number of data to be written */
                AT24Cxx_DataNum = AT24Cxx_PAGESIZE;          
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum));
                AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
                AT24Cxx_WaitEepromStandbyState();
                WriteAddr +=  AT24Cxx_PAGESIZE;
                pBuffer += AT24Cxx_PAGESIZE;  
            }
            if(NumOfSingle != 0)
            {
                /* Store the number of data to be written */
                AT24Cxx_DataNum = NumOfSingle;           
                AT24Cxx_WritePage(pBuffer, WriteAddr, (uint8_t*)(&AT24Cxx_DataNum)); 
                AT24Cxx_WaitEepromStandbyState();
            }
        }
    }  
}



uint32_t AT24Cxx_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{  
    uint32_t NumbOfSingle = 0, Count = 0, DataNum = 0, StartCom = 0;

    /* Get number of reload cycles */
    Count = (*NumByteToRead) / 255;  
    NumbOfSingle = (*NumByteToRead) % 255;
#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64)  
    /* Configure slave address, nbytes, reload and generate start */
    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
#else
	I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
#endif
    /* Wait until TXIS flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) 
        {
            return AT24Cxx_TIMEOUT_UserCallback();
        }
    }
	
#if defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) || defined(AT24C32)|| defined(AT24C64)  
    /* Send MSB of memory address */
    I2C_SendData(AT24Cxx_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));

    /* Wait until TXIS flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;  
    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TXIS) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0)
			return AT24Cxx_TIMEOUT_UserCallback();
    }
#endif
    /* Send LSB of memory address  */
    I2C_SendData(AT24Cxx_I2C, (uint8_t)(ReadAddr & 0x00FF));

    /* Wait until TC flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TC) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
    }  

    /* If number of Reload cycles is not equal to 0 */
    if (Count != 0)
    {
        /* Starting communication */
        StartCom = 1;

        /* Wait until all reload cycles are performed */
        while( Count != 0)
        { 
            /* If a read transfer is performed */
            if (StartCom == 0)      
            {
                /* Wait until TCR flag is set */
                AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT; 
                while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TCR) == RESET)
                {
                    if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
                }
            }      

            /* if remains one read cycle */
            if ((Count == 1) && (NumbOfSingle == 0))
            {
                /* if starting communication */
                if (StartCom != 0)
                {
                    /* Configure slave address, end mode and start condition */
                    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
                }
                else
                {
                    /* Configure slave address, end mode */
                    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_AutoEnd_Mode, I2C_No_StartStop);          
                }
            }
            else 
            {
                /* if starting communication */
                if (StartCom != 0)
                {
                    /* Configure slave address, end mode and start condition */
                    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_Reload_Mode, I2C_Generate_Start_Read);
                }
                else
                {
                    /* Configure slave address, end mode */
                    I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, 255, I2C_Reload_Mode, I2C_No_StartStop);          
                } 
            }

            /* Update local variable */
            StartCom = 0;      
            DataNum = 0;

            /* Wait until all data are received */
            while (DataNum != 255)
            {        
                /* Wait until RXNE flag is set */
                AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
                while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_RXNE) == RESET)
                {
                    if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
                }

                /* Read data from RXDR */
                pBuffer[DataNum]= I2C_ReceiveData(AT24Cxx_I2C);

                /* Update number of received data */
                DataNum++;
                (*NumByteToRead)--;
            }      
            /* Update Pointer of received buffer */ 
            pBuffer += DataNum;  

            /* update number of reload cycle */
            Count--;
        }

        /* If number of single data is not equal to 0 */
        if (NumbOfSingle != 0)
        {            
            /* Wait until TCR flag is set */
            AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;   
            while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_TCR) == RESET)
            {
                if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
            }

            /* Update CR2 : set Nbytes and end mode */
            I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, (uint8_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_No_StartStop);

            /* Reset local variable */
            DataNum = 0;

            /* Wait until all data are received */
            while (DataNum != NumbOfSingle)
            {        
                /* Wait until RXNE flag is set */
                AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
                while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_RXNE) == RESET)
                {
                    if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
                }

                /* Read data from RXDR */
                pBuffer[DataNum]= I2C_ReceiveData(AT24Cxx_I2C);

                /* Update number of received data */
                DataNum++;
                (*NumByteToRead)--;
            } 
        }
    }   
    else
    {
        /* Update CR2 : set Slave Address , set read request, generate Start and set end mode */
        I2C_TransferHandling(AT24Cxx_I2C, AT24Cxx_Address, (uint32_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_Generate_Start_Read);

        /* Reset local variable */
        DataNum = 0;

        /* Wait until all data are received */
        while (DataNum != NumbOfSingle)
        {
            /* Wait until RXNE flag is set */
            AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT; 
            while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_RXNE) == RESET)
            {
                if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
            }

            /* Read data from RXDR */
            pBuffer[DataNum]= I2C_ReceiveData(AT24Cxx_I2C);

            /* Update number of received data */
            DataNum++;
            (*NumByteToRead)--;
        }    
    }  

    /* Wait until STOPF flag is set */
    AT24Cxx_Timeout = AT24Cxx_LONG_TIMEOUT;
    while(I2C_GetFlagStatus(AT24Cxx_I2C, I2C_ISR_STOPF) == RESET)
    {
        if((AT24Cxx_Timeout--) == 0) return AT24Cxx_TIMEOUT_UserCallback();
    }

    /* Clear STOPF flag */
    I2C_ClearFlag(AT24Cxx_I2C, I2C_ICR_STOPCF);

    /* If all operations OK, return sEE_OK (0) */
    return AT24Cxx_OK;
}




/************************ (C) COPYRIGHT LKL0305 ****************END OF FILE****/


H文件代码:

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __BS_I2C_H
#define __BS_I2C_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx.h"


#define AT24Cxx_FLAG_TIMEOUT         ((uint32_t)0x2000)
#define AT24Cxx_LONG_TIMEOUT         ((uint32_t)(10 * AT24Cxx_FLAG_TIMEOUT))

#define AT24Cxx_MAX_TRIALS_NUMBER     300

#define AT24Cxx_OK                    0
#define AT24Cxx_FAIL                  1   
#define AT24Cxx_I2C                   I2C2


//AT24C01 AT24C02           一页  8Byte
//AT24C04 AT24C08 AT24C16   一页  16Byte
//AT24C32 AT24C64           一页  32Byte
//-------注意!!!本代码只适用24C64及以下的EEPROM ,大于8K的ROM不能使用此代码--------------   
#define AT24C02   //定义你使用的芯片型号

#if defined(AT24C01) || defined(AT24C02)
	#define AT24Cxx_PAGESIZE              8
#elif defined(AT24C04) || defined(AT24C08)|| defined(AT24C16) 
	#define AT24Cxx_PAGESIZE              16
#else
	#define AT24Cxx_PAGESIZE              32
#endif

#define AT24Cxx_HW_Address            0xAE//0xA0  这个注意对应你的硬件地址!!!!

extern void AT24CXX_Init(void);
extern void AT24Cxx_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite);
extern uint32_t AT24Cxx_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead);

#endif




主程序代码:

#include "stm32f0xx.h"
#include "bs_iic.h"


int main(void)
{
	//app_run();
	//-----------IIC2-测试代码-----
	uint8_t read_b[64]={0};
	uint8_t wirte_b[64]={1,2,3,4,4,4,8,5,22,66,88,77};
	AT24CXX_Init();


	while(1){
		uint16_t r_num=10;
		uint16_t w_num=10;
		AT24Cxx_ReadBuffer(read_b,0,&r_num);//注意!这里num在读取数据后减少对应长度
		AT24Cxx_WriteBuffer(wirte_b,0,w_num);
		if(wirte_b[0]<250)
			wirte_b[0]++;
		else
			wirte_b[0]=0;
	}

	
}
  • 7
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: STM32F103可以通过硬件I2C接口读写24C02芯片。 步骤如下: 1. 配置I2C接口:设置I2C时钟频率、I2C地址、I2C模式等参数。 2. 发送起始信号:向I2C总线发送起始信号。 3. 发送设备地址:向24C02芯片发送设备地址,包括读写位。 4. 发送数据地址:向24C02芯片发送要读写的数据地址。 5. 发送数据:向24C02芯片发送要写入的数据,或者从24C02芯片读取数据。 6. 发送停止信号:向I2C总线发送停止信号。 具体实现可以参考STM32F103的I2C库函数,例如HAL库中的HAL_I2C_Mem_Read()和HAL_I2C_Mem_Write()函数。 ### 回答2: STM32F103是一种非常流行的32位单片机系列,它具有强大的硬件性能和广泛的应用领域。而24C02则是I2C系列串行EEPROM,可以供我们存储大量的数据。在这里,我们主要介绍如何使用STM32F103的硬件I2C接口来读写24C02。 首先,我们需要对STM32F103的硬件I2C接口进行初始化。其中,我们需要配置I2C的时钟、GPIO口、I2C的工作模式等参数。具体的代码如下: RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);//使能I2C1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;//PB6--I2C1_SCL,PB7--I2C1_SDA GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//开漏输出 GPIO_Init(GPIOB,&GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//I2C模式 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//占空比为2 I2C_InitStructure.I2C_OwnAddress1 = 0x00;//自己的地址,一般为0 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//地址长度 I2C_InitStructure.I2C_ClockSpeed = 400000;//400kHZ时钟频率 I2C_Init(I2C1,&I2C_InitStructure); I2C_Cmd(I2C1,ENABLE);//使能I2C1 接着,我们编写读取21C02的程序。读取时,由于24C02是以字节为单位进行数据的读取,所以我们可以使用IIC的硬件读取指令,在读取时起始地址+1的下一个字节为第一个地址,直至读取结束地址。具体的代码如下: I2C_GenerateSTART(I2C1,ENABLE); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//等待START信号发送成功 I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);//发送器件地址,写命令0xA0 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待发送器件地址成功 I2C_SendData(I2C1,0x00);//发送内部地址0x00 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送成功 I2C_GenerateSTART(I2C1,ENABLE); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//等待START信号发送成功 I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Receiver);//发送器件地址,读命令0xA1 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//等待接收器件地址成功 for(i=0;i<length;i++) { if(i==(length-1))I2C_AcknowledgeConfig(I2C1,DISABLE);//如果是最后一个字节,后面不再发送AK信号,即不再接收数据 while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)); RxBuffer[i]=I2C_ReceiveData(I2C1); } I2C_GenerateSTOP(I2C1,ENABLE);//发送一个停止信号 再来看一下24C02的写入操作。通过IIC硬件写入指令,我们可以将数据依次写入到指定的地址中,假如写入了n个字节,则下一次写操作的地址将会到达第n+1个地址。具体的代码如下: I2C_GenerateSTART(I2C1,ENABLE); while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));//等待START信号发送成功 I2C_Send7bitAddress(I2C1,0xA0,I2C_Direction_Transmitter);//发送器件地址,写命令0xA0 while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待发送器件地址成功 I2C_SendData(I2C1,Addr);//发送写入的地址 while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送成功 for(i=0;i<length;i++) { I2C_SendData(I2C1,buf[i]);//发送数据 while(! I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待发送成功 } I2C_GenerateSTOP(I2C1,ENABLE);//发送一个停止信号 综上所述,我们可以通过STM32F103的硬件I2C接口来读取或写入24C02。不过,在实际操作中,还需要注意一些注意事项,如使用IIC读取有ACK和无ACK状态,需要注意IIC的时序等问题。 ### 回答3: STM32F103是一款基于ARM Cortex-M3内核的微控制器,支持多种通信接口,包括I2C总线接口。24C02是一种I2C EEPROM芯片,可用于存储小型数据和程序。 在STM32F103中,可以通过GPIO配置I2C总线接口来进行24C02读写操作。以下是实现I2C读写的基本步骤: 1. 配置GPIO引脚 使用CubeMX或者直接编写代码,将STM32F103的GPIO引脚配置成I2C总线引脚。通常I2C总线由两个引脚组成,即数据线(SDA)和时钟线(SCL),其中SDA引脚为双向输出,SCL引脚为输出。 2. 配置I2C总线 使用CubeMX或者直接编写代码,将STM32F103的I2C总线配置成所需的速率和从设备地址。24C02只有一个地址(0x50),因此将其配置为从设备地址即可。 3. 发送I2C起始信号 在进行I2C通信之前,需要先发送起始信号。发送起始信号的代码如下: HAL_I2C_Master_Transmit(&hi2c1, 0xA0, NULL, 0, 100); 其中hi2c1为I2C总线句柄,0xA0为24C02的从设备地址。 4. 发送I2C写入地址 在向24C02写入数据之前,需要先向其写入地址。该地址为数据的存储地址,可以根据具体要求进行设置。例如,向地址0x00写入数据,代码如下: HAL_I2C_Master_Transmit(&hi2c1, 0xA0, &addr, 1, 100); 其中addr为写入的地址。 5. 发送数据 在向24C02写入数据之前,需要先向其发送要写入的数据。代码如下: HAL_I2C_Master_Transmit(&hi2c1, 0xA0, &data, 1, 100); 其中data为要写入的数据。 6. 发送I2C停止信号 在完成I2C通信后,需要发送停止信号。发送停止信号的代码如下: HAL_I2C_Stop(&hi2c1); 以上是向24C02写入数据的基本步骤,读取数据的方法类似,只需将写入操作替换为读取操作即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值