单片机
返回首页

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

2023-04-03 来源:elecfans

一、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;

}


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • 家用电源无载自动断电装置的设计与制作

  • 用数字电路CD4069制作的万能遥控轻触开关

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 用NE555制作定时器

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章