(学习日记)2023.04.23

news2024/11/16 3:18:54

写在前面:
由于时间的不足与学习的碎片化,写博客变得有些奢侈。
但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。
既然如此
不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录,记录笔者认为最通俗、最有帮助的资料,并尽量总结几句话指明本质,以便于日后搜索起来更加容易。


标题的结构如下:“类型”:“知识点”——“简短的解释”
部分内容由于保密协议无法上传。


点击此处进入学习日记的总目录

2023.04.23

  • 一、元件:AT24C02——E2PROM存储器
  • 二、51:I2C总线
  • 三、51:AT24C02数据存储(I2C总线)
    • 1. 编写`I2C总线`函数
    • 2. 编写`AT24C02数据存储`函数
    • 3. 编写`main`函数

一、元件:AT24C02——E2PROM存储器

  1. 存储器介绍
    在这里插入图片描述
    在这里插入图片描述

详细可看计算机三级嵌入式系统开发 知识点笔记

  1. AT24C02介绍
    在这里插入图片描述
  2. 引脚及应用电路(SCL、SDA需要上拉电阻)
    在这里插入图片描述

(此处写保护为高电平有效,但我用的是低电平有效的存储器)

  1. 内部结构框图
    在这里插入图片描述

二、51:I2C总线

  1. I2C总线介绍
    在这里插入图片描述

详细可看计算机三级嵌入式系统开发 知识点笔记
在这里插入图片描述

  1. I2C电路规范
    在这里插入图片描述

上拉电阻
将一个不确定的信号(高或低电平),通过一个电阻与电源VCC相连,固定在高电平。
一般说法是上拉增大电流,下拉电阻是用来吸收电流。
在这里插入图片描述
上拉电阻阻值的选择原则:
1、从节约功耗及芯片的灌电流能力考虑应当足够大;电阻大,电流小。
2、从确保足够的驱动电流考虑应当足够小;电阻小,电流大。
3、对于高速电路,过大的上拉电阻可能边沿变平缓。
综合考虑以上三点,通常在 1K 到 10K 之间选取。对下拉电阻也是类似道理。

开漏输出(Open Drain Output)
常说的与推挽输出相对的就是开漏输出,对于开漏输出和推挽输出的区别最普遍的说法就是开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动。
在这里插入图片描述

  1. I2C时序结构
    在这里插入图片描述
    起始条件触发后,SCL开始产生时钟信号
    在这里插入图片描述
    SDA发送一个二进制,SCL拉高一次
    如果在SCL低电平切换SDA,不会有任何影响
    在这里插入图片描述
    和发送相同,不过拉高SCL和放置SDA的变成了从机
    在这里插入图片描述
    主机发送字节后,从机在下一时钟发送应答
    主机接收字节后,主机在下一时钟发送应答

  2. I2C数据帧
    在这里插入图片描述
    第一个字节中前7位为地址,第8位为读取或写入(1是read,0是write),如果器件只有A0~A2三个引脚,那么A3~A6为固定位(查手册)
    在这里插入图片描述
    如果在SCL低电平时切换SDA,认为触发了起始条件或终止条件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

三、51:AT24C02数据存储(I2C总线)

1. 编写I2C总线函数

  1. 寻找I2C对应引脚,很明显是P20P21
    在这里插入图片描述
sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;
  1. 编写I2C发送开始信号函数
/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void I2C_Start(void)
{
	I2C_SDA=1;
	I2C_SCL=1;
	I2C_SDA=0;
	I2C_SCL=0;
}
  • 将I2C总线的数据线(SDA)置为高电平(1)。
  • 将I2C总线的时钟线(SCL)置为高电平(1)。
  • 将I2C总线的数据线(SDA)置为低电平(0),表示发送开始信号。
  • 将I2C总线的时钟线(SCL)置为低电平(0),完成发送开始信号。

通过执行这段代码,可以在I2C总线上产生一个开始信号,该信号用于启动I2C通信过程。开始信号的形式是先将数据线(SDA)保持高电平,然后将时钟线(SCL)从高电平变为低电平,表示I2C通信的起始。

  1. 编写I2C发送停止信号函数
/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void I2C_Stop(void)
{
	I2C_SDA=0;
	I2C_SCL=1;
	I2C_SDA=1;
}
  • 将I2C总线的数据线(SDA)置为低电平(0)。
  • 将I2C总线的时钟线(SCL)置为高电平(1)。
  • 将I2C总线的数据线(SDA)置为高电平(1),表示发送停止信号。

