嵌入式进阶——EEPROM读写

news2024/11/16 15:27:17

🎬 秋野酱:《个人主页》
🔥 个人专栏:《Java专栏》《Python专栏》

⛺️心若有所向往,何惧道阻且长

文章目录

    • 设置EEPROM
    • 读写String字符串
    • 官方示例

EEPROM是一种可擦写可编程只读存储器(Electrically Erasable Programmable Read-Only Memory)的缩写。它是一种非易失性存储器,可以在不需要外部电源的情况下保持存储数据。与ROM不同,EEPROM可以通过电子擦除和编程来修改存储的数据,因此它是一种可重写的存储器。

EEPROM通常用于存储需要频繁修改的数据,例如系统配置信息、用户设置、校准数据等。由于EEPROM可以在系统运行时进行读写操作,因此它在许多应用中都具有很高的实用价值。

设置EEPROM

STC8H8K64U的EEPROM可以在烧录的时候指定大小, 如下图
在这里插入图片描述

读写String字符串

#include "Config.h"
#include "UART.h"
#include "EEPROM.h"
#include <string.h>

void UART_config(void) {
    // >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<
    COMx_InitDefine		COMx_InitStructure;					//结构定义
    COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
    COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
    COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200
    COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLE
    COMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLE
    UART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4

    NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
    UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}

#define     Max_Length          100      //读写EEPROM缓冲长度
u8  xdata   tmp[Max_Length];        //EEPROM操作缓冲

void main() {

    u16 addr_sector = 0x0000;
    char *str = "HelloWorld!abc123!";
    u16 str_length = strlen(str);	// 获取str的长度

    UART_config();
		
		EA = 1;

    // 擦除扇区, 一次性擦除一个扇区512字节, 从0x0000开始, 0x01FF
//    EEPROM_SectorErase(u16 EE_address);
    EEPROM_SectorErase(addr_sector);

//    // 写入数据. 字符串\int\long\float
    EEPROM_write_n(u16 EE_address,u8 *DataAddress,u16 number);
    EEPROM_write_n(addr_sector, str, str_length);


    // 读取数据. 字符串\int\long\float
//    EEPROM_read_n(u16 EE_address,u8 *DataAddress,u16 number);
    EEPROM_read_n(addr_sector, tmp, str_length);
		
		// 添加字符串结束符
		tmp[str_length] = '\0';
			
		printf(">>存储的字符串: %s\n", str);
		printf(">>读到的字符串: %s\n", tmp);
		if(strcmp(str, tmp) == 0){
			printf("两个字符串相等\n");
		}else {
			printf("两个字符串不等\n");
		}

    while(1) {

    }

}

官方示例

串口命令设置: (命令字母不区分大小写)
● E 0x0040 --> 对0x0040地址扇区内容进行擦除.
● W 0x0040 1234567890 --> 对0x0040地址写入字符1234567890.
● R 0x0040 10 --> 对0x0040地址读出10个字节数据.

/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.STCAI.com ---------------------------------------------*/
/* --- BBS: www.STCAIMCU.com  -----------------------------------------*/
/* --- QQ:  800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了STC的资料及程序            */
/*---------------------------------------------------------------------*/

#include	"config.h"
#include	"STC8G_H_GPIO.h"
#include	"STC8G_H_UART.h"
#include	"STC8G_H_Delay.h"
#include	"STC8G_H_NVIC.h"
#include	"STC8G_H_EEPROM.h"
#include	"STC8G_H_Switch.h"

/*************	本程序功能说明	**************

本例程基于STC8H8K64U为主控芯片的实验箱8进行编写测试,STC8G、STC8H系列芯片可通用参考.

通过串口对STC内部自带的EEPROM(FLASH)进行读写测试。

对FLASH做扇区擦除、写入、读出的操作,命令指定地址。

默认波特率:  115200,N,8,1. 

串口命令设置: (命令字母不区分大小写)
    E 0x0040             --> 对0x0040地址扇区内容进行擦除.
    W 0x0040 1234567890  --> 对0x0040地址写入字符1234567890.
    R 0x0040 10          --> 对0x0040地址读出10个字节数据. 

注意:下载时,下载界面"硬件选项"中设置用户EEPROM大小,

并确保串口命令中的地址在EEPROM设置的大小范围之内。

下载时, 选择时钟 22.1184MHz (可以在配置文件"config.h"中修改).

******************************************/

#define     Max_Length          100      //读写EEPROM缓冲长度

/*************	本地常量声明	**************/


/*************	本地变量声明	**************/
u8  xdata   tmp[Max_Length];        //EEPROM操作缓冲


