首页 > 其他分享 >16_AT24C02(I2C总线)

16_AT24C02(I2C总线)

时间:2023-11-19 13:56:23浏览次数:28  
标签:P2 16 void unsigned char AT24C02 I2C

AT24C02(I2C总线)

存储器介绍

image-20231117105825624

存储器简化模型

image-20231117105857055

AT24C02介绍

image-20231117105408422

引脚及应用电路

image-20231117105955453

内部结构框图

image-20231117110020801

I2C总线介绍

image-20231117110040632

I2C电路规范

image-20231117112722856

弱上拉模式

image-20231117113126406

开漏输出模式

image-20231117113207680

I2C时序结构

image-20231117113729427

image-20231117113957153

image-20231118132221481

image-20231118132346442

I2C数据帧

image-20231118132819320

image-20231118134527785

image-20231118134844406

AT24C02数据帧

image-20231118151900348

image-20231118152336702

AT24C02数据存储

I2C.c

#include <REGX52.H>

sbit I2C_SCL=P2^1;
sbit I2C_SDA=P2^0;

/**
  * @brief I2C开始
  * @param 无
  * @retval 无
  */
void I2C_Start()
{
	I2C_SCL=1;
	I2C_SDA=1;
	I2C_SDA=0;
	I2C_SCL=0;
}

/**
  * @brief I2C结束
  * @param 无
  * @retval 无
  */
void I2C_Stop()
{
	I2C_SDA=0;
	I2C_SCL=1;
	I2C_SDA=1;
}

/**
  * @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;
	}
}

/**
  * @brief I2C接收一个字节
  * @param 无
  * @retval 接收到的数据
  */
unsigned char I2C_ReceiveByte()
{
	unsigned char Byte=0x00,i;
	I2C_SDA=1; //接收之前,释放SDA
	for(i=0;i<8;i++)
	{
		I2C_SCL=1;
		if(I2C_SDA)
		{
			Byte|=(0x80>>i);
		}
		I2C_SCL=0;
	}
	return Byte;
}

/**
  * @brief I2C发送应答
  * @param AckBit 应答位 0为应答 1为非应答
  * @retval 无
  */
void I2C_SendAck(bit AckBit)
{
	I2C_SDA=AckBit;
	I2C_SCL=1;
	I2C_SCL=0;
}

/**
  * @brief I2C接收应答
  * @param 无
  * @retval 接收到的应答 0为应答 1为非应答
  */
bit I2C_ReceiveAck()
{
	bit AckBit;
	I2C_SDA=1; //接收之前,释放SDA
	I2C_SCL=1;
	AckBit=I2C_SDA;
	I2C_SCL=0;
	return AckBit;
}

I2C.h

#ifndef __I2C_H__
#define __I2C_H__

void I2C_Start();
void I2C_Stop();
void I2C_SendByte(unsigned char Byte);
unsigned char I2C_ReceiveByte();
void I2C_SendAck(bit AckBit);
bit I2C_ReceiveAck();

#endif

AT24C02.c

#include <REGX52.H>
#include "I2C.h"

#define AT24C02_ADDRESS 0xA0

