24C02该器件通过IIC总线接口进行操作,有一个专门的写保护功能。用于存储数据,掉电也不丢失数据。
实验内容:用按键控制计数器增加和减少,然后存入EEPROM内,断电后计数器计数不变。
元器件
元器件 | 名称 |
---|---|
51单片机 | AT89C51 |
按键 | BUTTON |
数码管 | 7SEG-BCD-BLUE |
EEPROM | 24C02C |
原理图部分
24C02C引脚作用
引脚 | 作用 |
---|---|
SCK | IIC时钟线 |
SDA | IIC数据线 |
WP | 读写保护位,接地关闭读写保护 |
A0-A2 | 硬件地址更改,接地都为0 |
如图,A0-A2都接地,IIC硬件地址为0XA0:
#define AT24C02_address 0xA0
IIC模拟
起始和终止信号
时序图
起始
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
终止
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
发送应答和等待应答信号
发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
等待应答
//
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
读和写函数
写函数
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
读函数
//
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
实验源码
main.c
代码如下:
#include "EEPROM.h"
sbit KEY1=P1^0;
sbit KEY2=P1^1;
typedef unsigned char uint_8;
typedef unsigned int uint_16;
void get_key(void);
void SMG_output(uint_8 Data);
char num=5;
void main(void)
{
num=EEPROM_read(AT24C02_address,0x00);
while(1)
{
SMG_output(num);
get_key();
EEPROM_write(AT24C02_address,0x00,num);
}
}
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;
}
EEPROM.h
#ifndef _EEPROM_H
#define _EEPROM_H
#include "reg51.h"
#include "intrins.h"
sbit SDA = P3^1;
sbit SCL = P3^0;
#define AT24C02_address 0xA0
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
void EEPROM_write(unsigned char hw_address,unsigned char reg_address,unsigned char num);
unsigned char EEPROM_read(unsigned char hw_address,unsigned char reg_address);
#endif
EEPROM.c
#include "EEPROM.h"
#define DELAY_TIME 5
void EEPROM_write(unsigned char hw_address,unsigned char reg_address,unsigned char num)
{
IIC_Start();
IIC_SendByte(hw_address&0xfe);
IIC_WaitAck();
IIC_SendByte(reg_address);
IIC_WaitAck();
IIC_SendByte(num);
IIC_WaitAck();
IIC_Stop();
}
unsigned char EEPROM_read(unsigned char hw_address,unsigned char reg_address)
{
unsigned char num;
IIC_Start();
IIC_SendByte(hw_address&0xfe);
IIC_WaitAck();
IIC_SendByte(reg_address);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(hw_address|0x01);
IIC_WaitAck();
num=IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return num;
}
//
void IIC_Delay(unsigned char i)
{
do{
_nop_();}
while(i--);
}
//
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit;
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}