728x90
반응형

내가 사용하는 코드.

#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();
}

728x90
반응형

'프로그램 > ST 32Bit' 카테고리의 다른 글

STM32CubeIDE Multiple definition 에러 해결 방법  (0) 2024.11.08
STM32L MCU 터치 사용  (0) 2024.05.25
터치 인식 조절  (0) 2024.01.02
STM32L072 터치 감도 및 인식 속도 조절  (0) 2023.10.27

+ Recent posts