应广单片机例程EERPOM页写中一个BUG

本文对比了24C02的两种规格,关注点在于页写入字节数的差异,指出超过8字节可能会导致错误。同时,提供了一份兼容两种类型24C02的EEPROM读写程序,详细阐述了启动、停止、应答等通信过程,并实现了数据的写入和读取功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、以24C02为例,比较两份规格书。
在这里插入图片描述
另一个型号
在这里插入图片描述
比较后可以发现在,上面页写:16字节,下面的页写:8字节,对于页写8字节的24C02页写超过8字节,会出错。

二、兼容两个类型的程序
////
// 功能名称: EEPROM页读写
// 适应芯片: 24C02
//--------------------------------------------------------------------------------//
//程序说明:
// 地址和数据可以随意改动,数据的范围为0~255,
// 超过的范围请参考连写或连读
//注意事项:
// 1.案例为PMS154C,其他芯片原理都相同
// 2.连读或连写请参考对应的程序
//
//

//#define _5us 5*4
//bit SCL : PA.3;//用于产生器件所有数据发送或接收的时钟
//bit SDA : PA.4;//用于器件所有数据的发送或接收

//byte Address;
//byte data;
//byte Read_Data;
//byte Write_Data;

static void init(void)//初始化函数
{
WDRESET
SCL = 1;
.delay _5us;
SDA = 1;//控制信号拉高
.delay _5us;
}

static void start(void)//启动信号子函数//向ROM发送一个开始的信号
{
WDRESET
SDA = 1;
.delay _5us;
SCL = 1;
.delay _5us;
SDA = 0;
.delay _5us;
}

static void stop(void)//停止信号子函数//向ROM发送一个停止的信号
{
WDRESET
SDA = 0;
.delay _5us;
SCl = 1;
.delay _5us;
SDA = 1;
.delay _5us;
}

static void respons(void)//应答信号子函数//接收一信号后应答
{
WDRESET
$ SDA in,pull;
.delay 1004;
SCL = 1;
.delay _5us;
while(SDA==1)
{ nop;}//WDRESET;}
SCL = 0;
.delay _5us;
$ SDA out,high;
.delay 100
4;
}

static void sendack(void)//
{
SDA = 0;
.delay _5us;
SCL = 1;
.delay _5us;
SCL = 0;
.delay _5us;
}

static void write_byte(void)//写入一个字节数据//向E2PROM写数据
{
byte temp = 0,i = 8;
WDRESET
while(i–)
{
SCL = 0;//数据可以改变
.delay _5us;
temp = data & 0x80;//保留最高位
if(temp)//写一位
SDA = 1;
else
SDA = 0;
.delay _5us;
data <<= 1;//要存的数据左移一位
SCL = 1;//数据稳定不能写了
.delay _5us;
}
SCL = 0;
.delay _5us;
SDA = 1;//稳定数据
.delay _5us;
}

static void read_byte(void)//读回一个字节
{
byte i = 8;
WDRESET
SCL = 0;//数据改变
.delay _5us;
SDA = 1;//可读信号
.delay _5us;
$ SDA in,pull;
.delay 1004;
Read_Data = 0;
while(i–)
{
Read_Data = Read_Data << 1;//写入时从高位写,读出时也一样
SCL = 1;//数据稳定,可从SDA读出一位
.delay _5us;
if(SDA)
Read_Data = Read_Data | 0x01;
else
Read_Data = Read_Data & 0xfe;
SCL = 0;//数据改变准备下一位
.delay _5us;
}
$ SDA out,high;
.delay 100
4;
}

static void write_add(void)//片内随意地址写任意数//根据起始地址、数据个数及数据写入E2PROM中
{ //Write_Data address变量
start();//起始

data = 0xa0;//E2PROM地址(ATC02为0xa0)//器件地址+写控制位
write_byte();
respons();//应答

data = address;//写入数据要存放的地址
write_byte();
respons();//应答

data = Write_Data;//写入数据
write_byte();
respons();//应答

stop();//终止

}

