STM32 как записать float в backup регистр.
Несколько раз мне задавали вопрос, как записать переменную типа float в внешнюю eeprom память или в backup регистры. Этот вопрос мне показался интересным, по этому решил ответить на него в статье.
Как известно, у STM32 один backup регистр вмещает в себя 16 бит, а переменная типа float содержит 32 бита. Получается для того, чтобы сохранить одну переменную типа float, нам понадобится 2 backup регистра.
Первое, что приходит в голову это сделать так.
Но компилятор ругается на этот код и пишет, что операция сдвига не может применяться для переменной типа float.
Раз не получается так, воспользуемся всеми любимыми указателями.
А этот код отлично работает.
Собирается переменная float, опять же с помощью указателя.
Тут опять же возникает вопрос, почему нельзя просто привести к типу float?
А надо приводить к указателю типа float, а только потом его разыменовывать?
Дело в том, что простое приведение к типу или добавляет нули или обрезает лишние цифры!!!!
А приведение к типу указателя, говорит компилятору как трактовать данные по указанному адресу.
Как известно, у STM32 один backup регистр вмещает в себя 16 бит, а переменная типа float содержит 32 бита. Получается для того, чтобы сохранить одну переменную типа float, нам понадобится 2 backup регистра.
Первое, что приходит в голову это сделать так.
float f;
BKP->DR1 = f;//сохраняем младшие 16 бит
BKP->DR2 = f>>16;//сохраняем старшие 16 бит
Но компилятор ругается на этот код и пишет, что операция сдвига не может применяться для переменной типа float.
Раз не получается так, воспользуемся всеми любимыми указателями.
float f;
uint16_t* tmp;
tmp = (uint16_t*) &f;
BKP->DR1 = *tmp;
BKP->DR2 = *(tmp+1);
А этот код отлично работает.
Собирается переменная float, опять же с помощью указателя.
uint32_t value;
float f;
value = (BKP->DR2<<16 | BKP->DR1);
f = *(float*)&value;
Тут опять же возникает вопрос, почему нельзя просто привести к типу float?
f = (float)value;//так работать не будет
А надо приводить к указателю типа float, а только потом его разыменовывать?
Дело в том, что простое приведение к типу или добавляет нули или обрезает лишние цифры!!!!
uint8_t->uint32_t//добавляет нули
uint32_t->uint8_t//обрезает лишние цифры
А приведение к типу указателя, говорит компилятору как трактовать данные по указанному адресу.
Похожие статьи