普中51单片机学习(EEPROM)

news2024/11/17 15:54:05

EEPROM

IIC串行总线的组成及工作原理

I2C总线的数据传送
  1. 数据位的有效性规定

I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
在这里插入图片描述

  1. 起始和终止信号

SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
在这里插入图片描述

  1. 数据传送格式
    字节传送与应答
    每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。
    在这里插入图片描述
    数据帧格式
    在总线的一次数据传送过程中,可以有以下几种组合方式:
    主机向从机发送数据,数据传送方向在整个传送过程中不变:
    在这里插入图片描述
    主机在第一个字节后,立即从从机读数据:
    在这里插入图片描述
    在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次,但两次读/写方向位正好反相。
    在这里插入图片描述

  2. 总线的寻址
    I2C总线协议有明确的规定:采用7位的寻址字节(寻址字节是起始信号后的第一个字节)。
    寻址字节的位定义
    在这里插入图片描述
    主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据R/T位将自己确定为发送器或接收器。
    从机的地址由固定部分和可编程部分组成。在一个系统中可能希望接入多个相同的从机,从机地址中可编程部分决定了可接入总线该类器件的最大数目。如一个从机的7位寻址位有4位是固定位,3位是可编程位,这时仅能寻址8个同样的器件,即可以有8个同样的器件接入到该I2C总线系统中。

典型信号模拟
在这里插入图片描述

串行E2PROM的扩展

写入过程

单片机进行写操作时,首先发送该器件的7位地址码和写方向位“0”(共8位,即一个字节),发送完后释放SDA线并在SCL线上产生第9个时钟信号。被选中的存储器器件在确认是自己的地址后,在SDA线上产生一个应答信号作为相应,单片机收到应答后就可以传送数据了。传送数据时,单片机首先发送一个字节的被写入器件的存储区的首地址,收到存储器器件的应答后,单片机就逐个发送各数据字节,但每发送一个字节后都要等待应答。当要写入的数据传送完后,单片机应发出终止信号以结束写入操作。写入n个字节的数据格式 :
在这里插入图片描述

读出过程

单片机先发送该器件的7位地址码和写方向位“0”(“伪写”),发送完后释放SDA线并在SCL线上产生第9个时钟信号。被选中的存储器器件在确认是自己的地址后,在SDA线上产生一个应答信号作为回应。然后,再发一个字节的要读出器件的存储区的首地址,收到应答后,单片机要重复一次起始信号并发出器件地址和读方向位(“1”),收到器件应答后就可以读出数据字节,每读出一个字节,单片机都要回复应答信号。当最后一个字节数据读完后,单片机应返回以“非应答”(高电平),并发出终止信号以结束读出操作。
在这里插入图片描述

AT24CXX存储器工作原理

在这里插入图片描述
总线时序
在这里插入图片描述
在这里插入图片描述

实验代码

i2c.h

#ifndef _I2C_H
#define _I2C_H

#include "reg52.h"
sbit SCL=P2^1;
sbit SDA=P2^0;
void At24c02Write(unsigned char addr, unsigned char dat);
unsigned char At24c02Read(unsigned char addr);

#endif

i2c.c

#include "i2c.h"

void Delay10us(void)
{
	unsigned char a,b;
	for(b=1;b>0;b--)
		for(a=2;a>0;a--);
}

void I2cStart()
{
	SDA=1;
	Delay10us();
	SCL=1;
	Delay10us();
	SDA=0;
	Delay10us();
	SCL=0;
	Delay10us();
}

void I2cStop()
{
	SDA=0;
	Delay10us();
	SCL=1;
	Delay10us();
	SDA=1;
	Delay10us();
}

unsigned char I2cSendByte(unsigned char dat)
{
	unsigned char a;
	unsigned char t=1;
	unsigned char b=1;
	for(a=0;a<8;a++)
	{
		SDA=dat>>7;
		dat<<=1;
		Delay10us();
		SCL=1;
		Delay10us();
		SCL=0;
		Delay10us();
	}
	SDA=1;
	Delay10us();
	SCL=1;
	Delay10us();
	while(SDA)
	{
		b++;
		if(b>200)
		{
			SCL=0;	
			Delay10us();
			t=0;
			return b;
		}
	}
	SCL=0;
	Delay10us();
	return t;
}

unsigned char I2cReadByte()
{
	unsigned char a=0,dat=0;
	SDA=1;
	Delay10us();
	for(a=0;a<8;a++)
	{
		SCL=1;
		Delay10us();
		dat<<=1;
		dat|=SDA;
		Delay10us();
		SCL=0;
		Delay10us();
	}
	return dat;
}

