내가 사용하는 코드.
#define FLASH_START_ADDRESS 0x0800FC00
#define FLASH_SAVE_TIME 5000 //5SEC
typedef struct
{
uint8_t fan_save; //fan level
uint8_t Heater_save; // bit1 : heater2, bit0 : heater1
uint8_t power_save;
uint8_t auto_save;
int8_t temp1;
int8_t temp2;
_Bool heater_enable_flag;
sensortypeenum sensor_type;
}flashstruct;
void flash_erase(void)
{
uint32_t PageError;
__IO uint32_t data32 = 0, MemoryProgramStatus = 0;
HAL_FLASH_Unlock();
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = FLASH_START_ADDRESS;
EraseInitStruct.NbPages = 1;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
{
Error_Handler();
}
HAL_FLASH_Lock();
}
void flash_read(void)
{
flashstruct t;
memcpy(&t, (flashstruct*)FLASH_START_ADDRESS, sizeof(t));
memcpy(&flash, &t, sizeof(t));
}
void flash_save_process(void)
{
unsigned int* p_w = (unsigned int*)&flash;
int byte_align = 0;
if (sys.flash_save_count <= FLASH_SAVE_TIME) sys.flash_save_count++;
if (sys.flash_save_count == FLASH_SAVE_TIME)
{
flashstruct x;
memcpy(&x, &flash, sizeof(flash));
flash_read();
if (memcmp(&x, &flash, sizeof(flash)) != NULL)
{
memcpy(&flash, &x, sizeof(x));
if ((sizeof(flash) % 4) > 0) byte_align = 1; //구조체가 64비트 단위가 아닌경우 마지막 떨거지들에 대한 처리
flash_erase();
HAL_FLASH_Unlock();
for (int i = 0; i < sizeof(flash) / 4 + byte_align; i++)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (FLASH_START_ADDRESS + (i * 4)), p_w[i]);
}
HAL_FLASH_Lock();
}
}
}
------------------------------------------------------------------------------------
다음은 Github copilot이 만든 코드
static FLASH_EraseInitTypeDef EraseInitStruct = {0};
flashstruct flash;
static uint32_t flash_save_counter = 0;
void flash_erase(void)
{
uint32_t PageError;
HAL_FLASH_Unlock();
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.Sector = FLASH_SECTOR_7;
EraseInitStruct.NbSectors = 1;
EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
{
Error_Handler();
}
HAL_FLASH_Lock();
}
void flash_read(void)
{
flashstruct temp;
memcpy(&temp, (flashstruct*)FLASH_START_ADDRESS, sizeof(temp));
memcpy(&flash, &temp, sizeof(temp));
}
void flash_save_process(void)
{
unsigned int* p_data = (unsigned int*)&flash;
int byte_align = 0;
if (flash_save_counter <= FLASH_SAVE_TIME)
flash_save_counter++;
if (flash_save_counter == FLASH_SAVE_TIME)
{
flashstruct temp;
flash.key = FLASH_KEY;
memcpy(&temp, &flash, sizeof(flash));
// 현재 저장된 값과 비교
flash_read();
if (memcmp(&temp, &flash, sizeof(flash)) != 0)
{
memcpy(&flash, &temp, sizeof(temp));
// 4바이트 정렬 체크
if ((sizeof(flash) % 4) > 0)
byte_align = 1;
flash_erase();
HAL_FLASH_Unlock();
// 4바이트 단위로 프로그래밍
for (int i = 0; i < sizeof(flash) / 4 + byte_align; i++)
{
HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
(FLASH_START_ADDRESS + (i * 4)),
p_data[i]);
}
HAL_FLASH_Lock();
}
flash_save_counter = 0;
}
}
void LoadSettings(void)
{
flash_read();
// 유효성 검사
if(flash.key == FLASH_KEY) {
start_temp = flash.start_temp;
sysState.heater1.tempSet = flash.heater1_temp;
sysState.heater2.tempSet = flash.heater2_temp;
// 범위 검증
if(start_temp < START_TEMP_MIN || start_temp > START_TEMP_MAX)
start_temp = 0.0f;
if(sysState.heater1.tempSet < TEMP_MIN || sysState.heater1.tempSet > TEMP_MAX)
sysState.heater1.tempSet = TEMP_DEFAULT;
if(sysState.heater2.tempSet < TEMP_MIN || sysState.heater2.tempSet > TEMP_MAX)
sysState.heater2.tempSet = TEMP_DEFAULT;
}
else {
// 기본값 설정
start_temp = 0.0f;
sysState.heater1.tempSet = TEMP_DEFAULT;
sysState.heater2.tempSet = TEMP_DEFAULT;
}
}
void SaveSettings(void)
{
flash.start_temp = start_temp;
flash.heater1_temp = sysState.heater1.tempSet;
flash.heater2_temp = sysState.heater2.tempSet;
flash_save_process();
}
'프로그램 > ST 32Bit' 카테고리의 다른 글
STM32CubeIDE Multiple definition 에러 해결 방법 (0) | 2024.11.08 |
---|---|
STM32L MCU 터치 사용 (0) | 2024.05.25 |
터치 인식 조절 (0) | 2024.01.02 |
STM32L072 터치 감도 및 인식 속도 조절 (0) | 2023.10.27 |