/*************	本地函数声明	**************/


/*************  外部函数和变量声明 *****************/


/******************* IO配置函数 *******************/
void	GPIO_config(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;		//结构定义

	GPIO_InitStructure.Pin  = GPIO_Pin_0 | GPIO_Pin_1;		//指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7
	GPIO_InitStructure.Mode = GPIO_PullUp;	//指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
	GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);	//初始化
}

/***************  串口初始化函数 *****************/
void	UART_config(void)
{
	COMx_InitDefine		COMx_InitStructure;					//结构定义

	COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTx
	COMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)
	COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200
	COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLE
	COMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLE
	UART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4
	NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}

/**********************************************/

u8	CheckData(u8 dat)
{
	if((dat >= '0') && (dat <= '9'))		return (dat-'0');
	if((dat >= 'A') && (dat <= 'F'))		return (dat-'A'+10);
	if((dat >= 'a') && (dat <= 'f'))		return (dat-'a'+10);
	return 0xff;
}

//========================================================================
// 函数: u16    GetAddress(void)
// 描述: 计算各种输入方式的地址.
// 参数: 无.
// 返回: 16位EEPROM地址.
// 版本: V1.0, 2013-6-6
//========================================================================
u16 GetAddress(void)
{
	u16 address;
	u8  i,j;
	
	address = 0;
	if((RX1_Buffer[2] == '0') && (RX1_Buffer[3] == 'X'))
	{
		for(i=4; i<8; i++)
		{
			j = CheckData(RX1_Buffer[i]);
			if(j >= 0x10)   return 65535;   //error
			address = (address << 4) + j;
		}
		return (address);
	}
	return  65535;  //error
}

/**************** 获取要读出数据的字节数 ****************************/
u8 GetDataLength(void)
{
	u8  i;
	u8  length;
	
	length = 0;
	for(i=9; i<COM1.RX_Cnt; i++)
	{
		if(CheckData(RX1_Buffer[i]) >= 10)  break;
		length = length * 10 + CheckData(RX1_Buffer[i]);
	}
	return (length);
}

/********************* 主函数 *************************/
void main(void)
{
	u8  i,j;
	u16 addr;
	u8  status;

	EAXSFR();		/* 扩展寄存器访问使能 */
	GPIO_config();
	UART_config();
	EA = 1;

	PrintString1("STC8系列单片机EEPROM测试程序,串口命令设置如下:\r\n");    //UART1发送一个字符串
	PrintString1("E 0x0040             --> 对0x0040地址扇区内容进行擦除\xfd.\r\n");     //UART1发送一个字符串
	PrintString1("W 0x0040 1234567890  --> 对0x0040地址写入字符1234567890.\r\n");  //UART1发送一个字符串
	PrintString1("R 0x0040 10          --> 对0x0040地址读出10个字节内容.\r\n");    //UART1发送一个字符串
	while(1)
	{
		delay_ms(1);
		if(COM1.RX_TimeOut > 0)		//超时计数
		{
			if(--COM1.RX_TimeOut == 0)
			{
				for(i=0; i<COM1.RX_Cnt; i++)    TX1_write2buff(RX1_Buffer[i]);    //把收到的数据原样返回,用于测试

				status = 0xff;  //状态给一个非0值
				if((COM1.RX_Cnt >= 8) && (RX1_Buffer[1] == ' ')) //最短命令为8个字节
				{
					for(i=0; i<8; i++)
					{
						if((RX1_Buffer[i] >= 'a') && (RX1_Buffer[i] <= 'z'))    RX1_Buffer[i] = RX1_Buffer[i] - 'a' + 'A';  //小写转大写
					}
					addr = GetAddress();
					if(addr < 63488)    //限制在0~123扇区
					{
						if(RX1_Buffer[0] == 'E')    //写入N个字节
						{
							EEPROM_SectorErase(addr);           //擦除扇区
							PrintString1("擦除\xfd成功!\r\n");
							status = 0; //命令正确
						}

						else if((RX1_Buffer[0] == 'W') && (RX1_Buffer[8] == ' '))    //写入N个字节
						{
							j = COM1.RX_Cnt - 9;
							if(j > Max_Length)  j = Max_Length; //越界检测
							//EEPROM_SectorErase(addr);           //擦除扇区
							EEPROM_write_n(addr,&RX1_Buffer[9],j);      //写N个字节
							PrintString1("已写入");
							if(j >= 100)    {TX1_write2buff(j/100+'0');   j = j % 100;}
							if(j >= 10)     {TX1_write2buff(j/10+'0');    j = j % 10;}
							TX1_write2buff(j%10+'0');
							PrintString1("字节!\r\n");
							status = 0; //命令正确
						}

						else if((RX1_Buffer[0] == 'R') && (RX1_Buffer[8] == ' '))   //PC请求返回N字节EEPROM数据
						{
							j = GetDataLength();
							if(j > Max_Length)  j = Max_Length; //越界检测
							if(j > 0)
							{
								PrintString1("读出");
								TX1_write2buff(j/10+'0');
								TX1_write2buff(j%10+'0');
								PrintString1("个字节内容如下:\r\n");
								EEPROM_read_n(addr,tmp,j);
								for(i=0; i<j; i++)  TX1_write2buff(tmp[i]);
								TX1_write2buff(0x0d);
								TX1_write2buff(0x0a);
								status = 0; //命令正确
							}
						}
					}
				}
				if(status != 0) PrintString1("命令错误!\r\n");
				COM1.RX_Cnt = 0;
			}
		}
	}
} 
/**********************************************/

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

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