void At24c02Write(unsigned char addr, unsigned char dat)
{
	I2cStart();
	I2cSendByte(0xA0);
	I2cSendByte(addr);
	I2cSendByte(dat);
	I2cStop();
}

unsigned char At24c02Read(unsigned char addr)
{
	unsigned char num;
	I2cStart();
	I2cSendByte(0xA0);
	I2cSendByte(addr);
	I2cStart();
	I2cSendByte(0xA1);
	num=I2cReadByte();
	I2cStop();
	return num;	
}

main.c

#include "reg52.h"
#include "i2c.h"
typedef unsigned char u8;
typedef unsigned int u16;

sbit k1=P3^1;
sbit k2=P3^0;
sbit k3=P3^2;
sbit k4=P3^3;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;

u8 code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
u8 num=0;
u8 disp[4];
void delay(u16 i)
{
	while(i--);
}

void datapros()
{
	disp[0]=smgduan[num/1000];
	disp[1]=smgduan[num/100%10];
	disp[2]=smgduan[num/10%100%10];
	disp[3]=smgduan[num%1000%100%10];
}


void Keypros()
{
	if(k1==0)
	{
		delay(1000);
		if(k1==0)
		{
			At24c02Write(1,num);
		}
		while(!k1);
	}
	if(k2==0)
	{
		delay(1000);
		if(k2==0)
		{
			num=At24c02Read(1);
		}
		while(!k2);
	}
	if(k3==0)
	{
		delay(1000);
		if(k3==0)
		{
			num++;
			if(num>255)
			{
				num=0;
			}
		}
		while(!k3);
	}
	if(k4==0)
	{
		delay(1000);
		if(k4==0)
		{
			num=0;
		}
		while(!k4);
	}
}

void DigDisplay()
{
	u8 i;
	for(i=0;i<4;i++)
	{
		switch(i)
		{
			case(0):
				LSA=0;LSB=0;LSC=0;break;
			case(1):
				LSA=1;LSB=0;LSC=0;break;
			case(2):
				LSA=0;LSB=1;LSC=0;break;
			case(3):
				LSA=1;LSB=1;LSC=0;break;
		}
		P0=disp[3-i];
		delay(100);
		P0=0x00;
	}
}


void main(){

	while(1)
	{
		Keypros();
		datapros();
		DigDisplay();
	}
}


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

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

相关文章

【Java 基础】Java 数组、方法极致精讲

《Java 零基础入门到精通》专栏持续更新中。通过本专栏你将学习到 Java 从入门到进阶再到实战的全套完整内容,所有内容均将集中于此专栏。无论是初学者还是有经验的开发人员,都可从本专栏获益。 订阅专栏后添加我微信或者进交流群,进群可找我领取 前端/Java/大数据/Python/低…

从0到1使用C++实现一个模拟器-1-【实现最简CPU】

文章目录 uint64_tstdstd::arrayCPU和CU类构造函数size_tstatic_caststd::ifstreamriscv64-unknown-elf-objcopy -O binary add-addi add-addi.binriscv64-unknown-elf-gcc -Wl,-Ttext0x0 -nostdlib -o add-addi add-addi.s-wlstd::hex std::setw() std::setfill()各自的用法he…

upload-Labs靶场“1-5”关通关教程

君衍. 一、环境搭建二、第一关 前端JS检测后缀1、源码分析2、禁用浏览器JS上传3、burp抓包修改 三、第二关 MIME头验证1、源码分析2、burp抓包绕过 四、第三关 PHP3绕过1、源码分析2、PHP3绕过 五、第四关 .htaccess重写绕过1、源码分析2、.htaccess复写 六、第五关 黑名单大小…

Qt槽函数不响应的原因总结

Qt专栏&#xff1a;http://t.csdnimg.cn/LE2Lx 目录 1.问题 2.原因 2.1.没有继承QObject&#xff0c;声明Q_OBJECT宏 2.2.信号槽参数不匹配 2.3.信号函数未声明为 signals 2.4.访问权限 2.5.注意connect的位置&#xff0c;信号在创建信号槽连接前使用&#xff0c;则无法…

C#使用iText7将多个PDF文档合并为单个文档

使用HtmlAgilityPack抓取并分析网页内容&#xff0c;然后再调用PuppeteerSharp将网页生成PDF文件&#xff0c;最终的成果如下图所示&#xff0c;得到将近120个pdf文档。能看&#xff0c;但是不方便&#xff0c;需要逐个打开文档才能看到所需的内容&#xff0c;最好能将这些文档…

java 企业培训管理系统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 java 企业培训管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&…

Vulnhub靶机:basic_pentesting_2

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.4&#xff09; 靶机&#xff1a;basic_pentesting_2&#xff08;10.0.2.7&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnhub.c…

未来已来:智慧餐饮点餐系统引领餐饮业的数字化转型