通过执行这段代码,可以在I2C总线上产生一个停止信号,该信号用于结束I2C通信过程。停止信号的形式是先将数据线(SDA)变为低电平,然后将时钟线(SCL)从高电平变为低电平,最后将数据线(SDA)变为高电平,表示I2C通信的结束。停止信号通常用于表示一次完整的数据传输完成。

  1. 编写I2C发送一个字节数据函数
/**
  * @brief  I2C发送一个字节
  * @param  Byte 要发送的字节
  * @retval 无
  */
void I2C_SendByte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		I2C_SDA=Byte&(0x80>>i);
		I2C_SCL=1;
		I2C_SCL=0;
	}
}
  • 函数接受一个无符号字符类型的参数Byte,表示要发送的字节数据。
  • 进入一个循环,循环执行8次,每次发送一个bit的数据。
  • 在每次循环中,通过按位与操作(Byte & (0x80 >> i))来获取要发送的bit的值。
  • 将得到的bit值设置到I2C总线的数据线(SDA)上,通过将I2C_SDA变量赋值为该bit值。
  • 将I2C总线的时钟线(SCL)置为高电平(1),表示准备发送数据。
  • 然后将I2C总线的时钟线(SCL)置为低电平(0),完成一个bit的发送。
  • 循环结束后,函数完成了一个字节数据的发送。

该函数用于通过I2C总线发送数据时,通过连续发送8个bit来传输一个字节数据。具体的工作流程是根据要发送的字节数据,按位设置I2C总线的数据线(SDA)的状态,并通过控制I2C总线的时钟线(SCL)来实现数据的发送。

  1. 编写I2C接收一个字节数据函数
/**
  * @brief  I2C接收一个字节
  * @param  无
  * @retval 接收到的一个字节数据
  */
unsigned char I2C_ReceiveByte(void)
{
	unsigned char i,Byte=0x00;
	I2C_SDA=1;
	for(i=0;i<8;i++)
	{
		I2C_SCL=1;
		if(I2C_SDA){Byte|=(0x80>>i);}
		I2C_SCL=0;
	}
	return Byte;
}
  • 首先声明了一个无符号字符类型的变量iByte,并将Byte初始化为0x00,用于存储接收到的字节数据。
  • 将I2C总线的数据线(SDA)置为高电平(1),表示准备接收数据。
  • 进入一个循环,循环执行8次,每次接收一个bit的数据。
  • 在每次循环中,首先将I2C总线的时钟线(SCL)置为高电平(1),表示准备接收数据。
  • 然后通过判断I2C总线的数据线(SDA)的状态,来确定接收到的bit是0还是1。如果SDA为高电平,则将对应的bit位置为1(Byte的对应bit位根据循环次数递减),如果SDA为低电平,则对应的bit位置为0。
  • 最后,将I2C总线的时钟线(SCL)置为低电平(0),完成一个bit的接收。
  • 循环结束后,函数返回接收到的一个字节数据(Byte)。

该函数用于从I2C总线接收数据时,通过连续接收8个bit来组成一个字节数据。具体的工作流程是根据I2C总线的时钟和数据线状态来逐位接收数据,并将其组装成一个完整的字节数据。

  1. 编写I2C发送应答信号函数
/**
  * @brief  I2C发送应答
  * @param  AckBit 应答位,0为应答,1为非应答
  * @retval 无
  */
void I2C_SendAck(unsigned char AckBit)
{
	I2C_SDA=AckBit;
	I2C_SCL=1;
	I2C_SCL=0;
}
  • 将I2C总线的数据线(SDA)设置为应答位(AckBit),其中0表示应答,1表示非应答。
  • 将I2C总线的时钟线(SCL)置为高电平(1)。
  • 将I2C总线的时钟线(SCL)置为低电平(0),完成应答信号的发送。

通过执行这段代码,可以在I2C总线上发送应答信号,用于确认接收到的数据或指示拒绝接收数据。应答信号通常在主设备向从设备发送数据后,从设备进行响应,以指示是否成功接收数据。

  1. 编写I2C接收应答信号函数
/**
  * @brief  I2C接收应答位
  * @param  无
  * @retval 接收到的应答位,0为应答,1为非应答
  */
unsigned char I2C_ReceiveAck(void)
{
	unsigned char AckBit;
	I2C_SDA=1;
	I2C_SCL=1;
	AckBit=I2C_SDA;
	I2C_SCL=0;
	return AckBit;
}
  • 将I2C总线的数据线(SDA)置为高电平(1)。
  • 将I2C总线的时钟线(SCL)置为高电平(1)。
  • 将接收到的应答位(AckBit)设置为I2C总线的数据线(SDA)的状态。
  • 将I2C总线的时钟线(SCL)置为低电平(0),完成应答信号的接收。

