单片机用IIC读写EEPROM

单片机用IIC读写EEPROM,第1张

对iicEEPROM进行写入橘旁 *** 作时,IC内部有个自循环写时序大约10mS(不同的芯片可能略有差异),如果在这个时序尚未结束之前,执行读 *** 作,读出的数据只能是先前有效的写 *** 作记录的数据,因为单步调试 *** 作的时间伏瞎远大于10mS,iic的自循环写时序已经结束,所以读缺伍空出的数据是正确的。建议在写 *** 作之后延时10mS后再进行读 *** 作。

可友虚以这么肯定的说,如果橘闹你的项目不是很特殊的情况下,那就不是问题。

怎么说呢,官方承认在某种情况下,硬件I2C是存在不足的地方,但是官方给出了解决方法。

STM32F10x_硬件I2C读写EEPROM(标准外设圆告罩库版本):

http://blog.csdn.net/ybhuangfugui/article/details/52175621

写程序的时候,多注意一下芯片的资料。24C01的资料里面写的很清楚。读写必须按要求的波形来处理。我发一段我用在ST芯片的程序给你。由于IIC接口采用模拟的方式。所以,与什么和渣闭芯片没有关系。你把这段程序看一下。相信你可以看懂。使用这段程序的产品已经出货几十万套产品。不会有问题。

ST芯片的端口输入输出设定比较麻烦。所以有单独的子程序来处理。

单片机IIC的SDA端口在向EEPROM(24C01)发数据时,设为输出

在读取EEPROM数据的时候则设为输入。

//-------------------------------------------

//-程序名称: Eestart

//-入口参数:无

//-出口参数:无

//-功能说明: IIC的START信号生成

//-------------------------------------------

void Eestart(void) //启动I2C总线//

{

SETSDA

DelayNOP(STARTNOP)

SETSCL

DelayNOP(STARTNOP)

CLRSDA

DelayNOP(STARTNOP)

CLRSCL --注意此处,很重要。总线只有SCL为低时,才允许SDA变化。

DelayNOP(STARTNOP)

}

//-------------------------------------------

//-程序名称: Eestop

//-入口参数:无

//-出口参数:无

//-功能说明: IIC的STOP信号生成

//-------------------------------------------

void Eestop(void )/*停止I2C总线*/

{

i2csdaoutput()

CLRSCL

DelayNOP(STARTNOP)

CLRSDA

DelayNOP(STARTNOP)

SETSCL

DelayNOP(STARTNOP)

SETSDA

}

//-------------------------------------------

//-程序名称: read_byte_eeprom

//-入口参数:ackstate

//-出口参数:返回值(读取到的数梁源据)

//-功能说明: 读取1byte的EEPROM数据

//-------------------------------------------

UI08 read_byte_eeprom(UI08 ackstate) //-read

{

UI08 j,data

i2csdainput() //-SDA端口设为输入状态

data = 0 //-将接收缓冲清空

//DelayNOP(NOP1US) //-2011-7-21 新增延时

for(j=0j<8j++)

{

//-

data <<= 1 //-将接收缓冲左移,保证高位先发

SETSCL

DelayNOP(NOP2US)//-延时

if(p_eepsdain != 0) //-此处的p_eepsdain 就是SDA端口,ST芯片输入输出端口不是同一名字

{

//-检测到数据为1时,将接收缓冲0BIT置1

data++

}

CLRSCL

DelayNOP(NOP1P5US)

}

if(ackstate == ACKREAD)

{

//-有要求发送ACK信号的则发送ACK信号

i2csdaoutput()//-将SDA端口设为输出

CLRSDA

DelayNOP(NOP2US)

SETSCL

DelayNOP(NOP2US)

CLRSCL

}

return(data)

}

//-------------------------------------------

//-程序名称: write_byte_eeprom

//-入口参数:wrdata

//-出口参数:返唤裂回值,FALSE(写入失败),TRUE(写入成功)

//-功能说明: 将wrdata写入EEPROM

//-------------------------------------------

bool write_byte_eeprom(UI08 wrdata)

{

bool j=FALSE //-返回值,默认为失败

UI08 i

//DelayNOP(NOP1US)//-2011-7-21 新增延时

for(i=0i<8i++)

{

//-总共移位8次

if((0x80 &wrdata) != 0)

{

//-最高位为1时,SDA置1

SETSDA

}

else

{

//-最高位为0时,SDA置0

CLRSDA

}

wrdata <<= 1//-将发送数据左移,实现高位先发

//DelayNOP(NOP1US)//-2011-7-21 新增延时

SETSCL

DelayNOP(NOP2US)

CLRSCL

DelayNOP(NOP1P5US)

}

//--read ACK signal--{

i2csdainput() //-将SDA设为输入状态

DelayNOP(NOP1US)

SETSCL

if(p_eepsdain == 0)

{

//-读取到正确的ACK信号,则返回写入成功

j = TRUE

}

DelayNOP(NOP1P5US)

CLRSCL

i2csdaoutput()//-将SDA端口设为输出

//--read ACK signal--}

return(j)

}

//-------------------------------------------

//-程序名称: DelayNOP

//-入口参数:cntnop

//-出口参数:无

//-功能说明: 进行cntnop个延时

//-------------------------------------------

void DelayNOP(UI08 cntnop)

{

UI08 i

for(i=0i<cntnopi++)

}

//-------------------------------------------

//-程序名称: i2csdainput

//-入口参数:无

//-出口参数:无

//-功能说明: 将SDA端口设为输入

//-------------------------------------------

void i2csdainput(void)

{

/*

GPIO_InitTypeDef GPIO_InitStructure

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 //SDA

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU

GPIO_Init(GPIOB, &GPIO_InitStructure)

*/

}

//-------------------------------------------

//-程序名称: i2csdaoutput

//-入口参数:无

//-出口参数:无

//-功能说明: 将SDA端口设为输出

//-------------------------------------------

void i2csdaoutput(void)

{

/*

GPIO_InitTypeDef GPIO_InitStructure

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 //SDA

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD

GPIO_Init(GPIOB, &GPIO_InitStructure)

*/

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12252978.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-22
下一篇2023-05-22

发表评论

登录后才能评论

评论列表(0条)

    保存