Proteus8仿真:51单片机25AA020A(SPI接口EEPROM)的使用

news2024/12/25 13:15:47

51单片机25AA020A

  • 实验内容
  • 25AA020A引脚功能
  • SPI信号模拟
    • 8位写
    • 8位读
  • EEPROM读写函数
    • EEPROM写使能
    • EEPROM写一个Byte
  • 实验程序例程
    • main.c
  • 工程文件

Microchip的25AA020A是一个2Kbit串行电可擦除可编程只读存储器(EEPROM)。内存可以通过一个简单的串行外围接口(SPI)兼容的串行总线来访问。所需的总线信号是时钟输入(SCK)加上独立的数据(SI)和数据输出(SO)线。通过芯片选择(CS)输入来控制对设备的访问。

实验内容

实验内容

使用25AA020A完成对计数器的计数值的保存。

实验原理图
在这里插入图片描述
实验器件

元器件名称
51单片机AT89C51
按键BUTTON
数码管7SEG-BCD-BLUE
EEPROM25AA020A

25AA020A引脚功能

在这里插入图片描述

引脚功能
SCKSPI时钟
SISPI的MOSI(主机输出从机输入)
SOSPI的MISO(主机输入从机输出)
SCKSPI时钟
CSSPI的片选信号
WP读写保护位
HOLD暂停传输信号,拉高保证连续传输

SPI信号模拟

8位写

在这里插入图片描述

/**********************************************************************************************************************************
作用:SPI一个Byte写入函数
Byte:要写入的Byte
从高位往低位,上升沿传输

**********************************************************************************************************************************/
void SPI_WriteByte(uint_8 Byte)
{
	uint_8 i=0;
	for(i=0;i<8;i++)
	{
		SCK=0;
		if(Byte&0x80)SI=1;
		else SI=0;
		Byte <<=1;
		SCK=1;
	}
	SCK=0;
}

8位读

在这里插入图片描述

/**********************************************************************************************************************************
作用:SPI一个Byte读取函数
返回:读取的一个Byte
从高位往低位,下降沿传输
**********************************************************************************************************************************/

uint_8 SPI_ReadByte(void)
{
	uint_8 i;
	uint_8 Byte;
	SCK=0;
	for(i=0;i<8;i++)
	{
		SCK=1;
		Byte <<=1;
		if(SO)Byte++;
		SCK=0;
	}
	return Byte;
}

EEPROM读写函数

EEPROM写使能

在这里插入图片描述

/**********************************************************************************************************************************
作用:EEPROM写使能

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

void EEPROM_WriteData_ENABLE(void)
{
	CS=1;
	CS=0;
	SPI_WriteByte(EEPROM_Address_ENABLE);
	CS=1;
}

在这里插入图片描述

/**********************************************************************************************************************************
作用:EEPROM写不使能
**********************************************************************************************************************************/
void EEPROM_WriteData_DISENABLE(void)
{
	CS=1;
	CS=0;
	SPI_WriteByte(EEPROM_Address_DISABLE);
	CS=1;
}

EEPROM写一个Byte

在这里插入图片描述
在任何尝试将数据写入25AA020A之前,写启用锁必须通过发WREN来设置使用说明。这是通过设置CS较低来实现的然后把正确的指令输入到25AA020A.在所有的八位指令之后传输时,CS必须驱动到高才能设置写入启用锁存器。如果在没有CS驱动的高的情况下,在WREN指令后立即启动写操作,数据自写入后将不会被写入数组启用锁存器没有正确设置。

