2024-11-11 12:23 PM - edited 2024-11-12 04:16 AM
Microcontroller: STM32C031K6T6
I'm trying to make an interface so that the user can change the name of their environment in real time, my idea and what I tried to write is something that holds the previous strings (which may already be edited) in RAM, makes the modifications and then then write in flash again. Currently my code is like this, it shows the environments ("AMBIENTE 01...24"), I can edit the name of the string, it "saves" when i call Grava();, but when I turn my board off and on the changes do not continue...
I tried to copy the txtL strings to b_txtL using memcpy, and strncpy at the beginning of main();, but when i do this my my display goes "crazy" showing the strings "AMBIENTE ..." all broken in line 1 and 2
Note: I can't debug and at the same time see the changes that happen on the display because the SWCLK pin was used for a display pin, I had to implement a code that erased the memory after holding down some buttons to be able to record another code, workaround ...
const char txtL[][17] = {
" AMBIENTE L01 ", " AMBIENTE L02 ", " AMBIENTE L03 ",
" AMBIENTE L04 ", " AMBIENTE L05 ", " AMBIENTE L06 ",
" AMBIENTE L07 ", " AMBIENTE L08 ", " AMBIENTE L09 ",
" AMBIENTE L10 ", " AMBIENTE L11 ", " AMBIENTE L12 ",
" AMBIENTE L13 ", " AMBIENTE L14 ", " AMBIENTE L15 ",
" AMBIENTE L16 ", " AMBIENTE L17 ", " AMBIENTE L18 ",
" AMBIENTE L19 ", " AMBIENTE L20 ", " AMBIENTE L21 ",
" AMBIENTE L22 ", " AMBIENTE L23 ", " AMBIENTE L24 ",
" ENGFOX 24L "
}; // default flash text
char b_txtL[26][17]; //BUFFER
int main{
//lcd and gpios inits
EEPROM_INIT();
lerEeprom();
//button config and enters the prog
Prog();
//test to see if saved something
lcd_set_cursor(0, 0);
lcd_write_string2((const char*)txtL[0]);
lcd_set_cursor(0, 1);
lcd_write_string2((const char*)b_txtL[15]);
// Prog func
/* I'm using a eeprom_write function to write flags of 0 or 1, due to the limitation of my microcontroller I can only use DOUBLEWORD, which ends up recording a flag in 32 bits, and the next 32 bits are empty */
while (loop < 26) {
DisplayLaco(loop);
HAL_Delay(60);
if (HAL_GPIO_ReadPin(GPIOA, SW1_Pin) == GPIO_PIN_RESET)
{
HAL_Delay(200);
// Verifica o estado atual dos bits
int re_bit = (ure.re_all[loop / 8] & (1 << (loop % 8))) ? 1 : 0;
int rfl_bit = (urfl.rfl_all[loop / 8] & (1 << (loop % 8))) ? 1 : 0;
// Alterna entre as combinações S N, N S, N N, S S
if (re_bit && !rfl_bit)
{
// Caso atual seja S N -> Muda para N S
ure.re_all[loop / 8] &= ~(1 << (loop % 8)); // Desativa o bit em re_all
urfl.rfl_all[loop / 8] |= (1 << (loop % 8)); // Ativa o bit em rfl_all
}
else if (!re_bit && rfl_bit)
{
// Caso atual seja N S -> Muda para N N
ure.re_all[loop / 8] &= ~(1 << (loop % 8)); // Desativa o bit em re_all
urfl.rfl_all[loop / 8] &= ~(1 << (loop % 8)); // Desativa o bit em rfl_all
}
else if (!re_bit && !rfl_bit)
{
// Caso atual seja N N -> Muda para S S
ure.re_all[loop / 8] |= (1 << (loop % 8)); // Ativa o bit em re_all
urfl.rfl_all[loop / 8] |= (1 << (loop % 8)); // Ativa o bit em rfl_all
}
else
{
// Caso atual seja S S -> Muda para S N
ure.re_all[loop / 8] |= (1 << (loop % 8)); // Ativa o bit em re_all
urfl.rfl_all[loop / 8] &= ~(1 << (loop % 8)); // Desativa o bit em rfl_all
}
DisplayLaco(loop); // Atualiza o display
}
if (HAL_GPIO_ReadPin(GPIOA, SW2_Pin) == GPIO_PIN_RESET) {
HAL_Delay(200);
uoff.off_all[loop / 8] ^= (1 << (loop % 8));
DisplayLaco(loop);
}
if (HAL_GPIO_ReadPin(GPIOA, SW3_Pin) == GPIO_PIN_RESET) {
HAL_Delay(200);
Conf_txt(loop);
lcd_display_control(true, false, false);
DisplayLaco(loop);
loop++;
}
}
dcBKL_ch2(200);
}
//Display func (Maybe the trouble is here, idk)
void DisplayLaco(int loop)
{
// Exibe informações sobre o laço atual e o nome correspondente
char nomeL[20];
snprintf(nomeL, sizeof(nomeL), "L%02d:", loop + 1);
lcd_set_cursor(0, 0);
lcd_write_string(nomeL);
lcd_write_string((uoff.off_all[loop / 8] & (1 << (loop % 8))) ? "S " : "N ");
lcd_write_string((ure.re_all[loop / 8] & (1 << (loop % 8))) ? "RE:S " : "RE:N ");
lcd_write_string((urfl.rfl_all[loop / 8] & (1 << (loop % 8))) ? "RFL:S" : "RFL:N");
// Exibe o nome do ambiente correspondente (da RAM)
lcd_set_cursor(0, 1);
// Copiar as strings de b_txtL para txtL (presumindo que b_txtL foi modificado)
lcd_write_string(b_txtL[loop]); // `b_txtL[loop]` já deve estar em `char[]`
}
// Conf_txt func, it's a bit buggy, I'm trying to solve it...
void Conf_txt(uint16_t loop)
{
// Permite a edição em tempo real do nome selecionado em b_txtL
bool edit = true;
// Posição do caractere dentro do nome
uint8_t pressCounter = 0;
uint8_t col = 0;
// Exibe o nome inicial na LCD
lcd_write_string2((const char*)b_txtL[loop]);
lcd_set_cursor(col, 1); // Coloca o cursor na posição inicial
while (edit)
{
lcd_display_control(true, true, true);
lcd_set_cursor(col, 1); // Atualiza a posição do cursor
bool SW3 = (HAL_GPIO_ReadPin(GPIOA, SW3_Pin) == GPIO_PIN_RESET);
// Pressão longa do SW3 para sair do modo de edição
if (SW3)
{
pressCounter++; // Incrementa o contador
if (pressCounter >= 15) // 3 segundos (ajuste conforme necessário)
{
edit = false;
lcd_display_control(true, false, false);
Grava();
return;
}
}
else
{
pressCounter = 0; // Resetando o contador após uma ação
col++; // Avança para a próxima coluna
lcd_set_cursor(col, 1);
if (col >= 16)
{
col = 0;
}
}
// Controle de incremento e decremento do caractere na posição atual
if (HAL_GPIO_ReadPin(GPIOA, SW1_Pin) == GPIO_PIN_RESET)
{
HAL_Delay(200);
b_txtL[loop][col]++;
if (b_txtL[loop][col] > 0x5A) b_txtL[loop][col] = 0x30; // "Z" -> "0"
else if (b_txtL[loop][col] < 0x30) b_txtL[loop][col] = 0x41; // " " -> "A"
else if (b_txtL[loop][col] > 0x39 && b_txtL[loop][col] < 0x41) b_txtL[loop][col] = 0x20; // "9" -> " "
lcd_write_string2((const char*)b_txtL[loop]); // Atualiza o caractere na posição do cursor
}
if (HAL_GPIO_ReadPin(GPIOA, SW2_Pin) == GPIO_PIN_RESET)
{
HAL_Delay(200);
b_txtL[loop][col]--;
if (b_txtL[loop][col] < 0x20) b_txtL[loop][col] = 0x39; // " " -> "9"
else if (b_txtL[loop][col] < 0x30) b_txtL[loop][col] = 0x5A; // "0" -> "Z"
else if (b_txtL[loop][col] > 0x39 && b_txtL[loop][col] < 0x41) b_txtL[loop][col] = 0x20; // "A" -> " "
lcd_write_string2((const char*)b_txtL[loop]); // Atualiza o caractere na posição do cursor
}
HAL_Delay(200);
}
}
// Then, after i call grava(); function to write the changes in the eeprom
for (int i = 0; i < 26; i++) // i is my ID
{
EEPROM_WRITE_STRING(i, b_txtL[i]);
}
// EEPROM write stirng.
void EEPROM_WRITE_STRING(uint16_t id, const char* c)
{
HAL_Delay(10); // Pode ser ajustado conforme necessário
HAL_FLASH_Unlock(); // Desbloqueia a memória FLASH para gravação
uint32_t address = ACTIVE_PAGE; // Começa no endereço da última gravação
// Verifica o comprimento da string
int str_len = strlen(c);
if (str_len > 17) str_len = 17; // Limita o comprimento a 17 caracteres (tamanho máximo da string)
// Garantir que o endereço está alinhado a 8 bytes
if (address % 8 != 0)
{
address += 8 - (address % 8); // Ajuste de alinhamento
}
// Grava a string na Flash em blocos de 8 bytes
for (int offset = 0; offset < str_len; offset += 8)
{
uint64_t data_to_write = 0;
// Preenche os próximos 8 bytes (ou menos, se a string terminar antes)
for (int i = 0; i < 8; i++)
{
if (offset + i < str_len) {
data_to_write |= ((uint64_t)c[offset + i]) << (i * 8);
}
}
// Grava os dados na memória FLASH
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data_to_write);
address += 8; // Avança para o próximo endereço
}
if (address >= (ACTIVE_PAGE + PAGE_SIZE - sizeof(EEPROM)))
{EEPROM_SWAP();}
HAL_FLASH_Lock(); // Bloqueia a memória FLASH após a gravação
}
void EEPROM_READ_STRING(uint16_t id, char* c)
{
uint32_t address = ACTIVE_PAGE + (id * sizeof(EEPROM)); // Endereço baseado no ID
uint64_t data_read = 0;
// Lê os dados da memória FLASH em blocos de 8 bytes
while (address < (ACTIVE_PAGE + PAGE_SIZE))
{
EEPROM* entry = (EEPROM*)address;
if (entry->id == id)
{
for (int offset = 0; offset < 17; offset += 16)
{
data_read = *(volatile uint64_t*)address;
// Copia os dados lidos de volta para a string
memcpy(&c[offset], &data_read, (offset + 8 <= 17) ? 8 : (17 - offset));
address += 8; // Avança para o próximo endereço
}
}
address += sizeof(EEPROM);
}
}
Solved! Go to Solution.
2024-11-13 06:52 AM
It was actually @Andrew Neil who said first that flash must be erased before writing, so maybe mark his answer as solution.
Although I guess "in the end it doesn't really matter", as who sang? ;)
2024-11-15 10:25 PM
hello iam using srm32f429i-disc1 microcontroller and i want refrence code for emulated eeprom
2024-11-16 03:04 AM
@syedhashmiraza you already have your own thread on this:
This thread is about a different, much newer chip - not relevant to yours.