STM32—EEPROM

介绍

EEPROM作为掉电不丢失的储存器,在使用上还是比较广泛的,

其可重复擦写,电擦除,使用方便

这里主要是以AT24C02为例介绍

硬件设计

Pin Configurations

该电路图设置下,A0—A2都是接地,所以EEPROM的地址为0x1010 000.

SDA和SCL分别与I2C相连,二者数据交换。

WP是写保护端口,这里直接接地,就没有写保护的功能,当然这不是说写保护不重要,只是在此处教学没有太大的用途,要是想控制WP,那就使WP与GPIO相连。

协议

写入

又协议图可知,I2C协议就是这个,所以我们可以把I2C协议拉出来使用。

向串行EEPROM指定地址写入若干数据,采用页写操作提高写入效率。

字节写入的话,每写完一次就需要判断是否写入完成,这一很麻烦。

于是我们就采用突发写入,也就是连续写入,这样就能直接写入多个字节


/*
*********************************************************************************************************
*    函 数 名: ee_ReadBytes
*    功能说明: 从串行EEPROM指定地址处开始读取若干数据
*    形    参:_usAddress : 起始地址
*             _usSize : 数据长度,单位为字节
*             _pReadBuf : 存放读到的数据的缓冲区指针
*    返 回 值: 0 表示失败,1表示成功
*********************************************************************************************************
*/
uint8_t ee_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize)
{uint16_t i;/* 采用串行EEPROM随即读取指令序列,连续读取若干字节 *//* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_WR);    /* 此处是写指令 *//* 第3步:等待ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}/* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那么此处需要连发多个地址 */i2c_SendByte((uint8_t)_usAddress);/* 第5步:等待ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}/* 第6步:重新启动I2C总线。前面的代码的目的向EEPROM传送地址,下面开始读取数据 */i2c_Start();/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_RD);    /* 此处是读指令 *//* 第8步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}    /* 第9步:循环读取数据 */for (i = 0; i < _usSize; i++){_pReadBuf[i] = i2c_ReadByte();    /* 读1个字节 *//* 每读完1个字节后,需要发送Ack, 最后一个字节不需要Ack,发Nack */if (i != _usSize - 1){i2c_Ack();    /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */}else{i2c_NAck();    /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */}}/* 发送I2C总线停止信号 */i2c_Stop();return 1;    /* 执行成功 */cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();return 0;
}

读取

该读取方式为:读取当前地址数据,就是上次操作的地址数据。这样的读取方式很少。

读取数据的操作只需要多一步,那就使提前说好要读取的地址,之后就是想要读取几个就几个,但是不能超出储存器范围,否则会重复读取,也就是读取之前的数据。



/*
*********************************************************************************************************
*    函 数 名: ee_ReadBytes
*    功能说明: 从串行EEPROM指定地址处开始读取若干数据
*    形    参:_usAddress : 起始地址
*             _usSize : 数据长度,单位为字节
*             _pReadBuf : 存放读到的数据的缓冲区指针
*    返 回 值: 0 表示失败,1表示成功
*********************************************************************************************************
*/
uint8_t ee_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize)
{uint16_t i;/* 采用串行EEPROM随即读取指令序列,连续读取若干字节 *//* 第1步:发起I2C总线启动信号 */i2c_Start();/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_WR);    /* 此处是写指令 *//* 第3步:等待ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}/* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那么此处需要连发多个地址 */i2c_SendByte((uint8_t)_usAddress);/* 第5步:等待ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}/* 第6步:重新启动I2C总线。前面的代码的目的向EEPROM传送地址,下面开始读取数据 */i2c_Start();/* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */i2c_SendByte(EEPROM_DEV_ADDR | EEPROM_I2C_RD);    /* 此处是读指令 *//* 第8步:发送ACK */if (i2c_WaitAck() != 0){goto cmd_fail;    /* EEPROM器件无应答 */}    /* 第9步:循环读取数据 */for (i = 0; i < _usSize; i++){_pReadBuf[i] = i2c_ReadByte();    /* 读1个字节 *//* 每读完1个字节后,需要发送Ack, 最后一个字节不需要Ack,发Nack */if (i != _usSize - 1){i2c_Ack();    /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */}else{i2c_NAck();    /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */}}/* 发送I2C总线停止信号 */i2c_Stop();return 1;    /* 执行成功 */cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 *//* 发送I2C总线停止信号 */i2c_Stop();return 0;
}

想要更加深入的学习,拿下offer

V:YHBGFFT76


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部