#include "eeprom_lc02b.h" #include "delay.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); }