173 lines
5.3 KiB
C
173 lines
5.3 KiB
C
#include "eeprom_lc02b.h"
|
||
#include "delay.h"
|
||
#include "i2cs.h"
|
||
|
||
#define W_ADD_COM 0xa8 // 写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
|
||
#define R_ADD_COM 0xa9 // 读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
|
||
#define PAGE_SIZE 8U
|
||
#define SIZE 256U
|
||
|
||
#define EEPROM_LC02B_SDA_PORT I2C1_SDA_GPIO_Port
|
||
#define EEPROM_LC02B_SDA_PIN I2C1_SDA_Pin
|
||
#define EEPROM_LC02B_SCL_PORT I2C1_SCL_GPIO_Port
|
||
#define EEPROM_LC02B_SCL_PIN I2C1_SCL_Pin
|
||
|
||
static i2c_t *_eeprom_24lc028bt_i2c;
|
||
static TIM_TypeDef *_timer_us;
|
||
|
||
static void _delay_us(uint32_t us)
|
||
{
|
||
if (_timer_us != NULL)
|
||
{
|
||
delay_hardware_us(_timer_us, us);
|
||
}
|
||
else
|
||
{
|
||
delay_us(us);
|
||
}
|
||
}
|
||
|
||
void eeprom_lc02b_test(void)
|
||
{
|
||
#define TEST_SIZE 15
|
||
uint16_t test_address = SIZE - TEST_SIZE;
|
||
uint8_t buf[TEST_SIZE];
|
||
for (uint8_t i = 0; i < TEST_SIZE; i++)
|
||
{
|
||
buf[i] = i + 1;
|
||
}
|
||
|
||
eeprom_lc02b_write(test_address, buf, TEST_SIZE);
|
||
_delay_us(10000);
|
||
osel_memset(buf, 0, ARRAY_LEN(buf));
|
||
eeprom_lc02b_read(test_address, buf, TEST_SIZE);
|
||
|
||
__NOP();
|
||
}
|
||
|
||
/**
|
||
* @brief 获取EEPROM LC02B的状态
|
||
*
|
||
* 此函数用于获取EEPROM LC02B的当前状态。
|
||
*
|
||
* @return 如果EEPROM LC02B处于正常状态,则返回TRUE;否则返回FALSE。
|
||
* 注意:在本实现中,总是返回TRUE,因为这是一个简单的示例函数。
|
||
*/
|
||
BOOL eeprom_lc02b_status_get(void)
|
||
{
|
||
return TRUE;
|
||
}
|
||
|
||
/**
|
||
* @brief EEPROM LC02B初始化
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
void eeprom_lc02b_init(TIM_TypeDef *timer_us)
|
||
{
|
||
if (timer_us != NULL)
|
||
{
|
||
_timer_us = timer_us;
|
||
ENABLE_TIM_COUNT(_timer_us);
|
||
}
|
||
|
||
i2c_gpio_group_t gpios;
|
||
gpios.scl = gpio_create(EEPROM_LC02B_SCL_PORT, EEPROM_LC02B_SCL_PIN);
|
||
gpios.sda = gpio_create(EEPROM_LC02B_SDA_PORT, EEPROM_LC02B_SDA_PIN);
|
||
|
||
_eeprom_24lc028bt_i2c = i2c_create(gpios, 10);
|
||
// eeprom_lc02b_test();
|
||
}
|
||
|
||
/**
|
||
* @brief EEPROM LC02B反初始化
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
void eeprom_lc02b_dinit(void)
|
||
{
|
||
GPIO_SET_ANALOG(EEPROM_LC02B_SDA_PORT, EEPROM_LC02B_SDA_PIN);
|
||
GPIO_SET_ANALOG(EEPROM_LC02B_SCL_PORT, EEPROM_LC02B_SCL_PIN);
|
||
}
|
||
/**
|
||
* @brief 写入数据
|
||
* @param {uint32_t} write_addr
|
||
* @param {uint8_t} *data
|
||
* @param {uint16_t} length
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
void eeprom_lc02b_write(uint32_t write_addr, uint8_t *data, uint16_t length)
|
||
{
|
||
// 发送开始信号
|
||
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
|
||
// 发送写入地址命令
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
|
||
// 等待写入地址命令响应
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
// 发送要写入的地址
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)write_addr);
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
|
||
// 循环写入数据
|
||
|
||
for (uint16_t i = 0; i < length; i++)
|
||
{
|
||
// 写入一个字节数据
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, *data++);
|
||
// 等待响应
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
write_addr++;
|
||
if (write_addr % PAGE_SIZE == 0)
|
||
{
|
||
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
|
||
_delay_us(10000); // 延时10ms,等待写入完成
|
||
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)write_addr);
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
}
|
||
}
|
||
// 写入完成,停止I2C总线
|
||
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
|
||
}
|
||
|
||
/**
|
||
* @brief 读取数据
|
||
* @param {uint32_t} read_addr
|
||
* @param {uint8_t} *data
|
||
* @param {uint16_t} length
|
||
* @return {*}
|
||
* @note
|
||
*/
|
||
void eeprom_lc02b_read(uint32_t read_addr, uint8_t *data, uint16_t length)
|
||
{
|
||
// 发送开始信号
|
||
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
|
||
// 发送写入地址命令
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, W_ADD_COM);
|
||
// 等待写入地址命令响应
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
|
||
// 发送要读取的地址
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, (uint8_t)read_addr);
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
|
||
// 发送开始信号
|
||
_eeprom_24lc028bt_i2c->interface.start(_eeprom_24lc028bt_i2c);
|
||
// 发送读取地址命令
|
||
_eeprom_24lc028bt_i2c->interface.write_byte(_eeprom_24lc028bt_i2c, R_ADD_COM);
|
||
// 等待读取地址命令响应
|
||
_eeprom_24lc028bt_i2c->interface.wait_ack(_eeprom_24lc028bt_i2c);
|
||
// 循环读取数据
|
||
for (uint16_t i = 0; i < length - 1; i++)
|
||
{
|
||
// 读取一个字节数据
|
||
*data++ = _eeprom_24lc028bt_i2c->interface.read_byte(_eeprom_24lc028bt_i2c, TRUE);
|
||
}
|
||
*data++ = _eeprom_24lc028bt_i2c->interface.read_byte(_eeprom_24lc028bt_i2c, FALSE);
|
||
// 停止I2C总线
|
||
_eeprom_24lc028bt_i2c->interface.stop(_eeprom_24lc028bt_i2c);
|
||
}
|