STM32F4 读/写 EEPROM【EEPROM、串口显示】

将姓名(拼音)+学号写入EEPROM并在启动时通过串口显示

本篇博客将介绍如何使用STM32F4开发板将姓名(拼音)+学号写入EEPROM,并在启动时通过串口显示。我们将使用核心实现函数EEPROM_WR_Test来完成这个功能。

准备工作

在开始之前,我们需要准备以下材料:

  • STM32F4开发板
  • I2C EEPROM(例如24C64)
  • 连接线

接下来,按照以下步骤进行连接:

  1. 将I2C EEPROM的VCC引脚连接到STM32F4开发板的5V引脚。
  2. 将I2C EEPROM的GND引脚连接到STM32F4开发板的GND引脚。
  3. 将I2C EEPROM的SCL引脚连接到STM32F4开发板的I2C_SCL引脚。
  4. 将I2C EEPROM的SDA引脚连接到STM32F4开发板的I2C_SDA引脚。

连接完成后,我们可以开始编写代码。

编写代码

首先,我们需要在代码中包含相应的头文件和定义相关的宏:

原始的例子中是存在eeprom.ceeprom.h

eeprom.h
如果你有原始的例子,就不需要添加这个

/* 这是一个EEPROM的头文件,EEPROM的型号是FM24C64-D. */

#ifndef __EEPROM_H
#define __EEPROM_H

#include <string.h>
#include <stdint.h>
#include <stdbool.h>

#include "stm32f4xx.h"
#include "stm32f4xx_i2c.h"

#define ADDR_EEPROM_24C64		0xA0

#define I2C_Open_FLAG_TIMEOUT         ((uint32_t)0x1000)
#define I2C_Open_LONG_TIMEOUT         ((uint32_t)(10 * I2C_Open_FLAG_TIMEOUT))



void EEPROM_Config(void); 

uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num);
uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num);

void Del_EEPROM_Data(uint16_t addr_start,uint16_t datalen);
//void EEPROM_WR_Test( );
#endif


eeprom.c

在原始例子中,你仅需要修改void EEPROM_WR_Test( )函数

/* 这是一个EEPROM的驱动文件,EEPROM的型号是FM24C64-D. */
#include "stm32f4xx_rcc.h"
#include "eeprom.h"
#include "usart.h"
#include "user.h"

#include "GWProtocol.h"



#define I2C                        	  I2C3
#define I2C_CLK                    	  RCC_APB1Periph_I2C3

#define I2C_SDA_PIN                 	GPIO_Pin_9
#define I2C_SDA_GPIO_PORT           	GPIOC
#define I2C_SDA_GPIO_CLK            	RCC_AHB1Periph_GPIOC
#define I2C_SDA_SOURCE              	GPIO_PinSource9
#define I2C_SDA_AF                  	GPIO_AF_I2C3

#define I2C_SCL_PIN                 	GPIO_Pin_8
#define I2C_SCL_GPIO_PORT           	GPIOA
#define I2C_SCL_GPIO_CLK            	RCC_AHB1Periph_GPIOA
#define I2C_SCL_SOURCE              	GPIO_PinSource8
#define I2C_SCL_AF                  	GPIO_AF_I2C3

#define I2C_SPEED               100000
#define I2C_SLAVE_ADDRESS7      0x30


static void I2C_delay(uint16_t cnt);
uint32_t I2C_TIMEOUT_UserCallback(void);
static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr);

__IO uint32_t  I2CTimeout = I2C_Open_LONG_TIMEOUT;

/*******************************************************************************
* Function Name  : EEPROM_Configuration
* Description    : 
* Input          : None
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
void EEPROM_Config(void)
{
    
    
			I2C_InitTypeDef  I2C_InitStructure;
			GPIO_InitTypeDef  GPIO_InitStructure; 
			
			RCC_AHB1PeriphClockCmd(I2C_SDA_GPIO_CLK | I2C_SCL_GPIO_CLK,ENABLE);
			
			RCC_APB1PeriphClockCmd(I2C_CLK,ENABLE);
			
			GPIO_PinAFConfig(I2C_SDA_GPIO_PORT, I2C_SDA_SOURCE, I2C_SDA_AF);
			GPIO_PinAFConfig(I2C_SCL_GPIO_PORT, I2C_SCL_SOURCE, I2C_SCL_AF);
			
			GPIO_InitStructure.GPIO_Pin =  I2C_SDA_PIN;
			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
			GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
			GPIO_Init(GPIOC, &GPIO_InitStructure);
				
			GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;
			GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
			GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
			GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
			GPIO_Init(GPIOA, &GPIO_InitStructure);
	
		
			I2C_DeInit(I2C);
			I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
			I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
			I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
			I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
			I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
			I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
			
			I2C_Cmd(I2C, ENABLE);
			I2C_Init(I2C, &I2C_InitStructure);
			
			I2C_AcknowledgeConfig(I2C, ENABLE);
			
}
/*******************************************************************************
* Function Name  : I2C_delay
* Description    : 
* Input          : None
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
static void I2C_delay(uint16_t cnt)
{
    
    
	while(cnt--);
}

/**
  * @brief  Basic management of the timeout situation.
  * @param  None.
  * @retval None.
  */
uint32_t I2C_TIMEOUT_UserCallback(void)
{
    
    
  /* Block communication and all processes */
  printf("\r\n The I2C communication is corrupted \r\n");
  while (1)
  {
    
       
  }
}

