1.硬件连接
AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。在单片机上的应用广泛, 可以实现掉电数据不丢失功能。
2.AT24C02读写时序说明:
(1)写数据描述:
通过IIC几种信号的组合,可以向AT24C02指定单元地址写一字节的数据。
可以看出,写顺序为:
起始,写器件地址,应答,写单元地址,应答,写数据,应答,终止。
(2)读数据描述
从AT24C02任意单元地址读取数据,可以看出读写顺序为:
起始,写器件地址(下一个字节为写),应答,写单元地址,应答,起始,写器件地址(下一个字节为读取),读取数据,终止。
3.例程实现
(1)延时
delay.h:
#ifndef _DELAY_H
#define _DELAY_H
#include "stc51.h"
void delay_us(uchar t);
void delay_ms(uint t);
#endif
#include "delay.h"
#include "stc51.h"
void delay_us(uchar t)
{
while(t--);
}
void delay_ms(uint t)
{
uint x,y;
for(x=t;x>0;x--)
for(y=110;y>0;y--);
}
(2)IIC模拟
iic.h:
#ifndef _IIC_H
#define _IIC_H
#include "stc51.h"
/*IIC管脚定义*/
sbit IIC_SDA = P3^0;
sbit IIC_SCL = P3^1;
void IO_Init();
void IIC_Start();
void IIC_Stop();
void IIC_Ack();
void IIC_NAck();
void IIC_Write_Byte(uchar txd);
uchar IIC_Read_Byte();
#endif
iic.c:
#include "delay.h"
#include "iic.h"
#include "stc51.h"
void IO_Init()
{
IIC_SCL = 1;
delay_us(5);
IIC_SDA = 1;
delay_us(5);
}
void IIC_Start()
{
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(5);
IIC_SDA = 0;
delay_us(5);
IIC_SCL = 0;
}
void IIC_Stop()
{
IIC_SCL = 0;
IIC_SDA = 0;
delay_us(5);
IIC_SCL = 1;
IIC_SDA = 1;
delay_us(5);
}
void IIC_Ack()
{
uchar i;
IIC_SCL = 1;
delay_ms(2);
while((IIC_SDA == 1) && i < 250)
i++;
IIC_SCL = 0;
delay_ms(2);
}
void IIC_NAck()
{
IIC_SCL = 1;
delay_ms(2);
IIC_SDA = 1;
IIC_SCL = 0;
delay_ms(2);
}
void IIC_Write_Byte(uchar txd)
{
uchar len;
for (len=0;len<8;len++)
{
IIC_SCL = 0;
delay_us(5);
if(txd & 0x80)
IIC_SDA = 1;
else
IIC_SDA = 0;
delay_us(5);
IIC_SCL = 1;
txd <<= 1;
delay_us(10);
IIC_SCL = 0;
delay_us(5);
}
IIC_SDA = 1;
IIC_SCL = 1;
delay_us(5);
}
uchar IIC_Read_Byte()
{
uchar len,dat = 0;
IIC_SDA = 1;
for(len=0;len<8;len++)
{
IIC_SCL = 0;
delay_us(5);
IIC_SCL = 1;
delay_us(5);
dat <<= 1;
dat |= IIC_SDA;
delay_us(5);
IIC_SCL = 0;
delay_us(5);
}
return dat;
}
(3)AT24C02实现:
at24c02.h:
#ifndef _AT24C02_H
#define _AT24C02_H
#include "stc51.h"
#define IIC_WADDR 0XA0
#define IIC_RADDR 0XA1
void AT24C02_Init(void);
void At24c02_Write_Byte(uchar addr,uchar dat);
uchar At24c02_Read_Byte(uchar addr);
void At24c02_Serial_Write(uchar Writeaddr,uchar *Str,uchar Len);
void At24c02_Serial_Read(uchar Readaddr,uchar *Str,uchar Len);
#endif
at24c02.c:
#include "iic.h"
#include "delay.h"
#include "at24c02.h"
#include "stc51.h"
void AT24C02_Init(void)
{
IO_Init();
}
void At24c02_Write_Byte(uchar addr,uchar dat)
{
IIC_Start();
IIC_Write_Byte(IIC_WADDR);
IIC_Ack();
IIC_Write_Byte(addr);
IIC_Ack();
IIC_Write_Byte(dat);
IIC_Ack();
IIC_Stop();
delay_ms(10);
}
uchar At24c02_Read_Byte(uchar addr)
{
uchar dat;
IIC_Start();
IIC_Write_Byte(IIC_WADDR);
IIC_Ack();
IIC_Write_Byte(addr);
IIC_Ack();
IIC_Start();
IIC_Write_Byte(IIC_RADDR);
IIC_Ack();
dat = IIC_Read_Byte();
IIC_Stop();
return dat;
}
void At24c02_Serial_Write(uchar Writeaddr,uchar *Str,uchar Len)
{
while(Len--)
{
At24c02_Write_Byte(Writeaddr,*Str);
Writeaddr++;
Str++;
}
}
void At24c02_Serial_Read(uchar Readaddr,uchar *Str,uchar Len)
{
while(Len)
{
*Str++ = At24c02_Read_Byte(Readaddr++);
Len--;
}
}
stc51.h:
#ifndef _STC51_H
#define _STC51_H
#include
typedef unsigned char uchar;
typedef unsigned int uint;
#endif
主函数main.c:
#include "iic.h"
#include "at24c02.h"
#include "stc51.h"
#include "Lcd_4line.h"
#include "key.h"
#include "delay.h"
//要写入到24c02的字符串数组
const uchar TEXT_Buffer[]={"STC51"};
uchar TEXT_Buffer1[]={"00000"};//数组一定初始化
#define SIZE sizeof(TEXT_Buffer)
void main()
{
uchar dat = 8;
uchar Text = 6 + '0';
uchar val;
Lcd_1602_init();
AT24C02_Init();
while(1)
{
lcd_onestring(0,0,Text);
At24c02_Write_Byte(10,dat);
val = At24c02_Read_Byte(10);
val = val + '0';
lcd_onestring(1,0,val);
lcd_string(0,7,5,TEXT_Buffer);
At24c02_Serial_Write(10,TEXT_Buffer,5);
At24c02_Serial_Read(10,TEXT_Buffer1,5);
lcd_string(1,7,5,TEXT_Buffer1);
}
}
4.实验现象
通过LCD1602显示写入和读出的数据,分别测试单字节和字符串。