通过执行这段代码,可以在I2C总线上接收从设备发送的应答信号,并将其作为函数的返回值返回。应答信号通常由从设备发送给主设备,用于确认接收到的数据或指示拒绝接收数据。函数返回的应答位为0表示应答,为1表示非应答。

2. 编写AT24C02数据存储函数

  1. 确定固定地址
    因为器件只有E0~E2三个引脚,那么E3~E6为固定位(1010)
    在这里插入图片描述

在这里插入图片描述

#define AT24C02_ADDRESS		0xA0
  1. 编写 向AT24C02芯片写入一个字节数据 的函数
/**
  * @brief  AT24C02写入一个字节
  * @param  WordAddress 要写入字节的地址
  * @param  Data 要写入的数据
  * @retval 无
  */
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	I2C_SendByte(Data);
	I2C_ReceiveAck();
	I2C_Stop();
}
  • 参数WordAddress表示要写入字节的地址。
  • 参数Data表示要写入的数据。
  • 函数首先发送开始信号(I2C_Start()),然后发送AT24C02芯片的地址(AT24C02_ADDRESS)并接收应答信号(I2C_ReceiveAck())。
  • 接下来,发送要写入的字节的地址(WordAddress)并接收应答信号。
  • 最后,发送要写入的数据(Data)并接收应答信号。
  • 最后发送停止信号(I2C_Stop())结束通信。
  1. 编写 从AT24C02芯片读取一个字节数据 的函数
/**
  * @brief  AT24C02读取一个字节
  * @param  WordAddress 要读出字节的地址
  * @retval 读出的数据
  */
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{
	unsigned char Data;
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS|0x01);
	I2C_ReceiveAck();
	Data=I2C_ReceiveByte();
	I2C_SendAck(1);
	I2C_Stop();
	return Data;
}
  • 参数WordAddress表示要读取字节的地址。
  • 函数首先发送开始信号(I2C_Start()),然后发送AT24C02芯片的地址(AT24C02_ADDRESS)并接收应答信号。
  • 接下来,发送要读取的字节的地址(WordAddress)并接收应答信号。
  • 然后再次发送开始信号,发送AT24C02芯片地址的读取位(AT24C02_ADDRESS | 0x01)并接收应答信号。
  • 接下来,从AT24C02芯片读取一个字节数据(Data = I2C_ReceiveByte())。
  • 最后发送非应答信号(I2C_SendAck(1))表示读取结束,并发送停止信号(I2C_Stop())结束通信。
  • 函数返回读取到的数据。

3. 编写main函数

unsigned char KeyNum;
unsigned int Num;

void main()
{
	LCD_Init();
	LCD_ShowNum(1,1,Num,5);
	while(1)
	{
		KeyNum=Key();
		if(KeyNum==1)	//K1按键,Num自增
		{
			Num++;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==2)	//K2按键,Num自减
		{
			Num--;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==3)	//K3按键,向AT24C02写入数据
		{
			AT24C02_WriteByte(0,Num%256);
			Delay(5);
			AT24C02_WriteByte(1,Num/256);
			Delay(5);
			LCD_ShowString(2,1,"Write OK");
			Delay(1000);
			LCD_ShowString(2,1,"        ");
		}
		if(KeyNum==4)	//K4按键,从AT24C02读取数据
		{
			Num=AT24C02_ReadByte(0);
			Num|=AT24C02_ReadByte(1)<<8;
			LCD_ShowNum(1,1,Num,5);
			LCD_ShowString(2,1,"Read OK ");
			Delay(1000);
			LCD_ShowString(2,1,"        ");
		}
	}
}

main函数通过按键控制一个数字变量Num的增减以及与AT24C02 EEPROM芯片的读写操作。

