//-------------------------------------------------------------------------------//
//----------void write_AT24(unsigned char address,unsigned char word);-----------//
//----------unsigned char read_AT24(unsigned char address);----------------------//
//----------使用以上两个函数可以向at24分别写读一个字节---------------------------//
//----------注意在写完一个字节后必须使用delay10ms()延迟10ms----------------------//
//-------------------------------------------------------------------------------//
//void write_AT24_S(unsigned char address,unsigned char *word,unsigned char number)//
//可以连续写字节,最多8个字节,但只能在一个扇区内写,一个扇区8个字节。因为AT24-----//
//内部地址的低三位每读一次加一位,不会进位到第四位,比如写地址为0x0f=0b00001111,---//
//低三为111加一位为000,写完地址00001111后下一个地址被写入00001000,而不是0001000--//
//void char read_AT24_S(unsigned char address,unsigned char *word,unsigned char number)//
//----------------连续读字节,同样有扇区和最多读8字节的限制,不然会--------------------//
//----------重复读之前读过的东西.最后读取的字节放在word中-------此函数暂时无法使用-----//
#include "reg51.h"
#include "intrins.h"
sbit SCL=P0^0;//rom输入时钟,最大频率为400khz,周期为2.5us,模拟时钟输出时一个周期的高低位都设为2us,也不违反高低脉冲的占空比要求,另外读或写时都最好保留1u的建立时间和保持时间
sbit SDA=P0^1;
void delay10ms(void);//数据写入rom后需要一个最大10ms的内部写入周期
void delay(void);//SCL最大时钟频率是400Khz,即一个周期最少为2.5us
void start(void);//进入start condition,进入条件为scl为高电平时sda由高电平变为低电平
void stop(void);//进入stop condition,进入条件为scl为高电平时sda有低电平变为高电平,因此sda必须在scl高电平时稳定不然就判断是否进入stat或stop
void ack(void);//每次像eeprom写入一个字节(8个scl时钟周期)数据都要确认,确认信号为eeprom发过来的0,在scl的下降沿接受
void write_byte(unsigned char);//单片机向a24写一个字节,写数据实在时钟的上升沿
void write_AT24(unsigned char,unsigned char);//将一个字节写入rom中的某个地址,地址为7位,注意用完后必须延迟10ms使数据真正写入rom
unsigned char read_byte(void);//向at24读取一个字节的过程
unsigned char read_AT24(unsigned char);//从rom读取指定地址的字节到单片机
void write_AT24_S(unsigned char,unsigned char*,unsigned char);//连续向AT24的某个地址写入i个字节,i必须小于8,不然会重写
void read_AT24_S(unsigned char,unsigned char*,unsigned char);//从指定地址连续读出指定字节
void Rack(bit);
void main(void)//测试用主函数
{
unsigned char cc[20];
unsigned char temp[8]={0x14,0x53,0xa6,0xff,0x1f,0x20,0xc4,0x87};
//unsigned char temp1[8]={0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01};
//unsigned char uu;
unsigned char i;
for(i=0;i<16;i++)
{
//write_AT24(i,1);
write_AT24_S((0x00+8*i),temp,0x08);
delay10ms();
}
//char vv[3];//
write_AT24_S(0x00,temp,0x08);
delay10ms();
//read_AT24_S(0x02,cc,0x01);
//start();//再一个开始,不然就变写的操作了
//write_byte(0xA1);//写入设备地址10100001,进行读的操作
//ack();
//cc[19]=read_byte();
//Rack(0);
//cc[18]=read_byte();
//Rack(0);
//i=read_byte();
//Rack(1);
//stop();
//start();//再一个开始,不然就变写的操作了
//write_byte(0xA1);//写入设备地址10100001,进行读的操作
//ack();
//cc[19]=read_byte();
//Rack(0);
//cc[18]=read_byte();
//Rack(0);
//i=read_byte();
//Rack(1);
//stop();
//write_AT24(0x10,3)
//cc[0]=read_AT24(0x00);
for(i=0;i<20;i++)
{
cc[i]=read_AT24(0x00+i);
}
//write_AT24(0x01,0xAA);
//write_AT24(0x02,0xBA);
//delay10ms();
//ACC=read_AT24(0x01);
//delay10ms();
//ACC=read_AT24(0x02);
// write_AT24(0x03,0xA0);
//delay10ms();
// ACC=read_AT24(0x03);
// write_AT24(0x04,0x4A);
// delay10ms();
// ACC=read_AT24(0x04);
while(1);
//return (0);
}
void delay10ms(void)//假设12M的晶振,一个指令周期12个震荡周期,所以一个指令周期是12/12=1us,所以需要10000个指令周期,while花费2个指令周期
{
unsigned int i=5000;
while(--i);
}
void delay(void)//SCL最大时钟频率是400Khz,即一个周期最少为2.5us,因此模拟时钟是高低电平的延迟时间用2us,占用两个指令周期
{
_nop_();_nop_();
}
void start(void)
{
SDA=1;
SCL=1;
delay();//设置Tsu.sta,按标准最小为0.6us,这里保险点用2us
SDA=0;
delay();//设置Thd.sta,按标准最小0.6us,这里也用2us
SCL=0;
}
void stop(void)
{
SDA=0;
SCL=1;
delay();//设置Tsu.sto,按标准最小为0.6us,这里保险点用2us
SDA=1;
delay();//设置Tbuf,按标准最小1.2us,这里也用2us
//SCL=0;不用置0,可以在当前高电平中继续下一个start
}
void ack(void)
{
//SDA=1;//锁存器置1,读取io口的值?
SCL=0;
delay();//scl电平的持续时间
SCL=1;//scl时钟置0,在下降沿eeprom发出一个ack信息,单片机接受
//if(SDA){break;} 24发送数据在时钟的下降沿,所以在scl=0和scl=1出都可以读io口的值,这里没有考虑出错的情况
delay();//满足Tdh,标准最小50ns,这里用2us
SCL=0;
}
void write_byte(unsigned char word)
{
unsigned char i;
SCL=0;
for(i=0;i<8;i++)
{
SDA=(bit)(word&0x80);
word<<=1;
delay();//低电平的持续时间同时保证Tsu.dat,a24准备在时钟上升沿锁存数据,前面两个语句时间够长就不用了
SCL=1;
delay();//高电平的持续时间,构成一个时钟周期
SCL=0;//继续下一个时钟周期
}
}
void write_AT24(unsigned char address,unsigned char word)
{
start();
write_byte(0xA0);//写入设备地址10100000
ack();//单片机接受应答
write_byte(address);//写入需要写入字节的地址
ack();
write_byte(word);//写入数据
ack();
stop();
}
unsigned char read_byte(void)
{
unsigned char word;
unsigned char i;
unsigned char temp=0x80;
SCL=0;
for(i=0;i<8;i++)
{
//SDA=1;//锁存器置1,准备接受io口引脚上的数据?
delay();//时钟低电平的持续时间
SCL=1;
if(SDA) word|=temp;
temp>>=1;
delay();//时钟高电平的持续时间,可以不加,前面几个指令时间够长了
SCL=0;
}
delay();//第八个也就是最后一个时钟周期读完之后产生低电平的持续时间,可以不加
return(word);
}
unsigned char read_AT24(unsigned char address)
{
unsigned char word;
start();
write_byte(0xA0);//写入设备地址10100000,先写一次需要读取自己的地址
ack();
write_byte(address);
ack();
start();//再一个开始,不然就变写的操作了
write_byte(0xA1);//写入设备地址10100001,进行读的操作
ack();
word=read_byte();
//SDA=1;
//delay();
//SCL=1;
//delay();
//SCL=0;
//delay();//进行一个周期,noack
Rack(1);
stop();
return(word);
}
void write_AT24_S(unsigned char address,unsigned char *word,unsigned char number)
{
unsigned char i;
start();
write_byte(0xA0);//写入设备地址10100000
ack();//单片机接受应答
write_byte(address);//写入需要写入字节的地址
ack();
for(i=0;i<number;i++)
{
write_byte(*(word+i));//写入数据
ack();
}
stop();
}
/*void read_AT24_S(unsigned char address,unsigned char *word,unsigned char number)
{
//unsigned char *word;
unsigned char i;
start();
write_byte(0xA0);//写入设备地址10100000,先写一次需要读取自己的地址
ack();
write_byte(address);
ack();
start();//再一个开始,不然就变写的操作了
write_byte(0xA1);//写入设备地址10100001,进行读的操作
ack();
for(i=0;i<number;i++)
{
*(word+i)=read_byte();
if(i==number-1)//如果只读一次或者读到最后一个字节要单片机要发出一个no ack信号,此外发ack
Rack(1);
else
Rack(0);
}
stop();
//return(word);
}*/
void Rack(bit i)//单片机向AT24发送的ACK有ACK和no ACK两种
{
SDA=i;
delay();
SCL=1;
delay();
SCL=0;
delay();
}
eeprom.zip_EEPROM C51_I2C总线协议_iic eeprom_单片机
版权申诉
110 浏览量
2022-09-20
15:08:43
上传
评论
收藏 3KB ZIP 举报
APei
- 粉丝: 63
- 资源: 1万+
最新资源
- PxCook-像素大厨Mac版本安装包
- 基于mysql和python的学生选课系统【课程设计(实验报告+源码)】
- PxCook-像素大厨Windows版本安装包
- aspose-words-23.12-jdk16 有水印
- [大模型部署]在C# Winform中使用文心一言ERNIE-3.5 4K 聊天模型
- python毕业设计-基于Django+OpenCV的二维码生成与识别系统设计与实现.zip
- python毕业设计-基于Django+OpenCV的二维码生成与识别系统设计与实现+使用说明.zip
- 基于STM32单片机空气监测系统设计源码+详细文档+配套全部资料(毕业设计).zip
- rdf0412-kcu116-pcie-c-2019-1.zip(XILINX KCU116 源码)
- 基于C#语言的winform界面火车票订票系统(源码+实验报告)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