void Nwrite_add(void)//片内随意地址写任意数//根据起始地址、数据个数及数据写入E2PROM中
{
Nwrite_add2A();
.delay 5000*4;
Nwrite_add2B();
}

void Nwrite_add2A(void)//片内随意地址写任意数//根据起始地址、数据个数及数据写入E2PROM中
{ //Write_Data address变量
start();//起始

data = 0xa0;//E2PROM地址(ATC02为0xa0)//器件地址+写控制位
write_byte();
respons();//应答

address=0x0;
data = address;//写入数据要存放的地址
write_byte();
respons();//应答

data = freq_value[0];//写入第一个数据
write_byte();
respons();//应答

data = freq_value[1];//写入第二个数据
write_byte();
respons();//应答

//------连写几个数据就加几个下面的语句--------
data = freq_value[2];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[3];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[4];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[5];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[6];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[7];//写入第三个数据
write_byte();
respons();//应答
/*
data = freq_value[8];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[9];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[10];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[11];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[12];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[13];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[14];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[15];//写入第三个数据
write_byte();
respons();//应答
*/
//--------------------------------------------
stop();//终止
}

void Nwrite_add2B(void)//片内随意地址写任意数//根据起始地址、数据个数及数据写入E2PROM中
{ //Write_Data address变量
start();//起始

data = 0xa0;//E2PROM地址(ATC02为0xa0)//器件地址+写控制位
write_byte();
respons();//应答

address=0x0;
data = address;//写入数据要存放的地址
data += 8;		//1k 和 2k 是8byte
write_byte();
respons();//应答

/*
data = freq_value[0];//写入第一个数据
write_byte();
respons();//应答

data = freq_value[1];//写入第二个数据
write_byte();
respons();//应答

//------连写几个数据就加几个下面的语句--------
data = freq_value[2];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[3];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[4];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[5];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[6];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[7];//写入第三个数据
write_byte();
respons();//应答
*/
data = freq_value[8];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[9];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[10];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[11];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[12];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[13];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[14];//写入第三个数据
write_byte();
respons();//应答
data = freq_value[15];//写入第三个数据
write_byte();
respons();//应答
//--------------------------------------------
stop();//终止
}

static void read_add(void)//片内随意地址读数据//根据起始地址和读出个数,从E2PROM中读出一串数据
{ //address变量
start();//起始

data = 0xa0;//器件地址+写控制位
write_byte();
respons();//应答

data = address;//数据地址
write_byte();
respons();//应答

start();//起始

data = 0xa1;//器件地址+读控制位
write_byte();
respons();

read_byte();
.delay 1000*4;

stop();//停止

}

//freq_value[12]

static void Nread_add(void)//片内随意地址读数据//根据起始地址和读出个数,从E2PROM中读出一串数据
{ //address变量
start();//起始

data = 0xa0;//器件地址+写控制位
write_byte();
respons();//应答

address = 12;
data = address;//数据地址
write_byte();
respons();//应答

start();//起始

data = 0xa1;//器件地址+读控制位
write_byte();
respons();

read_byte();//读出第一个地址的数据
freq_value[12] = Read_Data;
.delay 1000*4;//延时一下
sendack();//应答,连续读数据之间必须应答,否则数据读取失败
read_byte();//读出第二个地址的数据
freq_value[13] = Read_Data;
.delay 1000*4;//延时一下

//---------连续读几位就写几次下面的语句-----------
sendack();//应答
read_byte();//读出第三个地址的数据
freq_value[14] = Read_Data;
.delay 10004;//延时一下
//---------连续读几位就写几次下面的语句-----------
sendack();//应答
read_byte();//读出第三个地址的数据
freq_value[15] = Read_Data;
.delay 1000
4;//延时一下
//------------------------------------------------
stop();//停止
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值