/**********************************************************************************************************************************
作用:EEPROM写入一个Byte函数
HW_Address:EEPROM硬件地址
SW_Address:EEPROM软件地址即写出内存的地址
Data:写入的数据

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

void EEPROM_WriteData(uint_8 HW_Address,uint_8 SW_Address,uint_8 Data)
{
	uint_8 status=0x01;
	//打开EEPROM写使能
	EEPROM_WriteData_ENABLE();
	CS=1;
	CS=0;
	SPI_WriteByte(HW_Address);
	SPI_WriteByte(SW_Address);
	SPI_WriteByte(Data);
	CS=1;
	//读取EEPROM寄存器
	//从寄存器最低位判断写是否完成
	while((status&0x01)==0x01)
	{
		CS=1;
		CS=0;
		SPI_WriteByte(EEPROM_Address_Read_REGISTER);
		status=SPI_ReadByte();	
		CS=1;		
	}
	//关闭EEPROM写使能
	EEPROM_WriteData_DISENABLE();
}

实验程序例程

main.c

#include "REG51.h"

sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit SCK=P3^0;
sbit SI=P3^1;
sbit SO=P3^2;
sbit CS=P3^3;

#define EEPROM_Address_W 0X02
#define EEPROM_Address_R 0X03
#define EEPROM_Address_ENABLE 0X06
#define EEPROM_Address_DISABLE 0X04
#define EEPROM_Address_Read_REGISTER 0x05

typedef unsigned char uint_8;
typedef unsigned int uint_16;

void SPI_WriteByte(uint_8 Byte);
uint_8 SPI_ReadByte(void);

void EEPROM_WriteData(uint_8 HW_Address,uint_8 SW_Address,uint_8 Data);
uint_8 EEPROM_ReadData(uint_8 HW_Address,uint_8 SW_Address);
void EEPROM_WriteData_ENABLE(void);


void get_key(void);
void SMG_output(uint_8 Data);
char num=5;

void main(void)
{
	num=EEPROM_ReadData(EEPROM_Address_R,0x00);
	while(1)
	{
		SMG_output(num);
		EEPROM_WriteData(EEPROM_Address_W,0x00,num);
		get_key();	
	}
}

/**********************************************************************************************************************************
作用:EEPROM写使能

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

void EEPROM_WriteData_ENABLE(void)
{
	CS=1;
	CS=0;
	SPI_WriteByte(EEPROM_Address_ENABLE);
	CS=1;
}

/**********************************************************************************************************************************
作用:EEPROM写不使能
**********************************************************************************************************************************/
void EEPROM_WriteData_DISENABLE(void)
{
	CS=1;
	CS=0;
	SPI_WriteByte(EEPROM_Address_DISABLE);
	CS=1;
}

/**********************************************************************************************************************************
作用:SPI一个Byte写入函数
Byte:要写入的Byte
从高位往低位,上升沿传输

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

uint_8 EEPROM_ReadData(uint_8 HW_Address,uint_8 SW_Address)
{
	uint_8 Data=0;
	CS=1;
	CS=0;
	SPI_WriteByte(HW_Address);
	SPI_WriteByte(SW_Address);
	Data=SPI_ReadByte();
	CS=1;
	return Data;
}

/**********************************************************************************************************************************
作用:EEPROM写入一个Byte函数
HW_Address:EEPROM硬件地址
SW_Address:EEPROM软件地址即写出内存的地址
Data:写入的数据

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

void EEPROM_WriteData(uint_8 HW_Address,uint_8 SW_Address,uint_8 Data)
{
	uint_8 status=0x01;
	//打开EEPROM写使能
	EEPROM_WriteData_ENABLE();
	CS=1;
	CS=0;
	SPI_WriteByte(HW_Address);
	SPI_WriteByte(SW_Address);
	SPI_WriteByte(Data);
	CS=1;
	//读取EEPROM寄存器
	//从寄存器最低位判断写是否完成
	while((status&0x01)==0x01)
	{
		CS=1;
		CS=0;
		SPI_WriteByte(EEPROM_Address_Read_REGISTER);
		status=SPI_ReadByte();	
		CS=1;		
	}
	//关闭EEPROM写使能
	EEPROM_WriteData_DISENABLE();
}

/**********************************************************************************************************************************
作用:SPI一个Byte读取函数
返回:读取的一个Byte
从高位往低位,下降沿传输
**********************************************************************************************************************************/

uint_8 SPI_ReadByte(void)
{
	uint_8 i;
	uint_8 Byte;
	SCK=0;
	for(i=0;i<8;i++)
	{
		SCK=1;
		Byte <<=1;
		if(SO)Byte++;
		SCK=0;
	}
	return Byte;
}

