单片机STC12C5A60S2控制AT24C04的程序(C语言)

发布时间:
来源: 电子工程世界

/**************************************

主芯片:STC12C5A60S2(1T)
工作频率:12.000MHz
**************************************/

#include"REG51.H"
#include"INTRINS.H"


typedefunsignedcharBYTE;
typedefunsignedshortWORD;

sbitSCL=P3^4;//AT24C04的时钟
sbitSDA=P3^5;//AT24C04的数据

BYTEBUF[16];//数据缓存区

BYTEcodeTESTDATA[]=
{
0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF
};

voidDelay5us();
voidDelay5ms();
voidAT24C04_Start();
voidAT24C04_Stop();
voidAT24C04_SenDACK(bitack);
bitAT24C04_RecvACK();
voidAT24C04_SendByte(BYTEdat);
BYTEAT24C04_RecvByte();
voidAT24C04_ReadPage();
voidAT24C04_WritePage();

voidmain()
{
AT24C04_WritePage();
Delay5ms();
AT24C04_ReadPage();

while(1);

}

/**************************************
向AT24C04写1页(16字节)数据
将TESTDATA开始的16个测试数据写如设备的00~0F地址中
**************************************/
voidAT24C04_WritePage()
{
BYTEi;

AT24C04_Start();//起始信号
AT24C04_SendByte(0xa0);//发送设备地址+写信号
AT24C04_SendByte(0x00);//发送存储单元地址

for (i=0; i《16; i++)

{

BUF[i] = AT24C04_RecvByte();

if (i == 15)

{

AT24C04_SendACK(1); //最后一个数据需要会NAK

}

else

{

AT24C04_SendACK(0); //回应ACK

}

}

AT24C04_Stop(); //停止信号

}

/**************************************

延时5微秒(STC12C5A60S2@12M)

不同的工作环境,需要调整此函数

此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同

**************************************/

void Delay5us()

{

BYTE n = 4;

while (n--)

{

_nop_();

_nop_();

}

}

/**************************************

延时5毫秒(STC12C5A60S2@12M)

不同的工作环境,需要调整此函数

此延时函数是使用1T的指令周期进行计算,与传统的12T的MCU不同

**************************************/

void Delay5ms()

{

WORD n = 2500;

while (n--)

{

_nop_();

_nop_();

_nop_();

_nop_();

_nop_();

}

}

/**************************************

起始信号

**************************************/

void AT24C04_Start()

{

SDA = 1; //拉高数据线

SCL = 1; //拉高时钟线

Delay5us(); //延时

SDA = 0; //产生下降沿

Delay5us(); //延时

SCL = 0; //拉低时钟线

}

/**************************************

停止信号

**************************************/

void AT24C04_Stop()

{

SDA = 0; //拉低数据线

SCL = 1; //拉高时钟线

Delay5us(); //延时

SDA = 1; //产生上升沿

Delay5us(); //延时

}

/**************************************

发送应答信号

入口参数:ack (0:ACK 1:NAK)

**************************************/

void AT24C04_SendACK(bit ack)

{

SDA = ack; //写应答信号

SCL = 1; //拉高时钟线

Delay5us(); //延时

SCL = 0; //拉低时钟线

Delay5us(); //延时

}

/**************************************

接收应答信号

**************************************/

bit AT24C04_RecvACK()

{

SCL = 1; //拉高时钟线

Delay5us(); //延时

CY = SDA; //读应答信号

SCL = 0; //拉低时钟线

Delay5us(); //延时

return CY;

}

/**************************************

向IIC总线发送一个字节数据

**************************************/

void AT24C04_SendByte(BYTE dat)

{

BYTE i;

for (i=0; i<8; i++) //8位计数器

{

dat <<= 1; //移出数据的最高位

SDA = CY; //送数据口

SCL = 1; //拉高时钟线

Delay5us(); //延时

SCL = 0; //拉低时钟线

Delay5us(); //延时

}

AT24C04_RecvACK();

}

/**************************************

从IIC总线接收一个字节数据

**************************************/

BYTE AT24C04_RecvByte()

{

BYTE i;

BYTE dat = 0;

SDA = 1; //使能内部上拉,准备读取数据

for (i=0; i<8; i++) //8位计数器

{

dat <<= 1;

SCL = 1; //拉高时钟线

Delay5us(); //延时

dat |= SDA; //读数据

SCL = 0; //拉低时钟线

Delay5us(); //延时

}

return dat;

}


文章来源于: 电子工程世界 原文链接

本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。