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

news2024/9/28 21:26:21

将姓名(拼音)+学号写入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();

实验结果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/711876.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Dubbo【Dubbo实战(用户更新业务消费者实现、用户删除业务消费者实现、复习内容) 】(六)-全面详解(学习总结---从入门到深化)

目录 Dubbo实战_用户更新业务消费者实现 Dubbo实战_用户删除业务消费者实现 复习内容&#xff1a; Dubbo实战_用户更新业务消费者实现 在Consumer中调用更新用户业务 /*** 根据用户id修改用户名字* param users* return*/Integer updateUsers(User users);/*** 根据用户id查…

Apollo分布式配置中心(二)

上一篇&#xff1a; 上一篇已经知道Apollo是什么东西了&#xff0c;接下来实践一下 目录 一、创建应用 1、 新增配置 2、创建Namespace ​3、同步配置 4、灰度发布 添加灰度配置项 ​编辑 配置灰度规则 二、删除应用、集群、appNamespace 三、springBoot整合Apollo …

JAVA设计模式介绍

一、什么是设计模式 设计模式&#xff08;Design pattern&#xff09;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计…

前端Vue自定义手机号文本格式化组件手机号码文本转星号

前端Vue自定义手机号文本格式化组件, 下载完整代码请访问uni-app插件市场地址&#xff1a;https://ext.dcloud.net.cn/plugin?id13231 效果图如下: # cc-format-phone #### 使用方法 使用方法 <!-- phone:手机号 isStar: 是否转星号 --> <cc-format-phone :phon…

2023.7.2

#include <iostream>using namespace std;class Complex { private:int age;int num; public://无参构造Complex(){}//有参构造Complex(int age,int num){this->age age;this->num num;}void show(){cout << "age" << age << "…

chatgpt赋能python:用Python根据IP地址查找具体地址:一个实用的SEO技巧

用Python根据IP地址查找具体地址&#xff1a;一个实用的SEO技巧 在数字化时代&#xff0c;IP地址是一个重要的数字标识符。使用IP地址来发现目标受众的位置是网络营销和搜索引擎优化策略的重要组成部分。在本文中&#xff0c;我们将介绍用Python编程语言根据IP地址查找具体地址…

4. MySQL多表查询练习题

数据库表 CREATE TABLE departments (dept_no CHAR(4) PRIMARY KEY COMMENT 部门编码,dept_name VARCHAR(40) NOT NULL UNIQUE COMMENT 部门名称 ) COMMENT 部门表;CREATE TABLE dept_emp (emp_no INT NOT NULL COMMENT 部门编码,dept_no …

vue路由配置公共布局layout

本篇实现三段式界面 公共布局文件 首先在src下新建layoutPc文件夹&#xff0c;再给layoutPc新建组件 header 、bottm、main三个文件基本确定了一个页面的基本架子&#xff0c;然后再新建一个index.vue文件 comment/AppMain.vue <template><section class"ap…

卷积神经网络狗猫数据集的分类

卷积神经网络狗猫数据集的分类 环境搭建 安装Anaconda 具体安装过程&#xff0c;请自行百度 配置TensorFlow、Keras 创建虚拟环境 输入下面命令&#xff1a; conda create -n ppqppl_tfl python3.6 #tf1是自己为创建虚拟环境取的名字&#xff0c;后面python的版本可以根据自己需…

MyBatis-Plus教程,不敢说是最详细的

一、MyBatis-Plus 1.简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window)的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 我们的愿景是成为 MyBatis 最好的搭档&…

基于SpringBoot+vue的在线动漫信息平台设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

SAM 在遥感图像分割上的应用

文章目录 导读方法SAM 模型SAM 的实例分割扩展 RSPrompter概述特征聚合器锚点式Prompter查询式Prompter 实验在 WHU 上的结果在NWPU上的结果在SSDD上的结果 总结参考 Title: RSPrompter: Learning to Prompt for Remote Sensing Instance Segmentation based on Visual Foundat…

Spring Boot 整合视图层技术 FreeMarker

大家好&#xff01;我是今越。简单记录一下在 Spring Boot 框架中如何整合 Freemarker 及使用。 FreeMarker 简介 FreeMarker 是一款模板引擎&#xff1a;即一种基于模板和要改变的数据&#xff0c;并用来生成输出文本&#xff08; HTML 网页&#xff0c;电子邮件&#xff0c;…

Python3 实例(二) | 菜鸟教程(二十)

目录 一、Python 将列表中的头尾两个元素对调 &#xff08;一&#xff09;定义一个列表&#xff0c;并将列表中的头尾两个元素对调。 &#xff08;二&#xff09;实例1 &#xff08;三&#xff09;实例2 &#xff08;四&#xff09;实例3 二、Python 将列表中的指定位置的…

新一代版本依赖管理Vesion Catalog的探索与实践

前言 前段时间使用新版本的Android Studio创建了个项目想测试点东西&#xff0c;项目创建后发现整个Gradle的依赖管理发生了巨大的变化。 先说一下我使用的Android Studio的版本如下。 创建项目后主要变化如下&#xff1a; 原本的.gradle变成了.gradle.kts&#xff0c;也就是…

商业综合体智能管理系统

自主研发的商业综合体智能管理系统和智能硬件&#xff0c;并针对行业不同需求&#xff0c;推出了不同行业的创新解決方案和服务。该系统能够提高商业综合体的管理效率和安全性&#xff0c;为商业综合体的经营和服务增加更多的价值。全自动智能完成无需人工干预&#xff0c;从而…

【企业架构框架】SOGAF架构类型/模式

模式概述 Salesforce 运营、治理和架构框架 (SOGAF) 将新窗口企业架构框架中的 MIT-CISR Salesforce 实施和程序。在此框架内&#xff0c;有四种通用架构类型&#xff1a; 单一系统核心模型模板多系统 每个特定的架构类型对应一个支持 SOGAF 运营模型。架构类型的选择还应包括…

前端搭建名言生成器(内含源码)

目录 前言 名言生成器 页面搭建 功能实现 前言 今天呢我们来给大家展示的&#xff0c;就是一个非常非常简单的名言生成器&#xff0c; 那么它的功能的非常简单&#xff0c;就是我们通过点击按钮&#xff0c;然后可以生成名人名言&#xff0c;然后我们也可以点击按钮将它分享到…

C++图形开发(1):graphics图形库简介与安装

文章目录 1.引入2.安装&#xff08;1&#xff09;在官网下载安装包&#xff08;2&#xff09;安装 3.检验 1.引入 为了帮助大家实现真正的、更有意思的C开发&#xff0c;本人决定开一个C图形开发的专栏&#xff0c;来制作更多的有意思的游戏、程序。 首先我们要了解的&#x…