C51读写AT24C04源代码及AT24C04测试程序

发布时间:2023-06-25  

一、C51读写AT24C04源代码

/*=============================================*/

/*;***********************************/


/*;起动24C01时序*/

void Start()

{

SCL=1;

SDA=1;

SDA=0;

SCL=0;

}


/*;************************************/

/*;停止24C01时序*/

void Stop()

{

SDA=0;

SCL=1;

SDA=1;

}

/*;**************************************/

/*;检测24C01的响应信号*/

bit ACK()

{

bit c;

SDA=1;

SCL=1;

c=SDA;

SCL=0;

return c;

}

/*;************************************/

/*;往24C01发一8位数据*/

void SendChar(unsigned char ch)

{

unsigned char i;

i=8;

do

{

SDA=(ch&0x80);

SCL=1;

SCL=0;

ch《《=1;

}while(--i!=0);

}

/*;**************************************/

/*;从24C01接收一8位数据*/

unsigned char RecChar()

{

unsigned char i,j;

i=8;

do

{

SCL=1;

j=(j《《1)|SDA;

SCL=0;

}while(--i!=0);

return j;

}

//;**************************************

/*;********************************/

/*;往24C01写一字节*/

void WriteChar(unsigned int addr,unsigned char ch)

{

unsigned char c;

c=((*((unsigned char *)&addr))《《1)&0x02;

Start();

SendChar(0xa0|c);

ACK();

SendChar(addr);

ACK();

SendChar(ch);

ACK();

Stop();

// for(addr=4;addr!=0;addr--)

for(ch=0xff;ch!=0;ch--) ;

}

//;**************************************

/*;********************************/

/*;往24C01写多字节*/

void WriteBuf(unsigned int addr,unsigned char idata *buf,unsigned char count)

{

unsigned char c;

c=((*((unsigned char *)&addr))《《1)&0x02;

Start();

SendChar(0xa0|c);

ACK();

SendChar(addr);

ACK();

do

{

SendChar(*buf++);

ACK();

if(count!=1)

{if(((++addr)&0x7)==0)

{

Stop();

for(c=0xff;c!=0;c--) ;

c=((*((unsigned char *)&addr))《《1)&0x02;

Start();

SendChar(0xa0|c);

ACK();

SendChar(addr);

ACK();

}

}

else

{

Stop();

for(c=0xff;c!=0;c--) ;

}

}while(--count!=0);

}

/*;**********************************/

/*;从24C01读一字节*/

/*;入口:R0中为要读出内容的地址*/

/*;出口:A中为读到的内容*/

unsigned char ReadChar(unsigned int addr)

{

unsigned char ch;

ch=((*((unsigned char *)&addr))《《1)&0x02;

Start();

SendChar(0xa0|ch);

ACK();

SendChar(addr);

ACK();

Start();

SendChar(0xa1|ch);

ACK();

ch=RecChar();

Stop();

return ch;

}

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

/*至少读2字节*/

void ReadBuf(unsigned int addr,unsigned char idata *buf,unsigned char count)

{

unsigned char ch;

ch=((*((unsigned char *)&addr))《《1)&0x02;

Start();

SendChar(0xa0|ch);

ACK();

SendChar(addr);

ACK();

Start();

SendChar(0xa1|ch);

ACK();

count--;

do

{

*buf++=RecChar();

SDA=0;

SCL=1;

SCL=0;

SDA=1;

}while(--count!=0);

*buf=RecChar();

Stop();

}

二、AT24C04测试程序

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

主芯片 : STC12C5A60S2 (1T)

工作频率: 12.000MHz

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

#include “REG51.H”

#include “INTRINS.H”

typedef unsigned char BYTE;

typedef unsigned short WORD;

sbit SCL = P3^4; //AT24C04的时钟

sbit SDA = P3^5; //AT24C04的数据

BYTE BUF[16]; //数据缓存区

BYTE code TESTDATA[] =