/**********************************************************************************************************************************
作用:SPI一个Byte写入函数
Byte:要写入的Byte
从高位往低位,上升沿传输

**********************************************************************************************************************************/
void SPI_WriteByte(uint_8 Byte)
{
	uint_8 i=0;
	for(i=0;i<8;i++)
	{
		SCK=0;
		if(Byte&0x80)SI=1;
		else SI=0;
		Byte <<=1;
		SCK=1;
	}
	SCK=0;
}
/**********************************************************************************************************************************
作用:按键扫描

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

void get_key(void)
{
	if(KEY1==0)
	{
		num++;
		if(num>=9)num=9;
		while(KEY1==0);
	}
	else if(KEY2==0)
	{
		num--;
		if(num<=0)num=0;
		while(KEY2==0);		
	}
}
/**********************************************************************************************************************************
作用:数码管显示

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

void SMG_output(uint_8 Data)
{
	P2=Data&0x0F;
}


工程文件

工程文件+25AA020A官方文档

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

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

相关文章

第三十讲:神州路由器路由重分发配置

RIP和OSPF协议是目前应用最广泛的路由协议&#xff0c;两种协议交接的场合也很多见&#xff0c;两种协议的重分布是比较常见的配置。主校区原来所采用的网络协议为OSPF&#xff0c;而分校区采用的路由协议是RIP&#xff0c;采用RIP和OSPF重分发技术可以解决此问题。 实验拓扑图…

HDLBits练习汇总-14-时序逻辑设计测试--状态机(二)

水箱问题&#xff08;Exams/ece241 2013 q4&#xff09; 一个大水库的水为几个用户服务。为了保持足够高的水位&#xff0c;三个传感器以5英寸的间隔垂直放置。当水位高于最高传感器S3时&#xff0c;输入流量应为零。当液位低于最低传感器(Si)时&#xff0c;流量应处于最大(公…

【技术分享】戴尔工作站安装Win10+Ubuntu20.04双系统避坑指南

文章目录引言1.安装前的几个注意事项&#xff08;避坑指南&#xff09;1.1.有多块硬盘&#xff0c;该如何分配给Win10和Ubuntu系统&#xff1f;1.2.Ubuntu分区应该怎么分&#xff1f;2.系统安装步骤2.1.下载系统镜像2.2.制作U盘启动盘2.3.进入Win10系统分配系统空间2.4.BIOS设置…

82.【LibraryManger】

图书管理系统(一)、搭建环境1.数据库语句2.导入需要的依赖(二)、配置文件3.创建MyBatis的xml文件 mybais-config.xml4.创建dao层接口以及dao层的 mapper.xml5.创建数据库的资源 database.properties6.创建spring的配置文件 spring-dao.xml【】7.创建service层的接口以及servcie…

查找

章节目录&#xff1a;一、线性查找1.1 概述1.2 代码示例二、二分查找2.1 概述2.2 代码示例三、插值查找3.1 概述3.2 代码示例四、斐波那契查找4.1 概述4.2 代码示例五、结束语一、线性查找 1.1 概述 线性查找又称顺序查找&#xff0c;是一种最简单的查找方法&#xff0c;它的…

若依框架:前端登录组件与图像验证码|用户登录逻辑

在上一篇《若依框架&#xff1a;前端项目结构与初始页面渲染流程》中&#xff0c;我们探讨了与“vue.config.js文件配置、.env模式和环境变量配置、vue-router全局导航守卫配置、vue-router路由配置简介”相关的内容&#xff0c;书接上回&#xff0c;我们继续探讨若依前端项目的…

【C语言进阶】字符函数与字符串函数

目录 1、函数介绍 1.1 strlen 1.2 strcpy 1.3 strcat 1.4 strcmp 1.5 strncpy 1.6 strncat 1.7 strncmp 1.8 strstr 1.9 strtok 1.10 strerror 【补】字符分类函数&#xff1a; 1.11 memcpy 1.12 memmove 1.13 memcmp 1.14 memset 1、函数介绍 1.1 strlen siz…

基于卷积神经网络的高光谱分类(1D、2D、3D-CNN)

算法原理 卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;CNN&#xff09;是深度学习中最常见的一种 算法&#xff0c;它具有强大的特征学习能力。CNN 通过结合局部感知区域、共享权重、空间或者 时间上的降采样来充分利用数据本身包含的局部性等特征&…

绘图仪 与 示波器 Plotter Oscilloscope

【后台管理&#xff0c;这哪里是广告了&#xff1f;图都是百度搜的&#xff0c;又没有销售信息&#xff0c;就事论事而已&#xff01;】 Plotter &#xff1a; 对低频信号持续测量并绘制到一张很长的纸上&#xff0c;通常是卷纸。 常见的比如传统心电图机&#xff08;图左&am…

『分分钟玩转VueRouter●下』我对VueRouter在项目中如何使用的理解

路由的设置会根据系统中用户角色的数量而有所不同&#xff0c;大致分为三种单角色同权限、单角色不同权限、多角色。这里的角色均是只一种身份&#xff0c;而不是用户量。接下来的讲解纯属个人见解&#xff0c;大型项目会将不同权限的用户直接分开开发不同的系统。如果是小型多…

c++基础——for循环

for循环是循环的一种 以下是 for 循环的结构&#xff1a; for (初始化; 判断条件; 更新) {循环体; } 执行顺序&#xff1a; for 语句的三个部分中&#xff0c;任何一个部分都可以省略。其中&#xff0c;若省略了判断条件&#xff0c;相当于判断条件永远为真。 for (int i …

fpga实操训练(从模块到系统开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们学习了fpga的一些基本操作&#xff0c;熟悉了这些操作&#xff0c;基本上说fpga已经入门了。但是距离我们用fpga开发产品&#xff0c;这中…

Faster RCNN网络源码解读(Ⅷ) --- RPN网络代码解析(下)RegionProposalNetwork类解析

目录 一、代码作用&#xff08;rpn_function.py&#xff09; 二、代码解析 2.1 RegionProposalNetwork类 2.1.1 正向传播过程forward 接着上篇博客的2.1.2节 2.1.2 assign_targets_to_anchors 2.1.3 det_utils.Matcher传入参数 2.1.4 compute_loss 2.1.5 smooth_l1_lo…

你真的会正确使用wait和notify么?

目录 wait和notify原理 API wait 与 sleep的区别 wait 和 notify的正确使用 step1 step2 step3 step4 step5 总结waitnotify wait和notify原理 当我们线程获取某个对象的monitor锁的时候就会成为owner线程,当owner线程条件不满足的时候,就会调用wait方法,该线程就会进…

惠州市政企信息化(互联网)市场调研报告

1.引言 1.1.编写目的 据广东省惠州市惠东县的政企信息化市场调研的客观性数据&#xff0c;分析相关数据&#xff0c;确定市场规模、市场潜力、市场需求&#xff0c;以及需求价值&#xff0c;为后续的市场决策、服务组合决策提供依据&#xff0c;也作为未来根据市场变化而调整…

Nacos 注册中心

Nacos 注册中心 目录概述需求&#xff1a;设计思路实现思路分析1.增加 Maven 依赖2.Client端配置注册中心3.Server端配置注册中心4.Nacos 注册中心参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c…

Java--Map接口详解

目录 Map接口的特点 代码实现 代码实现 Map的常用方法 代码实现 Map接口的4种遍历方法 代码实现 第一种方式 第二种方式 第三种方式 第四种方式 Map接口的特点 1)Map与Collection并列存在。用于保存具有映射关系的数据&#xff1a;Key-Value 2)Map中的key和value可以…

如何在星巴克连接家中Windows台式机?(安卓,iOS, Windows, macOS配合frp穿透公网IP实现)

zhaoolee 最近热衷于和海外热心老哥们交换硬盘中的单机游戏资源&#xff08;BT下载&#xff09;&#xff0c;家中有Windows台式机&#xff0c; 适合长时间挂机下载BT资源&#xff0c;zhaoolee希望能随时连接到Windows台式机新增下载任务&#xff0c;安装体积超大的主机游戏。 …

End-to-End Object Detection with Transformers论文阅读笔记

End-to-End Object Detection with Transformers 端到端&#xff0c;不需要NMS后处理了&#xff0c;直接出结果。 1、Abstract 将目标检测作为一个集合预测问题来解决。简化了检测的整体流程&#xff0c;有效的消除了许多人工设计的部分&#xff0c;比如NMS&#xff0c;anch…

数据库连接池(C++11实现)

目的&#xff1a; 因为对数据库的操作实质上是对磁盘的IO操作&#xff0c;所以如果对数据库访问次数过多&#xff0c;就会到导致大量的磁盘IO&#xff0c;为了提高MySQL数据库&#xff08;基于C/S设计&#xff09;的访问瓶颈&#xff0c;除了在服务器端增加缓存服务器缓存常用的…