相关文章

源达投顾的客户服务质量怎么样?

在金融服务行业中&#xff0c;客户服务质量是衡量一个公司成功与否的关键因素之一。源达投顾作为一家专业的投资顾问机构&#xff0c;其客户服务质量一直备受关注。那么&#xff0c;源达投顾的客户服务质量怎么样&#xff1f; 一、客户满意度调查方法 为了全面、客观地了解源…

SurfaceView与TextureView的绘制渲染

SurfaceView与TextureView的绘制渲染 一.SurfaceView1.SurfaceView的初始化1.1 SurfaceControl的创建1.1.1 BLASTBufferQueue与SurfaceControl的绑定 1.2 Surface初始化 2.SurfaceHolder的回调与绘制2.1 画布的获取2.2 矩形的绘制2.3 绘制的提交 二.TextureView1.TextureView的…

一文搞懂Java8 Lambda表达式、方法引用

Lambda表达式介绍 Java 8的一个大亮点是引入Lambda表达式&#xff0c;使用它设计的代码会更加简洁。通过Lambda表达式&#xff0c;可以替代我们以前经常写的匿名内部类来实现接口。Lambda表达式本质是一个匿名函数&#xff1b; 体验Lambda表达式 我们通过一个小例子来体验下L…

物联网都有什么优缺点?——青创智通

工业物联网平台解决方案 物联网&#xff0c;这个曾经似乎遥不可及的科技概念&#xff0c;如今已逐渐渗透到我们生活的方方面面。从智能家居到智能工业&#xff0c;从智能医疗到智能城市&#xff0c;物联网技术正在改变着我们的世界。 然而&#xff0c;正如任何一项技术一样&a…

代码随想录算法训练营第五十四天||392.判断子序列、115.不同的子序列

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、392.判断子序列 思路 二、115.不同的子序列 思路 一、392.判断子序列 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是…

FPGA中的乒乓操作

为什么不直接选用一个缓存更大的FIFO而选用乒乓操作为什么乒乓操作可以实现低速处理高速数据乒乓操作适用哪些场景 一、乒乓操作结构 首先先介绍一下乒乓操作的原理&#xff0c;其结构如下&#xff1a; 输入选择单元负责将数据送到数据缓冲模块&#xff0c;然后输出选择单元负…

51 html网页

上节内容的网页是hello world的字符串&#xff0c;但实际上网页应该是html格式的这种超文本标记语言&#xff0c;这一节完善一下网页的各种格式和内容 分文件 实际服务器中&#xff0c;网页的界面应该单独放一个文件&#xff0c;服务器从文件里读取网页的内容 先创建一个wroo…

有效运营企业内部社区的板块有哪些?

随着企业内部沟通和协作的重要性日益凸显&#xff0c;建立一个高效运营的企业内部社区成为越来越多企业的首要任务。针对不同的需求和目标&#xff0c;将企业内部社区分为多个板块&#xff0c;可以更好地促进员工之间的沟通、协作和共享知识。下面介绍如何从分多个板块创建的角…

Docker搭建Redis主从 + Redis哨兵模式(一主一从俩哨兵)

我这里是搭建一主一从&#xff0c;俩哨兵&#xff0c;准备两台服务器&#xff0c;分别安装docker 我这里有两台centos服务器 主服务器IP&#xff1a;192.168.252.134 从服务器IP&#xff1a;192.168.252.135 1.两台服务器分别拉取redis镜像 docker pull redis 2.查看镜像 d…

2024长三角快递物流展即将亮相,致鸿物流器材有限公司值得关注