{

0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,

0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF

};

void Delay5us();

void Delay5ms();

void AT24C04_Start();

void AT24C04_Stop();

void AT24C04_SendACK(bit ack);

bit AT24C04_RecvACK();

void AT24C04_SendByte(BYTE dat);

BYTE AT24C04_RecvByte();

void AT24C04_ReadPage();

void AT24C04_WritePage();

void main()

{

AT24C04_WritePage();

Delay5ms();

AT24C04_ReadPage();

while (1);

}

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

向AT24C04写1页(16字节)数据

将TESTDATA开始的16个测试数据写如设备的00~0F地址中

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

void AT24C04_WritePage()

{

BYTE i;

AT24C04_Start(); //起始信号

AT24C04_SendByte(0xa0); //发送设备地址+写信号

AT24C04_SendByte(0x00); //发送存储单元地址

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

{

AT24C04_SendByte(TESTDATA[i]);

}

AT24C04_Stop(); //停止信号

}

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

从AT24C04读取1页(16字节)数据

将设备的00~0F地址中的数据读出存放在DATA区的BUF中

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

void AT24C04_ReadPage()

{

BYTE i;

AT24C04_Start(); //起始信号

AT24C04_SendByte(0xa0); //发送设备地址+写信号

AT24C04_SendByte(0x00); //发送存储单元地址

AT24C04_Start(); //起始信号

AT24C04_SendByte(0xa1); //发送设备地址+读信号

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;

}


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

相关文章

    拿大模型代码来训练自用小模型;本文引用地址:1 前言 上一期所刊登的《从CLIP 应用领会隐空间的魅力》一文里,就是一个典型的范例:从Github 网页下载OpenAI 公司的CLIP 源代码......
    ://www.eembc.org/coremark/index.php 这里包含CoreMark相关说明、源代码下载、移植说明等。源代码位于Github,地址: https://github.com......
    Diffusion 模型就如同< 轮船> 的角色,而隐空间就如同< 码头> 的角色。接着,就来实际观摩一下SD 的源代码,从Github 上可以看到SD 的源代码。 进入这网页......
    测试系统的整体成本;提高开发效率;增加测试速度。 TestStand 特性:可立即运行,由用户定义测试执行;交互式开发环境建立测试顺序;用户选择XML,HTML,ASCII和数据库输出;高速并行顺序执行;源代码......
    帮您识别出图片里的人或物的种类。目前的ResNet50 可以准确地识别出1000 种人或物,如日常生活中常遇到的狗、猫、食物、汽车和各种家居物品等。 3 下载LoRA源代码 首先访问这个cccntu 网页,从Github......
    MCU源代码 点击左边栏的MCU开发,在硬件平台选择其他平台,然后输入Product Secret,下载代码包,在网页端的操作就完成了,剩下就是导入工程,和开发自己的功能了。 5、添加机智云代码到工程拷贝机智云代码......
    into Enterprise Architect 3 详细设计 3.1 代码编辑器 ECU(汽车电子控制单元)软件开发中常用的代码编辑工具包括: Source Insight: 一款功能强大的代码阅读和编辑工具,主要用于源代码......
    开发工具,可精确测量关键电机参数,自动调整反馈控制增益,并利用电机控制应用框架 (MCAF)生成源代码。最新版本(v2.45)包含名为“零速/最大扭矩(ZS/MT)”的强大新功能,可使......
    或MCU进行配置。   motorBench开发套件是一款基于图形用户界面的免费FOC软件开发工具,可精确测量关键电机参数,自动调整反馈控制增益,并利用电机控制应用框架 (MCAF)生成源代码。最新......
    应对实际工程挑战,如何为嵌入式软件开发选择编译器; 在过去数十年,一直支配着半导体的发展。随着MCU的性能越来越强,产品也越来越智能,嵌入式软件也变得越来越复杂。作为嵌入式的基础工具,将程序员编写的源代码......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>