嵌入式进阶——EEPROM读写

🎬 秋野酱:《个人主页》
🔥 个人专栏:《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;
			}
		}
	}
} 
/**********************************************/

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MT2076 小码哥处理订单

思路&#xff1a; 使用二分&#xff1a;题目中隐含条件&#xff1a;如果不满足&#xff0c;需要找到第一个不满足的订单。 二分法需要满足单调性or有一个界线使前后两部分性质相反。这里的”界线“为&#xff1a;是否满足条件。假设第i天无法满足&#xff0c;则后面的所有天都…

SAP ABAP MD04屏幕增加:增加列

需求:增加显示销售订单送达方 主要使用二代增强出口:M61X0002 事务码T-code:CMOD 填写描述,保存到对应的包下 分配增强到项目下 激活组件,激活后效果如下 编写ZXM61U04 SAP留出的按钮,填写描述 button1_ez = 送达方. 编写ZXM61U03 *&-------------------------…

通讯录恢复怎么办?保护珍贵联系信息的2个必备技能!

手机通讯录扮演着重要的角色&#xff0c;它不仅仅是一个简单的联系方式列表&#xff0c;更是我们与亲朋好友、同事、业务伙伴等之间关系的见证。万一不慎丢失或误删通讯录&#xff0c;学会通讯录恢复的技能变得非常重要。本文将为你介绍几种保护珍贵联系信息的必备技能&#xf…

dubbo复习:(11)使用grpc客户端访问tripple协议的dubbo 服务器

一、服务器端依赖&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…

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个寄存器通常用…

如何在操作系统中合并 PDF 文件?不同系统有不同的方法

Windows 系统 在 Windows 系统中想要合并 PDF 文件我们可能需要借助一些第三方的软件或者浏览器的插件。 我们可以在 Google 浏览器中的 Chrome 应用商店中输入“Merge pdf”这样就可以搜索到在线合并 PDF 文件的插件&#xff0c;只需要下载到浏览器中就可以直接使用。当然 Ed…

量化交易:如何在QMT中运行Python策略并在VSCode中高效调试?

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 为何选择QMT和VSCode进行量化策略开发&#xff1f; 在量化交易的世界里&#xff0c;选择正确的工具与拥有优秀的策略同等重要。调用用Visual Studio Code&#xff08;简称VSCode&#xff09;或pycharm&#xff0c;方…

【SQLServer】Merge语法

概述 MERGE语句&#xff0c;也被称为“upsert”&#xff0c;根据与源表联接的结果&#xff0c;对目标表进行插入、更新或删除操作。 例如&#xff0c;根据与另一个表的区别&#xff0c;在一个表中插入、更新或删除行&#xff0c;从而同步两个表。 MERGE 语句允许将数据源与目标…

【Vue】插值表达式 {{ }}

一、引入 插值表达式是一种Vue的模板语法 我们可以用插值表达式渲染出Vue提供的数据 作用&#xff1a;利用表达式进行插值&#xff0c;渲染到页面中 表达式&#xff1a;是可以被求值的代码&#xff0c;JS引擎会将其计算出一个结果 以下的情况都是表达式&#xff1a; money…

网络安全-钓鱼篇-利用cs进行钓鱼

一、环境 自行搭建&#xff0c;kill&#xff0c;Windows10&#xff0c;cs 二、原理 如图所示 三、钓鱼演示 首先第一步&#xff1a;打开System Profiler-分析器功能 选择克隆www.baidu.com页面做钓鱼 之后我们通过包装域名&#xff0c;各种手段让攻击对象访问&#xff1a;h…

硬盘有EFI分区格式化不了,也删不了怎么办,不能读取磁盘

问题&#xff1a;EFI为系统引导分区表明这是一块系统盘&#xff0c;常规操作无法格式化也无法删除&#xff0c;也不能读取 解决&#xff1a; 1.管理员运行cmd 2.输入diskpart 3.输入list disk 查看系统磁盘&#xff0c;并找到你格式化不了的那块磁盘 4.select disk 编号 选择…

动手学操作系统(一、搭建实验环境)

动手学操作系统&#xff08;一、搭建实验环境&#xff09; 文章目录 动手学操作系统&#xff08;一、搭建实验环境&#xff09;1. 在VMware虚拟机中安装ubuntu20.042. 安装Bochs3. 启动计算机Reference &#x1f680; 环境配置 &#x1f680; 笔者的环境使用的是 ubuntu 20.04…

学习sam的过程

一、抓包 我平时都是用花瓶去抓包的&#xff0c;配置也很简单。就是下载软件&#xff0c;然后一步步安装。下载地址&#xff1a;Download a Free Trial of Charles • Charles Web Debugging Proxy 。然后配置手机代理 对于那些走http协议的app是可以的&#xff0c;https的还是…

Linux 系统编程笔记--基本概念(一)

操作系统&#xff1a; 管理计算机硬件和软件资源的计算机程序。 内核&#xff1a; 操作系统的核心&#xff0c;是应用程序连接硬件设备的桥梁。 CPU 可以在两种状态下运行:用户态和内核态&#xff0c;在用户态下运行时&#xff0c;CPU 只能访问用户空间的内存;在内核态运行时&…

kafka-守护启动

文章目录 1、kafka守护启动1.1、先启动zookeeper1.1.1、查看 zookeeper-server-start.sh 的地址1.1.2、查看 zookeeper.properties 的地址 1.2、查看 jps -l1.3、再启动kafka1.3.1、查看 kafka-server-start.sh 地址1.3.2、查看 server.properties 地址 1.4、再次查看 jps -l 1…

【数据分享】2017-2023年全球范围10米精度土地覆盖数据

土地覆盖数据是我们在各项研究中都非常常用的数据&#xff0c;土地覆盖数据的来源也有很多。之前我们分享过欧空局发布的2020年和2021年的10米分辨率的土地覆盖数据,也分享过我国首套1米分辨率的土地覆盖数据&#xff08;均可查看之前的文章获悉详情&#xff09;&#xff01; …

Kunpeng Pro测评使用报告

1. 概述 前段时间&#xff0c;收到两条CSDN的短信&#xff0c;邀请我参加Kunpeng Pro的测评活动。说起来&#xff0c;自己玩过的开发板已经不在少数&#xff0c;而自己作为半导体行业的从业者&#xff0c;手上开发过的芯片也有十几款&#xff0c;小到Arm Cortex-A53&#xff0…

老年人健康管理系统项目部署【linux】

老年人健康管理系统项目部署【linux】 前言版权推荐老年人健康管理系统项目部署购买阿里云服务器开发票连接开放端口 安装软件查看状态1更新yum源2安装jdk83安装mysql4上传Mysql数据5安装redis6安装kakfa7安装nginx8运行命令 命令汇总1更新yum源2Jdk8安装3Mysql安装4Mysql数据5…

SpringBoot——集成Spring Data JPA保存数据

目录 JPA 项目总结 新建一个SpringBoot项目 pom.xml application.properties配置文件 User实体类 UserRepository接口 SpringbootJpaApplicationTests测试类 测试 JPA 项目在运行过程中会产生很多业务数据&#xff0c;一般我们把数据保存起来的这个过程称为数据持久化。…

【C++】牛客——JZ38 字符串的排列

✨题目链接&#xff1a; JZ38 字符串的排列 ✨题目描述 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数…