|
Как записать long int во флэш?, Закипаю, блин! |
|
|
|
Jan 9 2015, 18:20
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Первый вариант - разложить на байты и воспользоваться своим простым алгоритмом записи: Цитата unsigned char t1, t2, t3, t4; unsigned long int F, Freq = 103500; t1= (Freq); t2= (Freq>>8); t3= (Freq>>16); t4= (Freq>>24);
F = (t4<<24)|(t3<<16)|(t2<<8)|t1; t1 = sizeof(F); printf("\n%li",F); С успехом работает на компьютерном компиляторе С-Free(он 32-х разрядный), но нихрена не работает в AvrStudio, выдавая ошибку в строке F = (t4<<24)|(t3<<16)|(t2<<8)|t1;: ../main.c:84: warning: left shift count >= width of type. Подозреваю что это из - за разрядности. Второй вариант - воспользоваться стандартными средствами: Цитата void eeprom_write_dword ( uint32_t *addr , uint32_t value ) Но я не пойму что такое uint32_t *addr. По идее это должен быть адрес флэш, куда я пишу эти 4 байта. Тогда почему он 4-разрядный? Третий вариант - найти в памяти адрес это переменной и побайтово записать во флэш. Но я не знаю как это сделать. Помогите советом. Сделал так: Цитата char K; K = eeprom_read_byte ((uint8_t*) 0xff0); eeprom_write_dword ((uint32_t*)&K,Freq); K=K+4; eeprom_write_byte ((uint8_t*)0xff0,K); Пока не работает. Разбираюсь.
Сообщение отредактировал Димон Безпарольный - Jan 9 2015, 18:21
|
|
|
|
|
 |
Ответов
|
Jan 9 2015, 19:10
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Димон Безпарольный @ Jan 9 2015, 21:20)  Первый вариант - разложить на байты и воспользоваться своим простым алгоритмом записи:
С успехом работает на компьютерном компиляторе С-Free(он 32-х разрядный), но нихрена не работает в AvrStudio, выдавая ошибку в строке F = (t4<<24)|(t3<<16)|(t2<<8)|t1;: ../main.c:84: warning: left shift count >= width of type. Подозреваю что это из - за разрядности.
Второй вариант - воспользоваться стандартными средствами:
Но я не пойму что такое uint32_t *addr. По идее это должен быть адрес флэш, куда я пишу эти 4 байта. Тогда почему он 4-разрядный?
Третий вариант - найти в памяти адрес это переменной и побайтово записать во флэш. Но я не знаю как это сделать. Помогите советом.
Сделал так:
Пока не работает. Разбираюсь. Нужно тип приводить: Код F = ((uint32_t)t4<<24)|((uint32_t)t3<<16)|((uint32_t)t2<<8)|(uint32_t)t1; В противном случае сдвиг не имеет смысла. При помощи eeprom_write_dword ( uint32_t *addr , uint32_t value ) вы пишите 32 разрядное значение, соответственно адрес по которому это значение пишется должен быть указателем на 32битную величину. Для записи unsigned long нужно использовать eeprom_write_dword: Код #define K_EEPROM_ADDRESS 0x00 uint32_t K; // запись eeprom_write_dword((uint32_t*)K_EEPROM_ADDRESS,K); // чтение K=eeprom_read_dword((uint32_t*)K_EEPROM_ADDRESS);
|
|
|
|
|
Jan 9 2015, 19:29
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(psL @ Jan 9 2015, 22:10)  Нужно тип приводить: Код F = ((uint32_t)t4<<24)|((uint32_t)t3<<16)|((uint32_t)t2<<8)|(uint32_t)t1; В противном случае сдвиг не имеет смысла. Исчерпывающе. Спасибо. Первый вариант работает. Цитата(psL @ Jan 9 2015, 22:10)  При помощи eeprom_write_dword ( uint32_t *addr , uint32_t value ) вы пишите 32 разрядное значение, соответственно адрес по которому это значение пишется должен быть указателем на 32битную величину. Для записи unsigned long нужно использовать eeprom_write_dword: Код #define K_EEPROM_ADDRESS 0x00 uint32_t K; // запись eeprom_write_dword((uint32_t*)K_EEPROM_ADDRESS,K); // чтение K=eeprom_read_dword((uint32_t*)K_EEPROM_ADDRESS); Мне необходимо иметь во флэш - памяти не только массив uint32_t значений, но и индекс(количество значений). По нему я вычисляю адрес первой свободной ячейки: K=K+4; Значение это байтовое и пишется во флэш по адресу 0xff0. Вот тут я и запутался. Функция записи требует в качестве адреса указатель на uint32_t. А у меня K объявлена как char. И похоже что в (uint32_t*)&K я где - то ошибся. Не работает.
Сообщение отредактировал Димон Безпарольный - Jan 9 2015, 19:40
|
|
|
|
|
Jan 9 2015, 20:06
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Димон Безпарольный @ Jan 9 2015, 21:29)  Мне необходимо иметь во флэш - памяти Для начала вам нужно понять, что ЭСПЗУ (eeprom) и флеш - две совершенно разные вещи. функциями eeprom_write_xxxx() вы пишете в ЭСПЗУ. Цитата(Димон Безпарольный @ Jan 9 2015, 21:29)  Функция записи требует в качестве адреса указатель на uint32_t. А у меня K объявлена как char Тогда зачем вы для байта используете функцию eeprom_write_ dword()? Почитайте документацию чуть дальше и возьмите для этого байта функцию, предназначенную для записи байта.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 9 2015, 20:49
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Димон Безпарольный @ Jan 9 2015, 23:18)  А вот их количество умещается в байт. Он тоже должен хранится в EEPROM. есть функция записи байта eeprom_write_byte Код #define INDEX_EEPROM_ADDRESS 0xFF0
uint8_t index;
// запись eeprom_write_byte((uint8_t*) INDEX_EEPROM_ADDRESS, index); // чтение index=eeprom_read_byte((uint8_t*) INDEX_EEPROM_ADDRESS);
|
|
|
|
|
Jan 9 2015, 20:58
|
Знающий
   
Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247

|
Цитата(psL @ Jan 9 2015, 23:49)  есть функция записи байта eeprom_write_byte Код #define INDEX_EEPROM_ADDRESS 0xFF0
uint8_t index;
// запись eeprom_write_byte((uint8_t*) INDEX_EEPROM_ADDRESS, index); // чтение index=eeprom_read_byte((uint8_t*) INDEX_EEPROM_ADDRESS); Я в курсе. И она работает исправно. Но, прочитав этот байт индекса я должен его подставить в функцию чтения / записи dword. Вот тут и начинаются проблемы, поскольку эта функция требует в качестве адреса указатель на uint32_t. Я делал так: P = eeprom_read_dword ((uint32_t *)&J); Но это не работает.
|
|
|
|
|
Jan 10 2015, 12:45
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Димон Безпарольный @ Jan 9 2015, 22:58)  Вот тут и начинаются проблемы, поскольку эта функция требует в качестве адреса указатель на uint32_t. Проблемы от того, что вы не разобрались - что такое указатель и как он работает. Код #include <avr/eeprom.h>
typedef struct { uint8_t Index; uint32_t Frequency[]; } table_t;
table_t EEMEM Table;
void write_next(uint32_t frequency) { uint8_t Index = eeprom_read_byte(&Table.Index); ++Index; eeprom_write_dword(&Table.Frequency[Index], frequency); eeprom_write_byte(&Table.Index, Index); }
uint32_t read_last() { uint8_t Index = eeprom_read_byte(&Table.Index); return eeprom_read_dword(&Table.Frequency[Index]); }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|