current_v/Src/ht24lc02_eeprom.c

797 lines
20 KiB
C
Raw Normal View History

2025-12-31 08:21:43 +08:00
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file ht24lc02_eeprom.c
* @author Motor Control SDK Team, Yuwell Software XiangenWang
* @brief Voice Recognition Module Initialization Section,
including peripheral initialization and message node insertion, etc.
* @version 1.0
* @changelog version 1.0 <EFBFBD><EFBFBD>ʼ<EFBFBD> 2025.11.17
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>в<EFBFBD><EFBFBD><EFBFBD>
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2025 Yuwell Software Danyang.Jiangsu.China.
* All rights reserved.</center></h2>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted, provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of Yuwell Software nor the names of other
* contributors to this software may be used to endorse or promote products
* derived from this software without specific written permission.
* 4. This software, including modifications and/or derivative works of this
* software, must execute solely and exclusively on microcontroller or
* microprocessor devices manufactured by or for Yuwell Software.
* 5. Redistribution and use of this software other than as permitted under
* this license is void and will automatically terminate your rights under
* this license.
*
* THIS SOFTWARE IS PROVIDED BY Yuwell Software AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
* RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT
* SHALL Yuwell Software OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* USER CODE END Header */
#include "ht24lc02_eeprom.h"
#define HT24LC02_SDA_SET() FL_GPIO_SetOutputPin(EEPROM_24LC02_SDA_GROUP,EEPROM_24LC02_SDA_PIN)
#define HT24LC02_SCL_SET() FL_GPIO_SetOutputPin(EEPROM_24LC02_SCL_GROUP,EEPROM_24LC02_SCL_PIN)
#define HT24LC02_SDA_CLR() FL_GPIO_ResetOutputPin(EEPROM_24LC02_SDA_GROUP,EEPROM_24LC02_SDA_PIN)
#define HT24LC02_SCL_CLR() FL_GPIO_ResetOutputPin(EEPROM_24LC02_SCL_GROUP,EEPROM_24LC02_SCL_PIN)
#define EEPROM_WP_DISABLE() FL_GPIO_ResetOutputPin(EEPROM_24LC02_WP_GROUP,EEPROM_24LC02_WP_PIN)
#define EEPROM_WP_ENABLE() FL_GPIO_SetOutputPin(EEPROM_24LC02_WP_GROUP,EEPROM_24LC02_WP_PIN)
// <20>洢ÿ<E6B4A2><C3BF>uint32_t<5F><74><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>ʼ<EFBFBD><CABC>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><E9A3A8>64<36><34>Ԫ<EFBFBD>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD>0~63<36><33>Ӧ<EFBFBD><D3A6>0~<7E><>63<36><33>
const uint8_t eeprom_start_addr[BLOCK_NUM] =
{
0x00, 0x04, 0x08, 0x0C, // <20><>0~<7E><>3<EFBFBD><33><EFBFBD><EFBFBD>ַ0x00~0x0F<30><46>ǰ16<31>ֽڣ<D6BD>
0x10, 0x14, 0x18, 0x1C, // <20><>4~<7E><>7<EFBFBD><37><EFBFBD><EFBFBD>ַ0x10~0x1F
0x20, 0x24, 0x28, 0x2C, // <20><>8~<7E><>11<31><31><EFBFBD><EFBFBD>ַ0x20~0x2F
0x30, 0x34, 0x38, 0x3C, // <20><>12~<7E><>15<31><35><EFBFBD><EFBFBD>ַ0x30~0x3F
0x40, 0x44, 0x48, 0x4C, // <20><>16~<7E><>19<31><39><EFBFBD><EFBFBD>ַ0x40~0x4F
0x50, 0x54, 0x58, 0x5C, // <20><>20~<7E><>23<32><33><EFBFBD><EFBFBD>ַ0x50~0x5F
0x60, 0x64, 0x68, 0x6C, // <20><>24~<7E><>27<32><37><EFBFBD><EFBFBD>ַ0x60~0x6F
0x70, 0x74, 0x78, 0x7C, // <20><>28~<7E><>31<33><31><EFBFBD><EFBFBD>ַ0x70~0x7F
0x80, 0x84, 0x88, 0x8C, // <20><>32~<7E><>35<33><35><EFBFBD><EFBFBD>ַ0x80~0x8F
0x90, 0x94, 0x98, 0x9C, // <20><>36~<7E><>39<33><39><EFBFBD><EFBFBD>ַ0x90~0x9F
0xA0, 0xA4, 0xA8, 0xAC, // <20><>40~<7E><>43<34><33><EFBFBD><EFBFBD>ַ0xA0~0xAF
0xB0, 0xB4, 0xB8, 0xBC, // <20><>44~<7E><>47<34><37><EFBFBD><EFBFBD>ַ0xB0~0xBF
0xC0, 0xC4, 0xC8, 0xCC, // <20><>48~<7E><>51<35><31><EFBFBD><EFBFBD>ַ0xC0~0xCF
0xD0, 0xD4, 0xD8, 0xDC, // <20><>52~<7E><>55<35><35><EFBFBD><EFBFBD>ַ0xD0~0xDF
0xE0, 0xE4, 0xE8, 0xEC, // <20><>56~<7E><>59<35><39><EFBFBD><EFBFBD>ַ0xE0~0xEF
0xF0, 0xF4, 0xF8, 0xFC // <20><>60~<7E><>63<36><33><EFBFBD><EFBFBD>ַ0xF0~0xFF<46><46><EFBFBD><EFBFBD><EFBFBD><EFBFBD>16<31>ֽڣ<D6BD>
};
typedef enum
{
ACK,
NACK
}TYPE_ACK;
typedef enum
{
INPUT,
OUTPUT
}SDA_MODE;
/************************************************** <20><>̬<EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> **************************************************/
/**
* @brief <EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>I2Cʱ<EFBFBD><EFBFBD>
* @param us <EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>΢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void i2c_delay_us(uint32_t us)
{
FL_DelayUs(us); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MCU<43><55>ƵУ׼<D0A3><D7BC>ȷ<EFBFBD><C8B7>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>1us
}
/**
* @brief SDA<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param NONE
* @retval NONE
* @note Ϊʲô<EFBFBD><EFBFBD>©<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD>
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void i2c_sda_mode_set(SDA_MODE mode)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
if(mode == INPUT)
{
GPIO_InitStruct.pin = EEPROM_24LC02_SDA_PIN;
GPIO_InitStruct.mode = FL_GPIO_MODE_INPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init(EEPROM_24LC02_SDA_GROUP, &GPIO_InitStruct);
}else{
GPIO_InitStruct.pin = EEPROM_24LC02_SDA_PIN; // ÿ<>η<EFBFBD><CEB7>ͽ<EFBFBD><CDBD><EFBFBD>֮ǰ<D6AE>һ<EFBFBD><D2BB>ð<EFBFBD>IO<49>ڳ<EFBFBD>ʼ<EFBFBD><CABC>?
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT; // <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>©<EFBFBD><C2A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD>
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init(EEPROM_24LC02_SDA_GROUP, &GPIO_InitStruct);
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SDA<EFBFBD>ߡ<EFBFBD><EFBFBD>ͣ<EFBFBD>SCL<EFBFBD><EFBFBD><EFBFBD>ָߣ<EFBFBD>
* @param NONE
* @retval NONE
* @note
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void i2c_start(void)
{
i2c_sda_mode_set(OUTPUT);
HT24LC02_SDA_SET();
HT24LC02_SCL_SET();
i2c_delay_us(1);
HT24LC02_SDA_CLR();
i2c_delay_us(1);
HT24LC02_SCL_CLR();
i2c_delay_us(1);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֹͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SDA<EFBFBD>͡<EFBFBD><EFBFBD>ߣ<EFBFBD>SCL<EFBFBD><EFBFBD><EFBFBD>ָߣ<EFBFBD>
* @param NONE
* @retval NONE
* @note
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void i2c_stop(void)
{
i2c_sda_mode_set(OUTPUT);
HT24LC02_SDA_CLR();
HT24LC02_SCL_CLR();
i2c_delay_us(1); // <20><><EFBFBD><EFBFBD>t_SU:STO<54><4F>С250ns
HT24LC02_SCL_SET();
i2c_delay_us(1); // <20><><EFBFBD><EFBFBD>t_SU:STO<54><4F>С250ns
HT24LC02_SDA_SET();
i2c_delay_us(1);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param dat Ҫ<EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void i2c_sendByte(uint8_t dat)
{
uint8_t i;
i2c_sda_mode_set(OUTPUT);
for(i = 0; i < 8; i++)
{
HT24LC02_SCL_CLR();
i2c_delay_us(1);
if(dat & 0x80)
{
HT24LC02_SDA_SET();
}else{
HT24LC02_SDA_CLR();
}
i2c_delay_us(1); // <20><><EFBFBD><EFBFBD>t_SU:DAT<41><54>С100ns
HT24LC02_SCL_SET();
i2c_delay_us(1); // <20><><EFBFBD><EFBFBD>t_HIGH<47><48>С400ns
dat <<= 1;
}
HT24LC02_SCL_CLR();
i2c_delay_us(1);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param ack <EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>ֽڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static uint8_t i2c_recvByte(TYPE_ACK ack)
{
uint8_t dat = 0;
uint32_t EEcount = 0;
i2c_sda_mode_set(OUTPUT);
HT24LC02_SDA_SET(); // <20>ͷ<EFBFBD>SDA
i2c_sda_mode_set(INPUT);
for(uint8_t i=0; i<8; i++)
{
HT24LC02_SCL_CLR();
i2c_delay_us(1);
HT24LC02_SCL_SET();
i2c_delay_us(5); // <20><><EFBFBD><EFBFBD>t_AA<41><41><EFBFBD><EFBFBD>600ns
dat <<= 1;
if(FL_GPIO_GetInputPin(EEPROM_24LC02_SDA_GROUP,EEPROM_24LC02_SDA_PIN))
{
dat |= 0x01;
EEcount++;
}
}
HT24LC02_SCL_CLR();
i2c_delay_us(1);
i2c_sda_mode_set(OUTPUT);
// <20><><EFBFBD><EFBFBD>ACK/NACK
if(ack == ACK)
{
HT24LC02_SDA_CLR();
}else{
HT24LC02_SDA_SET();
}
HT24LC02_SCL_SET();
i2c_delay_us(1);
HT24LC02_SCL_CLR();
i2c_delay_us(1);
return dat;
}
/**
* @brief <EFBFBD>ȴ<EFBFBD><EFBFBD>ӻ<EFBFBD>ACK
* @param NONE
* @retval NONE
* @note
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static TYPE_ACK i2c_waitAck(void)
{
TYPE_ACK ack = NACK;
i2c_sda_mode_set(OUTPUT);
HT24LC02_SDA_SET(); // <20>ͷ<EFBFBD>SDA
HT24LC02_SCL_CLR();
i2c_delay_us(1);
HT24LC02_SCL_SET();
i2c_delay_us(1);
i2c_sda_mode_set(INPUT);
if(!FL_GPIO_GetInputPin(EEPROM_24LC02_SDA_GROUP,EEPROM_24LC02_SDA_PIN))
{
ack = ACK; // <20><><EFBFBD><EFBFBD>͵<EFBFBD>ƽΪACK
}
HT24LC02_SCL_CLR();
i2c_delay_us(1);
return ack;
}
/************************************************** <20>ⲿAPI<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> **************************************************/
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>EEPROM<EFBFBD><EFBFBD>
* @param data Ҫд<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ַ
addr оƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĵ<EFBFBD>ַ
len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note ע<EFBFBD><EFBFBD>EEPROMʹ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD>ҳд<EFBFBD><EFBFBD>
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void ht24lc02_multiByte_write(uint8_t* data,uint16_t addr,uint8_t len)
{
uint8_t i;
if((addr + len) > HT24LC02_ADDR_MAX)
{
return;
}
i2c_start();
i2c_sendByte(HT24LC02_ADDR | 0x00); // д<><D0B4><EFBFBD>0x00<30><30>
if (i2c_waitAck())
{
i2c_stop(); // δ<>յ<EFBFBD>ACK<43><4B><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
return;
}
i2c_sendByte(addr & 0xFF);
if (i2c_waitAck())
{
i2c_stop(); // δ<>յ<EFBFBD>ACK<43><4B><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
return;
}
for(i = 0;i < len;i++)
{
i2c_sendByte(data[i]);
if (i2c_waitAck())
{
i2c_stop(); // δ<>յ<EFBFBD>ACK<43><4B><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
return;
}
}
i2c_stop();
i2c_delay_us(5000);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>ȡ
* @param data Ҫ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ַ
addr оƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĵ<EFBFBD>ַ
len <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note ע<EFBFBD><EFBFBD>EEPROMʹ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD>ҳ<EFBFBD><EFBFBD>ȡ
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void ht24lc02_multiByte_read(uint8_t* data,uint16_t addr,uint8_t len)
{
uint8_t i;
if((addr + len) > HT24LC02_ADDR_MAX)
{
return;
}
i2c_start();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ+д<><D0B4><EFBFBD><EFBFBD><EEA3A8>ָ<EFBFBD><D6B8>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD>ġ<EFBFBD>ר<EFBFBD><D7A8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>
i2c_sendByte(HT24LC02_ADDR | 0x00);
if (i2c_waitAck())
{
i2c_stop(); // δ<>յ<EFBFBD>ACK<43><4B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Stop<6F>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
return;
}
i2c_sendByte(addr);
if (i2c_waitAck())
{
i2c_stop(); // δ<>յ<EFBFBD>ACK<43><4B><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
return;
}
i2c_start(); // <20>ظ<EFBFBD><D8B8><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
i2c_sendByte(HT24LC02_ADDR | 0x01); // <20><><EFBFBD><EFBFBD><EFBFBD>0x01<30><31>
if (i2c_waitAck())
{
i2c_stop(); // δ<>յ<EFBFBD>ACK<43><4B><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>
return;
}
for(i = 0; i < len; i++)
{
if(i == (len-1))
{
data[i] = i2c_recvByte(NACK);
}else{
data[i] = i2c_recvByte(ACK);
}
}
i2c_stop();
}
/**
* @brief <EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD>EEPROM<EFBFBD><EFBFBD>
* @param word Ҫд<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
addr_index оƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĵ<EFBFBD>ַ
* @retval NONE
* @note ע<EFBFBD><EFBFBD>EEPROMʹ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD>ҳд<EFBFBD><EFBFBD>
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
void ht24lc02_word_write(uint32_t word, uint8_t addr_index)
{
uint8_t data[4];
uint8_t i;
for(i = 0; i < 4; i++)
{
data[3-i] = (word >> (i*8)) & 0xFF;
}
ht24lc02_multiByte_write(data, eeprom_start_addr[addr_index], 4);
}
/**
* @brief <EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>ⲿ
* @param data Ҫ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ַ
addr оƬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĵ<EFBFBD>ַ
* @retval NONE
* @note ע<EFBFBD><EFBFBD>EEPROMʹ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD>ҳ<EFBFBD><EFBFBD>ȡ
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void ht24lc02_word_read(uint32_t* ptr_word, uint8_t addr_index)
{
uint8_t data[4];
uint32_t world = 0;;
uint8_t i;
ht24lc02_multiByte_read(data, eeprom_start_addr[addr_index], 4);
for(i = 0; i < 4; i++)
{
world += (data[3-i] << (i*8));
}
*ptr_word = world;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ Сʱ<EFBFBD><EFBFBD>
* @param NONE
* @retval <EFBFBD><EFBFBD><EFBFBD><EFBFBD>uint32_t <EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>ֽڵ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @note NONE
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static uint32_t ht24lc02_get_total_hours(void)
{
uint32_t totalTime = 0;
ht24lc02_word_read(&totalTime, INDEX_TOTAL_HOURS);
return totalTime;
}
/**
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param NONE
* @retval <EFBFBD><EFBFBD><EFBFBD><EFBFBD>uint32_t <EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>ֽڵ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @note NONE
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static uint32_t ht24lc02_get_total_minutes(void)
{
uint32_t totalTime = 0;
ht24lc02_word_read(&totalTime, INDEX_TOTAL_MINUTES);
return totalTime;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ Сʱ<EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD><EFBFBD><EFBFBD>uint32_t <EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>ֽڵ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note NONE
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void ht24lc02_set_total_hours(uint32_t hours)
{
if(hours > 19999)
{
hours = 19999;
}
ht24lc02_word_write(hours, INDEX_TOTAL_HOURS);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD><EFBFBD><EFBFBD>uint32_t <EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD>ĸ<EFBFBD><EFBFBD>ֽڵ<EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @retval NONE
* @note NONE
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.19
*/
static void ht24lc02_set_total_minutes(uint32_t minutes)
{
ht24lc02_word_write(minutes, INDEX_TOTAL_MINUTES);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ַ<EFBFBD><EFBFBD>ȡ<EFBFBD>ĸ<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param <EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
* @retval <EFBFBD><EFBFBD><EFBFBD>uint16_t<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @note NONE
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.12.03
*/
static uint32_t ht24lc02_get_uint32_by_index(uint8_t addr_index)
{
uint32_t ret = 0;
uint8_t data[4];
uint8_t i;
ht24lc02_multiByte_read(data, eeprom_start_addr[addr_index], 4);
for(i = 0; i < 4; i++)
{
ret += (data[3-i] << (i*8));
}
return ret;
}
/************************** <20><><EFBFBD><EFBFBD><E2B5BC><EFBFBD><EFBFBD>API<50><49><EFBFBD><EFBFBD> *************************/
/**
* @brief <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EERPOM<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param NONE
* @retval NONE
* @note NONE
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.25
*/
void eeprom_ht24lc02_init(void)
{
FL_GPIO_InitTypeDef GPIO_InitStruct;
MsgQueueItem queue_item;
MsgQueueItem filter_item;
GPIO_InitStruct.pin = EEPROM_24LC02_WP_PIN;
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_ENABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init(EEPROM_24LC02_WP_GROUP, &GPIO_InitStruct); // <20><><EFBFBD><EFBFBD>WPΪ<50><CEAA><EFBFBD><EFBFBD>ģʽ
GPIO_InitStruct.pin = EEPROM_24LC02_SCL_PIN;
FL_GPIO_Init(EEPROM_24LC02_SCL_GROUP, &GPIO_InitStruct); // <20><><EFBFBD><EFBFBD>SCLΪ<4C><CEAA><EFBFBD><EFBFBD>ģʽ
GPIO_InitStruct.pin = EEPROM_24LC02_SDA_PIN;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
FL_GPIO_Init(EEPROM_24LC02_SDA_GROUP, &GPIO_InitStruct); // <20><><EFBFBD><EFBFBD>SDAΪ<41><CEAA>©<EFBFBD><C2A9><EFBFBD><EFBFBD>ģʽ
// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϣ
queue_item.type = MSG_TYPE_TIME_SEND;
queue_item.data.hour_meter.hour = ht24lc02_get_total_hours(); // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>ʱ Сʱ<D0A1><CAB1>
queue_item.data.hour_meter.minute = ht24lc02_get_total_minutes(); // <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0>ʱ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
insert_queue_node_in_head(&global_queue, queue_item);
// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
queue_item.type = MSG_TYPE_AD_BOUNDARY_SEND;
queue_item.data.adc_boundary.elec_low_boundary = EEPROM_E3_ELEC_LOW_VALUE; // E3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
queue_item.data.adc_boundary.elec_high_boundary = ht24lc02_get_uint32_by_index(INDEX_E4_ELEC_HIGH); // E4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡEEPROM<4F>е<EFBFBD>ֵ
queue_item.data.adc_boundary.ntc_low_boundary = 0; // NTC̫<43>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
queue_item.data.adc_boundary.ntc_high_boundary = EEPROM_E5_NTC_HIGH_VALUE; // E5 ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
queue_item.data.adc_boundary.press_low_boundary = ht24lc02_get_uint32_by_index(INDEX_E1_PRESS_LOW); // E1 <20><>ȡEEPROM<4F>б<D0B1><EAB6A8>ֵ
queue_item.data.adc_boundary.press_high_boundary = ht24lc02_get_uint32_by_index(INDEX_E2_PRESS_HIGH); // E2 <20><>ȡEEPROM<4F>б<D0B1><EAB6A8>ֵ
queue_item.data.adc_boundary.net220v_low_boundary = ht24lc02_get_uint32_by_index(INDEX_E7_220V_LOW); // E7 <20><>ȡEEPROM<4F>е<EFBFBD>ֵ
queue_item.data.adc_boundary.net220v_high_boundary = 0; // <20><>ʹ<EFBFBD><CAB9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
insert_queue_node_in_head(&global_queue, queue_item);
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
filter_item.type = MSG_TYPE_FILTER_SERVER;
filter_item.data.filter_server.last_clean_filter_hours = ht24lc02_get_uint32_by_index(INDEX_LAST_CLEAN_FILTER_HOURS);
filter_item.data.filter_server.last_replace_filter_hours = ht24lc02_get_uint32_by_index(INDEX_LAST_REPLACE_FILTER_HOURS);
filter_item.data.filter_server.clean_filter_time_need_stored = false;
filter_item.data.filter_server.replace_filter_time_need_stored = false;
insert_queue_node_in_head(&global_queue, filter_item);
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD>ݶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EEPROM<EFBFBD>д<EFBFBD><EFBFBD>ǰСʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param NONE
* @retval NONE
* @note <EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD>
* @author <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @data 2025.11.25
*/
void eeprom_ht24lc02_save_task(MessageQueue* queue)
{
uint32_t hours = 0;
uint32_t minutes = 0;
MsgQueueItem queue_item;
MsgQueueItem adc_item;
MsgQueueItem carlib_item;
MsgQueueItem filter_item;
bool result = false;
result = remove_queue_node_by_type(&global_queue, MSG_TYPE_HOUR_SAVE, &queue_item); // ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
if(result)
{
hours = queue_item.data.hour_meter.hour;
ht24lc02_set_total_hours(hours);
}
result = remove_queue_node_by_type(&global_queue, MSG_TYPE_MINUTE_SAVE, &queue_item); // ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
if(result)
{
minutes = queue_item.data.hour_meter.minute;
ht24lc02_set_total_minutes(minutes);
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>464<36>¼<EFBFBD>
if(xOxygenEventGroupCheckBit(&global_event, EVENT_464_CLEAR))
{
// <20><><EFBFBD>ո<EFBFBD><D5B8>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
vOxygenEventGroupClearBits(&global_event, EVENT_464_CLEAR);
// <20>˴<EFBFBD><CBB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EEPROM<4F><4D>ʱ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD>
ht24lc02_set_total_minutes(0);
ht24lc02_set_total_hours(0);
vOxygenEventGroupSetBits(&global_event, EVENT_BLUE_BLINK);
}
// <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
if(remove_queue_node_by_type(&global_queue, MSG_TYPE_FILTER_TIME_SAVE, &filter_item))
{
if(filter_item.data.filter_server.clean_filter_time_need_stored)
{
ht24lc02_word_write(filter_item.data.filter_server.last_clean_filter_hours, INDEX_LAST_CLEAN_FILTER_HOURS);
filter_item.data.filter_server.clean_filter_time_need_stored = false;
}
if(filter_item.data.filter_server.replace_filter_time_need_stored)
{
ht24lc02_word_write(filter_item.data.filter_server.last_replace_filter_hours, INDEX_LAST_REPLACE_FILTER_HOURS);
filter_item.data.filter_server.clean_filter_time_need_stored = false;
}
}
// <20><>ȡE1 E2 E4 E7<45>߽<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>
peek_queue_node_by_type(&global_queue, MSG_TYPE_AD_SAMPLING, &adc_item); // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>ADC<44><43><EFBFBD><EFBFBD>ֵ
if(remove_queue_node_by_type(&global_queue, MSG_TYPE_CARLIB_SAVE, &carlib_item)) // ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD>
{
switch(carlib_item.data.carlib_data.netcode)
{
case NETCODE_E1_CALIB:
ht24lc02_word_write(adc_item.data.adc_data.real_press, INDEX_E1_PRESS_LOW);
// <20><>˸OK<4F>Ʊ<EFBFBD>ʶ<EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD>
vOxygenEventGroupSetBits(&global_event, EVENT_OK_BLINK);
break;
case NETCODE_E2_CALIB:
ht24lc02_word_write(adc_item.data.adc_data.real_press, INDEX_E2_PRESS_HIGH);
// <20><>˸OK<4F>Ʊ<EFBFBD>ʶ<EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD>
vOxygenEventGroupSetBits(&global_event, EVENT_OK_BLINK);
break;
case NETCODE_E4_CALIB:
ht24lc02_word_write(adc_item.data.adc_data.real_elec, INDEX_E4_ELEC_HIGH);
// <20><>˸OK<4F>Ʊ<EFBFBD>ʶ<EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD>
vOxygenEventGroupSetBits(&global_event, EVENT_OK_BLINK);
break;
case NETCODE_E7_CALIB:
// <20><>Ҫ<EFBFBD>洢E7<45>߽<EFBFBD><DFBD><EFBFBD>ֵ
ht24lc02_word_write(adc_item.data.adc_data.real_220V, INDEX_E7_220V_LOW);
// <20><>˸OK<4F>Ʊ<EFBFBD>ʶ<EFBFBD><EFBFBD><E6B4A2><EFBFBD><EFBFBD>
vOxygenEventGroupSetBits(&global_event, EVENT_OK_BLINK);
break;
default:
break;
}
}
}
/************************ (C) COPYRIGHT YUWELL *****END OF FILE****/