下面是代码的执行流程:

  1. 首先,调用LCD_Init()函数初始化LCD显示器。
  2. 调用LCD_ShowNum()函数在LCD上显示Num的当前值。
  3. 进入一个无限循环,程序将不断检测按键状态。
  4. 使用Key()函数获取当前按下的按键编号,并将其存储在KeyNum变量中。
  5. 如果按下的是K1按键(KeyNum等于1),则将Num自增,并使用LCD_ShowNum()函数在LCD上显示更新后的Num的值。
  6. 如果按下的是K2按键(KeyNum等于2),则将Num自减,并使用LCD_ShowNum()函数在LCD上显示更新后的Num的值。
  7. 如果按下的是K3按键(KeyNum等于3),则将Num的低8位写入AT24C02的地址0,并将Num的高8位写入AT24C02的地址1。然后,在LCD上显示"Write OK"消息,并进行延迟等待一段时间后清除显示。
  8. 如果按下的是K4按键(KeyNum等于4),则从AT24C02的地址0读取一个字节,并将其存储在Num的低8位中,然后从地址1读取一个字节,并将其存储在Num的高8位中。最后,使用LCD_ShowNum()函数在LCD上显示读取到的Num的值,并显示"Read OK"消息,并进行延迟等待一段时间后清除显示。
  9. 回到步骤3,继续等待按键操作。

这段代码演示了如何使用按键控制一个变量的增减,并将该变量的值写入和从EEPROM芯片读取。

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

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

相关文章

实用可靠的安科瑞电动机保护控制器的应用

安科瑞 徐浩竣 江苏安科瑞电器制造有限公司 zx acrelxhj 摘要&#xff1a;介绍了一种新型电动机保护器&#xff0c;兼有电流、电压、过载、短路保护功能。它集电流型和电压型电动机保护器优点于一身&#xff0c;对电源欠电压、过电压、断相起闭锁作用&#xff0c;它结构简单…

【测试报告】个人博客系统自动化测试报告

文章目录 项目背景项目功能测试计划功能测试测试用例执行测试的操作步骤 自动化测试设计的模块、自动化运行的结果、问题定位的结果自动化测试优点 项目背景 对于一个程序员来说&#xff0c;定期整理总结并写博客是不可或缺的步骤&#xff0c;不管是对近期新掌握的技术或者是遇…

C# 读取json格式文件

读取json格式文件 安装 Newtonsoft.Json 程序集 1. 选择界面下方的【程序包管理器控制台】页面&#xff0c;输入安装指令 Install-Package Newtonsoft.Json 2. 安装完成后&#xff0c;请确保在代码文件的顶部包含以下 using 指令&#xff1a; using Newtonsoft.Json; 创建读…

GCC如何生成并调用静态库

一&#xff0c;简介 本文主要介绍如何使用gcc编译代码生成静态库&#xff0c;并调用静态库运行的操作步骤。 二&#xff0c;准备工作 使用add.c和main.c生成test可行性文件的流程图&#xff1a; add.c文件的内容&#xff1a; #include "add.h"int add(int a, i…

自学网络安全, 一般人我劝你还是算了吧

前言&#xff1a;自学我劝你还是算了&#xff0c;我为什么要劝你放弃我自己却不放弃呢&#xff1f;因为我不是一般人。。。 1.这是一条坚持的道路,三分钟的热情可以放弃往下看了. 2.多练多想,不要离开了教程什么都不会了.最好看完教程自己独立完成技术方面的开发. 3.有时多 …

【性能测试】Jenkins+Ant+Jmeter自动化框架的搭建思路

前言 前面讲了Jmeter在性能测试中的应用及扩展。随着测试的深入&#xff0c;我们发现在性能测试中也会遇到不少的重复工作。 比如某新兴业务处于上升阶段&#xff0c;需要在每个版本中&#xff0c;对某些新增接口进行性能测试&#xff0c;有时还需要在一天中的不同时段分别进行…

计算如何与实验结合发Science

理论计算与实验结合的研究已经成为TOP期刊中的主流方式。近日&#xff0c;上海交通大学种丽娜副教授一项关于质子交换膜水解槽阳极催化剂的研究成果在Science发表。该工作报道了一种由沸石甲基咪唑酯骨架&#xff08;Co-ZIF&#xff09;衍生并通过静电纺丝处理的镧和锰共掺杂的…

Python 修复共享内存问题和锁定共享资源问题

文章目录 使用 multiprocessing.Array() 在 Python 中使用共享内存解决多进程之间共享数据问题的解决方案 使用 multiprocessing.Lock() 锁定 Python 中的共享资源 本篇文章解释了多处理共享内存的不同方面&#xff0c;并演示了如何使用共享内存解决问题。 我们还将学习如何使用…

Axure教程—图片手风琴效果

本文将教大家如何用AXURE制作图片手风琴效果 一、效果介绍 如图&#xff1a; 预览地址&#xff1a;https://6nvnfm.axshare.com 下载地址&#xff1a;https://download.csdn.net/download/weixin_43516258/87847313?spm1001.2014.3001.5501 二、功能介绍 图片自动播放为手风…

MT4交易外汇平台有哪些优势?为何是外汇投资首选?