/*******************************************************************************
* Function Name  : I2C_AcknowledgePolling
* Description    : 
* Input          : I2C_TypeDef * , uint8_t
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr)
{
    
    
  vu16 SR1_Tmp;
  do
  {
    
       
    I2C_GenerateSTART(I2Cx, ENABLE);

    SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);

		I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);

		}while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));
		
		I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
			
		I2C_GenerateSTOP(I2Cx, ENABLE);
}


/*******************************************************************************
* Function Name  : I2C_Read
* Description    : 
* Input          : 
* Output         : 
* Return         : 
* Attention		 : None
*******************************************************************************/
uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num)
{
    
    
  if(num==0)
	return 1;
	
	while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
	I2C_ClearFlag(I2Cx, I2C_FLAG_BUSY);
		
	I2C_AcknowledgeConfig(I2Cx, ENABLE);


  I2C_GenerateSTART(I2Cx, ENABLE);
  while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));


    I2C_Send7bitAddress(I2Cx,  I2C_Addr, I2C_Direction_Transmitter);
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

	I2C_SendData(I2Cx, (addr >> 8));
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	
	I2C_SendData(I2Cx, (addr & 0xFF));
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	
		
	I2C_GenerateSTART(I2Cx, ENABLE);
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
	
	I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
		
  while (num)
    {
    
    
		if(num==1)
		{
    
    
     		I2C_AcknowledgeConfig(I2Cx, DISABLE);
    		I2C_GenerateSTOP(I2Cx, ENABLE);
		}
	    
		while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));  /* EV7 */
	    *buf = I2C_ReceiveData(I2Cx);
	    buf++;
	    /* Decrement the read bytes counter */
	    num--;
    }

	I2C_AcknowledgeConfig(I2Cx, ENABLE);

	return 0;
}	

/*******************************************************************************
* Function Name  : I2C_WriteOneByte
* Description    : 
* Input          : 
* Output         : None
* Return         : 
* Attention		 : None
*******************************************************************************/
uint8_t I2C_WriteOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t value)
{
    
    
		addr = addr & 0x1FFF;
		
		I2CTimeout = I2C_Open_LONG_TIMEOUT;
		while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))
			{
    
    
				if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
			}
		I2C_ClearFlag(I2Cx, I2C_FLAG_BUSY);
  	
		I2C_GenerateSTART(I2Cx, ENABLE);
		I2CTimeout = I2C_FLAG_TIMEOUT;
		while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
		{
    
    
			if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
		}  


   	I2CTimeout = I2C_FLAG_TIMEOUT;
  	I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  	{
    
    
    	if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
  	}

  	I2C_SendData(I2Cx, (addr >> 8));

   	I2CTimeout = I2C_FLAG_TIMEOUT;  
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  	{
    
    
    	if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
  	} 
		
		I2C_SendData(I2Cx, (addr & 0xFF));
   	I2CTimeout = I2C_FLAG_TIMEOUT;  
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  	{
    
    
    	if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
  	} 
		
  	I2C_SendData(I2Cx, value);
	I2CTimeout = I2C_FLAG_TIMEOUT; 
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	{
    
    
    	if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
  	} 
	
  	I2C_GenerateSTOP(I2Cx, ENABLE);
  
  	I2C_AcknowledgePolling(I2Cx,I2C_Addr);

	I2C_delay(1000);

	return 0;
}


/*******************************************************************************
* Function Name  : I2C_Write
* Description    : 
* Input          : 
* Output         : None
* Return         : 
* Attention		 : None
*******************************************************************************/
uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num)
{
    
    
	uint8_t err=0;
	
		
	while(num--)
	{
    
    
				
		if(I2C_WriteOneByte(I2Cx, I2C_Addr,addr++,*buf++))
		{
    
    
			Delay_MS(10);
			err++;
		}
	}
	if(err)
		return 1;
	else 
		return 0;	
}


/* EEPROM清除函数. */
void Del_EEPROM_Data(uint16_t addr_start,uint16_t datalen)
{
    
    
		
	uint8_t data[TERM_MAX_NUM*GW_TERMINAL_LIST_LEN];
	
	memset(data,0,sizeof(uint8_t)*TERM_MAX_NUM*GW_TERMINAL_LIST_LEN);
	I2C_Write(I2C3, ADDR_EEPROM_24C64, addr_start, data, datalen);
}




/***** EEPROM读写测试. *****/
void EEPROM_WR_Test(  )
{
    
    
	uint16_t i;
	uint8_t readbuf[500];
	uint8_t writebuf[] = {
    
    '2','x','x'};

	//for( i = 0;i < 100;i++) writebuf[i] = i;
	
	printf(" EEPROM write start....\r\n");
	I2C_Write(I2C3,ADDR_EEPROM_24C64,0x0,writebuf,100);
			
	Delay_MS( 1000 );
	printf(" EEPROM read start....\r\n");
	I2C_Read(I2C3,ADDR_EEPROM_24C64,0x0,readbuf,100);
	printf("%s ",readbuf);
	
	/*for(i = 0;i < 100;i++)
	{
		printf("%02X ",readbuf[i]);
	}*/
	printf("\r\n");
}

/********************************************* end file *************************************************/

main.c调用函数

#include "eeprom.h"
……初始化
		EEPROM_Config( );
……读写测试
		EEPROM_WR_Test();

实验结果

在这里插入图片描述

Guess you like

Origin blog.csdn.net/qq_22841387/article/details/131505248