AT24C02(I2C总线)
存储器介绍
存储器简化模型
AT24C02介绍
引脚及应用电路
内部结构框图
I2C总线介绍
I2C电路规范
弱上拉模式
开漏输出模式
I2C时序结构
I2C数据帧
AT24C02数据帧
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