一,AT24C02
AT24C02为一种ROM,存储介质为E2PROM,掉电不丢失,以I2C为通信接口,有8个引脚。
A0,A1,A2:设备地址,AT24C02地址有8位,前4位默认1010,最后一位为写保护低电平有效。
SCL:时钟线。
SDA数据线。
AT24C02进行读写需要SCL与SDA配和。
1,写 *** 作:
该时序为向24C02写入一个字节的数据,基本流程为:
1)Start(SCL高电平期间,SDA从高电平切换到低电平)
2)写入设备地址,蓝桥杯平台24C02地址为0XA0,注意这里是写入 *** 作所以地址的最后一位为0。
3)等待24C02应答。
4)写入存储地址。
5)等待24C02应答。
6)写入一个字节的数据。
7)等待24C02应答。
8)Stop(SCL高电平期间,SDA从低电平切换到高电平)
2,读 *** 作
该时序为向24C02读出一个字节的数据,基本流程为:
1)Start(SCL高电平期间,SDA从高电平切换到低电平)。
2)写入设备地址,蓝桥杯平台24C02地址为0XA0。
3)等待24C02应答。
4)写入存储地址。
5)等待24C02应答。
上面的 *** 作是读出数据前的必要 *** 作,这个流程称为dummy write.
6)Start。
7)写入设备地址,因为我们这里要进行读 *** 作,所以设备地址的最后一位为1,所以写入地址为0XA1.
8)等待24C02应答。
9)接收数据。
10)向24C02发送应答信号1。
11)Stop。
二,代码部分
1,main.c
#include "reg52.h"
#include "xmf_smg_ca.h"
#include "AT24C02.h"
#include "absacc.h"
unsigned char SMGnotdotduanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void Delay5ms() //@12.000MHz
{
unsigned char i, j;
i = 59;
j = 90;
do
{
while (--j);
} while (--i);
}
unsigned char dat;
void Work_24c02()
{
Write_24C02(1,111);
Delay5ms();
dat=Read_24C02(1);
}
void SMGWorking()
{
Dispaly_SMG(0,0xff);
Delay(100);
Dispaly_SMG(1,0xff);
Delay(100);
Dispaly_SMG(2,0xff);
Delay(100);
Dispaly_SMG(3,0xff);
Delay(100);
Dispaly_SMG(4,0xff);
Delay(100);
Dispaly_SMG(5,SMGnotdotduanma[dat/100]);
Delay(100);
Dispaly_SMG(6,SMGnotdotduanma[dat/10%10]);
Delay(100);
Dispaly_SMG(7,SMGnotdotduanma[dat%10]);
Delay(100);
Display_ALL(0xff);
}
void main()
{
XBYTE[0XA000]=0X00;
Work_24c02();
while(1)
{
SMGWorking();
}
}
2,AT24C02.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台 8051,12MHz
日 期: 2011-8-9
*/
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
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; // 0:应答,1:非应答
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;
}
//通过I2C总线发送数据
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;
}
//从I2C总线上接收数据
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;
}
void Write_24C02(unsigned char addr,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0xA0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
unsigned char Read_24C02(unsigned char addr)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0xA0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0xA1);
IIC_WaitAck();
temp=IIC_RecByte();
IIC_SendAck(1);
IIC_Stop();
return temp;
}
三,总结
在多次写入或者读取时,中间需要延时5ms.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)