外汇市场上存在着各种各样的外汇交易商&#xff0c;但是很多的外汇交易商所选择的交易平台都是MT4交易外汇平台。作为全世界范围内使用最为广泛的交易平台&#xff0c;MT4交易外汇平台具有哪些优势&#xff0c;能够让外汇交易商和外汇投资者都选择使用。本文就来具体的聊聊&…

SQL中not in的一个坑

因not in 效率较低&#xff0c;在工作用一只用left join代替&#xff0c;在某一次查询使用了not in发现&#xff0c;结果为空&#xff0c;sql大致如下 select id from table1 where id not in (select id from table2)经过查询发现select id from table2里面的id有null值导致该…

司法大数据解决方案

2018年11月26日&#xff0c;司法部制定了《智慧监狱技术规范SFT0028-2018》并于2019年1月1日正式颁布实施&#xff0c;要求智慧监狱的建设应者眼于监狱工作实际&#xff0c;将物联网、云计算、大数据、人工智能等新一信息技术与监狱各项业务深度融合&#xff0c;形成标准规范科…

论文解读 | 基于改进点对特征的点云6D姿态估计

原创 | 文 BFT机器人 01 摘要 点对特征(PPF)方法已被证明是一种有效的杂波和遮挡下的姿态估计方法。 文章的改进方法主要包括: (1)一种基于奇偶规则求解封闭几何的法向的方法; (2)通过将体素网格划分为等效角度单元的有效降采样方法; (3)基于拟合点的验证步骤。在真实杂波数据集…

如何挖掘360下拉词,怎么删除360下拉负面词

大多数人的手机或者电脑上都安装了360浏览器&#xff0c;360搜索APP等&#xff0c;安装的用户量大&#xff0c;自然使用的用户也就多了&#xff0c;360下拉的优势就展现出来了&#xff0c;展示量大&#xff0c;全国各地均可见&#xff1b;能够引流来的都是相对精准的目标用户&a…

C#简单数据结构类和常用泛型结构类

文章目录 1.简单数据结构类&#xff08;1&#xff09;动态数组Arraylist&#xff08;2&#xff09;栈Stack&#xff08;3&#xff09;队列Queue&#xff08;4&#xff09;哈希表Hashtable 2.泛型3.常用泛型数据结构类&#xff08;1&#xff09;列表List&#xff08;2&#xff0…

高完整性系统:Fault Tolerant Design

目录 1. INTRODUCTION TO FAULT TOLERANCE 1.2 Definitions 1.3 Two Kinds of Faults 1.4 Hardware vs Software Faults 1.4.1 Failure Curve for Hardware 1.4.2 Hardware and Software Failures 1.5 Causes of Failures 1.6 3 Ways to Class Failures 1.6.1 Tempora…

Java 岗史上最全八股文面试真题汇总,堪称 2023 年面试天花板

前言 现如今&#xff0c;Java 面试的本质就是八股文&#xff0c;把八股文面试题背好&#xff0c;面试才有可能表现好。金九银十招聘黄金季已经来临&#xff01;大家在考研和找工作中纠结的时候&#xff0c;不妨先看一下面试题&#xff0c;毕竟我们的最终目标就是为了找一份心仪…

机器视觉怎么对陶瓷板外观尺寸进行自动检测?

随着陶瓷行业的发展&#xff0c;陶瓷板的生产和质量控制面临越来越高的要求。而机器视觉技术作为一种高精度、高效率、无损、可靠性高的自动化检测手段&#xff0c;已经成为陶瓷板外观尺寸自动化检测的首选方案。本文就如何利用机器视觉对陶瓷板外观尺寸进行自动检测进行分析和…

配电室的管理制度及综合监控系统的介绍

安科瑞虞佳豪 1、配电室全部机电设备&#xff0c;由配电室人员负责管理和值班&#xff0c;停送电由值班电工操作&#xff0c;非值班电工禁止操作&#xff0c;无关人员禁止进入配电室&#xff1b;公司内有关上级部门因检查工作&#xff0c;必须要进入这些场所时&#xff0c;应由…

【温故而知新】阶段总结!我在技术成长过程中的收获!

时间&#xff1a;2023年05月31日 作者&#xff1a;小蒋聊技术 邮箱&#xff1a;wei_wei10163.com 微信&#xff1a;wei_wei10 【20230531】【温故而知新】阶段总结&#xff01;我在技术成长过程中的收获&#xff01;_小蒋聊技术_免费在线阅读收听下载 - 喜马拉雅手机版欢迎…