广东致鸿物流器材有限公司&#xff0c;前身为广州致鸿物流器材有限公司&#xff0c;成立于2002年初&#xff0c;是一家中国专业仓储笼研发制造公司&#xff0c;公司员工约400名&#xff0c;日产仓储笼制造规模近8000个&#xff0c;在全国范围内有五大配送服务中心&#xff1a;江…

AI绘画Stable Diffusion XL 可商用模型!写实艺术时尚摄影级真实感大模型推荐(附模型下载)

大家好&#xff0c;我是设计师阿威 大家在使用AI绘画的时候&#xff0c;是不是遇到这种问题&#xff1a;收藏的模型确实很多&#xff0c;可商用的没几个&#xff0c;而今天阿威将给大家带来的这款写实艺术时尚摄影级真实感大模型-墨幽人造人XL&#xff0c; 对于个人来讲完全是…

应用弹窗优先级

背景 由于活动业务越来越多,积累的弹窗越来越多和杂乱,出现如下弹窗交互问题: 弹窗无限重叠,影响操作 弹出顺序无优先级,重要弹窗被隐藏 原因相信大家都一样,产品是一次次迭代的,也可能是不同人开发的,两个毫不相关的业务,弹窗时机也没有任何关联,重不重叠我怎么控制…

第8周 分布式事务与数据一致性主流解决方案落地

第8周 分布式事务与数据一致性主流解决方案落地 1. OpenFeign 服务间的远程调用_实战2. 客户端与服务端负载均衡机制_概念3. 微服务负载均衡NacosLoadbalancer_实战网关基于nacos实现负载均衡:默认轮询方式权重方式实现4. OSI七层网络模型_概念5. 微服务分布式环境下的事务问题…

Ubuntu22.04设置程序崩溃产生Core文件

Ubuntu22.04设置程序崩溃产生Core文件 文章目录 Ubuntu22.04设置程序崩溃产生Core文件摘要Ubuntu 生成Core文件配置1. 检查 core 文件大小限制2. 设置 core 文件大小限制3. 配置 core 文件命名和存储路径4. 重启系统或重新加载配置5. 测试配置 关键字&#xff1a; Ubuntu、 C…

VSCode连接远程服务器使用jupyter报错问题解决

目录 一. 问题描述二. jupyter环境确认三. 插件安装 一. 问题描述 经常会遇到一种问题就是, VSCode连接远程服务器, 上次jupyter notebook 还用的好好的, 下次打开就显示找不到内核了. 今天提供了全套解决方案, 帮大家迅速解决环境问题. 二. jupyter环境确认 首先进入自己需…

React 中的 Fiber 架构

React Fiber 介绍 React Fiber 是 React 的一种重写和改进的核心算法&#xff0c;用于实现更细粒度的更新和高效的调度。它是 React 16 版本中的一个重要更新&#xff0c;使得 React 能够更好地处理复杂和高频的用户交互。以下是对 React Fiber 的详细介绍&#xff1a; 为什么…

java中的工具类

以下是我们到现在学的三个类 在书写工具类的时候我们要遵循以下的规则 类名见面知意是为了知道这个工具类的作用 私有化构造方法的作用是为了不让外界不能创造这个类的对象吗&#xff0c;因为工具类不是描述一个事物的&#xff0c;它是一个工具。 方法定义位静态是为了方便调用…

8086 汇编笔记(一):寄存器

前言 8086 CPU 有 14 个寄存器&#xff0c;每个寄存器有一个名称。这些寄存器是&#xff1a;AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW 一、通用寄存器 8086 CPU 的所有寄存器都是 16 位的&#xff0c;可以存放两个字节。AX、BX、CX、DX 这 4个寄存器通常用…

剧本杀小程序开发,探索市场发展新的商业机遇

剧本杀游戏作为一个新兴行业&#xff0c;经历了爆发式的增长&#xff0c;剧本杀游戏在市场中的热度不断升高。 不过&#xff0c;在市场的火热下&#xff0c;竞争也在逐渐加大。因此&#xff0c;在市场竞争下&#xff0c;成本低、主题多样、有趣的线上剧本杀小程序成为了创业者…

永恒之蓝(MS17-010)详解

这个漏洞还蛮重要的&#xff0c;尤其在内网渗透和权限提升。 目录 SMB简介 SMB工作原理 永恒之蓝简原理 影响版本 漏洞复现 复现准备 复现过程 修复建议 SMB简介 SMB是一个协议服务器信息块&#xff0c;它是一种客户机/服务器、请求/响应协议&#xff0c;通过SMB协议…