时下&#xff0c;智慧餐饮点餐系统正在引领着餐饮业迈向更高的位置。今天&#xff0c;小编将与大家共同探讨智慧餐饮点餐系统的发展趋势、优势以及对餐饮业的影响。 一、智慧餐饮点餐系统的发展趋势 智慧餐饮点餐系统的出现填补了这一空白&#xff0c;它通过引入数字化技术&a…

基于springboot+vue的医院资源管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

IDEA-DeBug理论与实践

文章目录 01_Debug简介和意义02_IDEA中的Debug步骤03_跳转到当前代码执行的行04_步过调试的使用05_步入调试的使用06_强制步入调试的使用07_步出调试的使用08_回退断点调试的使用09_运行到光标处10_计算表达式11_条件断点12_多线程调试 在软件开发中&#xff0c;IDEA&#xff0…

让燃油车再次破防 比亚迪汉唐荣耀双出击

相信很多读者朋友都还记得&#xff0c;就在不久前趣味科技曾经报道&#xff0c;2024龙年伊始比亚迪就打着“电比油低”的旗号&#xff0c;推出了价格仅为7.98万元起的秦PLUS、驱逐舰05荣耀版&#xff0c;向合资燃油车发起了大举进攻。 这两款“7”字头售价的车型上市&#xff0…

<网络安全>《60 概念讲解<第七课 网络模型OSI对应协议>》

1 OSI模型 OSI模型&#xff08;Open Systems Interconnection Model&#xff09;是一个由国际标准化组织&#xff08;ISO&#xff09;提出的概念模型&#xff0c;用于描述和标准化电信或计算系统的通信功能&#xff0c;以实现不同通信系统之间的互操作性。该模型将通信系统划分…

智能驾驶规划控制理论学习-基于采样的规划方法

目录 一、基于采样的规划方法概述 二、概率路图&#xff08;PRM&#xff09; 1、核心思想 2、实现流程 3、算法描述 4、节点连接处理 5、总结 三、快速搜索随机树&#xff08;RRT&#xff09; 1、核心思想 2、实现流程 3、总结 4、改进RRT算法 ①快速搜索随机图&a…

每日一类:QString类深入讲解

QString类是Qt框架中的一个核心组件&#xff0c;设计用于方便、高效地处理Unicode字符串。与标准C中的字符串处理方式相比&#xff0c;QString提供了更为丰富的API&#xff0c;支持国际化&#xff0c;并且内部使用UTF-16编码&#xff0c;能够处理世界上几乎所有的语言文字。 设…

Python图像形态学处理:腐蚀、膨胀、礼帽、黑帽……

文章目录 二值形态学灰度形态学 python图像处理教程&#xff1a;初步&#x1f4f7;插值变换 最基础的形态学操作有四个&#xff0c;分别是腐蚀、膨胀、开计算和闭计算&#xff0c;【scipy.ndimage】分别实现了二值数组和灰度数组的这四种运算。而针对灰度图像&#xff0c;【sc…

android路由表APP,携程Android面试题

大家应该看过很多分享面试成功的经验&#xff0c;但根据幸存者偏差的理论&#xff0c;也许多看看别人面试失败在哪里&#xff0c;对自己才更有帮助。 最近跟一个朋友聊天&#xff0c;他准备了几个月&#xff0c;刚刚参加完字节跳动面试&#xff0c;第二面结束后&#xff0c;嗯&…

(案例贴2) html+css 倒计时器

欢迎大家使用这个计时器噢 老哥直接附代码咯. timer.html <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…

python 小游戏《2048》字符版非图形界面

参考链接&#xff1a; 闲谈2048小游戏和数组的旋转及翻转和转置 目录 2048 一、方阵类 二、随机插入1或2 三、 合并和递增 四、 判断和移动 五、 键盘控制 完整源代码 玩法过程 2048 上回说到2048小游戏中数组的各种旋转、翻转的方法&#xff0c;就是为代码编程作准…

非阻塞实现高效键盘扫描功能(STM32F4XX)

目录 概述 1 原理分析 1.1 技术背景 1.2 系统硬件 1.3 STM32 IO&#xff08;输入模式&#xff09;寄存器分析 1.3.1 输入IO的功能描述 1.3.2 输入配置 1.3.3 GPIO 寄存器&#xff08;输入模式相关&#xff09; 1.3.3.1 GPIO 端口模式寄存器 1.3.3.2 GPIO 端口上拉/下拉…

VUE3自定义文章排行榜的简单界面

文章目录 一、代码展示二、代码解读三、结果展示 一、代码展示 <template><div class"article-ranking"><div class"header"><h2 class"title">{{ title }}</h2></div><div class"ranking-list&qu…