/**
  * @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();
}

/**
  * @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;
}

AT24C02.h

#ifndef __AT24C02_H__
#define __AT24C02_H__

void AT24C02_WriteByte(unsigned char WordAddress, Data);

unsigned char AT24C02_ReadByte(unsigned char WordAddress);

#endif

main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
#include "Key.h"
#include "AT24C02.h"

unsigned char KeyNum;
unsigned int Num;

void main()
{
	LCD_Init();
	LCD_ShowNum(1,1,Num,5);
	while(1)
	{
		KeyNum=Key();
		switch(KeyNum)
		{
			case 1:Num++;LCD_ShowNum(1,1,Num,5);break;
			case 2:Num--;LCD_ShowNum(1,1,Num,5);break;
			case 3:
				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,"           ");
				break;
			case 4:
				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,"           ");
				break;
		}
	}
}

显示效果

![VID_20231118_193507 (2)](H:\通讯软件\QQSave\1607442148\FileRecv\MobileFile\VID_20231118_193507 (2).gif)

动态数码管显示秒表,使用AT24C02进行存储,定时器进行延时,不阻塞主函数

Key.c

#include <REGX52.H>
#include "Delay.h"

unsigned char Key_KeyNumber;

unsigned char Key()
{
	unsigned char Temp;
	Temp=Key_KeyNumber;
	Key_KeyNumber=0;
	return Temp;
}

unsigned char Key_GetState()
{
	unsigned char KeyNumber=0;
	if(P3_1==0){KeyNumber=1;}
	if(P3_0==0){KeyNumber=2;}
	if(P3_2==0){KeyNumber=3;}
	if(P3_3==0){KeyNumber=4;}
	return KeyNumber;
}

void Key_Loop()
{
	static unsigned char NowState,LastState;
	LastState=NowState;
	NowState=Key_GetState();
	
	if(NowState==0)
	{
		switch(LastState) //按下后松手
		{
			case 1:Key_KeyNumber=1;break;
			case 2:Key_KeyNumber=2;break;
			case 3:Key_KeyNumber=3;break;
			case 4:Key_KeyNumber=4;break;
		}
	}
}

Key.h

#ifndef __KEY_H__
#define __KEY_H__


unsigned char Key();
unsigned char Key_GetState();
void Key_Loop();

#endif

Nixie.c

#include <REGX52.H>
#include "Delay.h"

unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};

unsigned char Nixie_Buf[9]={0,10,10,10,10,10,10,10,10};

void Nixie_SetBuf(unsigned char Location,Number)
{
	Nixie_Buf[Location]=Number;
}

void Nixie_Scan(unsigned char Location,Number)
{
	P0=0x00; //消影
	switch(Location)
	{
		case 1:P2_4=1;P2_3=1;P2_2=1;break;
		case 2:P2_4=1;P2_3=1;P2_2=0;break;
		case 3:P2_4=1;P2_3=0;P2_2=1;break;
		case 4:P2_4=1;P2_3=0;P2_2=0;break;
		case 5:P2_4=0;P2_3=1;P2_2=1;break;
		case 6:P2_4=0;P2_3=1;P2_2=0;break;
		case 7:P2_4=0;P2_3=0;P2_2=1;break;
		case 8:P2_4=0;P2_3=0;P2_2=0;break;
	}
	P0=NixieTable[Number];
	
}

void Nixie_Loop()
{
	static unsigned char i=1;
	Nixie_Scan(i,Nixie_Buf[i]);
	i++;
	if(i>=9)
	{
		i=1;
	}
}

Nixie.h

#ifndef __NIXIE_H__
#define __NIXIE_H__

void Nixie_SetBuf(unsigned char Location,Number);
void Nixie_Scan(unsigned char Location,Number);
void Nixie_Loop();

#endif

main.c

#include <REGX52.H>
#include "Timer0.h"
#include "Key.h"
#include "Delay.h"
#include "Nixie.h"
#include "AT24C02.h"

unsigned char KeyNum;
unsigned char Min,Sec,MinSec;
unsigned char RunFlag;

void main()
{
	Timer0_Init();
	while(1)
	{
		KeyNum=Key();
		switch(KeyNum)
		{
			case 1:RunFlag=!RunFlag;break;
			case 2:Min=0;Sec=0;MinSec=0;break;
			case 3:
				AT24C02_WriteByte(0,Min);
				Delay(5);
				AT24C02_WriteByte(1,Sec);
				Delay(5);
				AT24C02_WriteByte(2,MinSec);
				Delay(5);
				break;
			case 4:
				Min=AT24C02_ReadByte(0);
				Sec=AT24C02_ReadByte(1);
				MinSec=AT24C02_ReadByte(2);
				break;
		}
		Nixie_SetBuf(1,Min/10);
		Nixie_SetBuf(2,Min%10);
		Nixie_SetBuf(3,11);
		Nixie_SetBuf(4,Sec/10);
		Nixie_SetBuf(5,Sec%10);
		Nixie_SetBuf(6,11);
		Nixie_SetBuf(7,MinSec/10);
		Nixie_SetBuf(8,MinSec%10);
	}
}

void Sec_Loop()
{
	if(RunFlag)
	{
		MinSec++;
		if(MinSec>=100)
		{
			MinSec=0;
			Sec++;
			if(Sec>=60)
			{
				Sec=0;
				Min++;
				if(Min>=60)
				{
					Min=0;
				}
			}
		}
	}
}

void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count1,T0Count2,T0Count3;
	TL0 = 0x18;
	TH0 = 0xFC;
	T0Count1++;
	if(T0Count1>=20)
	{
		T0Count1=0;
		Key_Loop();
	}
	T0Count2++;
	if(T0Count2>=1)
	{
		T0Count2=0;
		Nixie_Loop();
	}
	T0Count3++;
	if(T0Count3>=10)
	{
		T0Count3=0;
		Sec_Loop();
	}
}

运行效果

![VID_20231119_134042 (2)](H:\通讯软件\QQSave\1607442148\FileRecv\MobileFile\VID_20231119_134042 (2).gif)

标签:P2,16,void,unsigned,char,AT24C02,I2C
From: https://www.cnblogs.com/mzx233/p/17841976.html

相关文章

  • 11月16日总结
    一.今天做了什么上午uml写了报告,然后体育课打了两场比赛,我们队终于赢了一场,现在是三负一胜的战绩。下午数据结构课上机实验,写了两节课一道题也没写出来,我真服了。然后是离散数学,基本都听懂了二.遇到的问题,如何解决无......
  • P9197 [JOI Open 2016] 摩天大楼
    学习:连续端dp。目标:最优化\(F(S)=\sum_{i=1}^{n-1}w(A_{S_i},A_{S_{i+1}})\),或者说,重排序列以最优化相邻两个元素产生的贡献。考虑拆开贡献,拆成类似\(L(a_i)+R(a_{i+1})\)的形式。连续端dp通过以下两个操作生成作为一整个连续端的序列:在一个段的左或右插入一个元......
  • Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)
    ApacheShiro1.2.4反序列化漏洞(CVE-2016-4437)ApacheShiro是一款开源安全框架,提供身份认证、授权、密码学和会话管理。Shiro框架直观、易用,同时也提供健壮的安全性。ApacheShiro1.2.4以及以前部版本中,加密的用户信息序列号后存储在名为remember-me的Cookie中,攻击者开源使用Shi......
  • 前端学习笔记学习笔记第七十柒天-webpack源码分析16
      ......
  • 【第16章】 网络安全风险评估技术原理与应用
    16.1网络安全风险评估概述网络安全风险评估是评价网络信息系统遭受潜在的安全威胁所产生的影响。本节主要阐述网络安全风险评估的概念、网络安全风险评估的要素、网络安全风险评估模式。16.1.1网络安全风险评估概念网络安全风险评估(简称“网络风险评估")就是指依据有关信息安......
  • P1605 迷宫
    题目描述给定一个\(N\timesM\)方格的迷宫,迷宫里有\(T\)处障碍,障碍处不可通过。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。给定起点坐标和终点坐标,每个方格最多经过一次,问有多少种从起点坐标到终点坐标的方案。输入格式第一行为三......
  • DS145-16A-ASEMI整流二极管DS145-16A
    编辑:llDS145-16A-ASEMI整流二极管DS145-16A型号:DS145-16A品牌:ASEMI封装:TO-247特性:插件、整流二极管正向电流:45A反向耐压:1600V恢复时间:ns引脚数量:2芯片个数:1芯片尺寸:84MIL浪涌电流:150A漏电流:10ua工作温度:-55℃~150℃包装方式:500/盘;5000/箱备受欢迎的DS145-16A-ASEM......
  • 20211316郭佳昊 《信息安全系统设计与实现(上)》 第十周学习总结 块设备I/O和缓冲区处理
    一、任务要求[1]知识点归纳以及自己最有收获的内容,选择至少2个知识点利用chatgpt等工具进行苏格拉底挑战,并提交过程截图,提示过程参考下面内容(4分)我在学****知识点,请你以苏格拉底的方式对我进行提问,一次一个问题核心是要求GPT:请你以苏格拉底的方式对我进行提问然后GPT就会......
  • (链表)16-删除有序链表中重复的元素-b
    1importjava.util.*;23/*4*publicclassListNode{5*intval;6*ListNodenext=null;7*publicListNode(intval){8*this.val=val;9*}10*}11*/12publicclassSolution{13/**14*@paramhead......
  • 11.16每日总结
     昨天博客忘记发了,补一下。 昨天上课王老师强调了智能排产。昨天在做一个可以实现不同表都可以调用的增函数。publicstaticvoidinsertData(StringtableName,String...columnValuePairs){Connectionconnection=getConnection();try{......