|
Mega48-20 не пишет в EEPROM, Что я забыл? |
|
|
|
Dec 16 2014, 08:56
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата(Сергей Борщ @ Dec 16 2014, 10:00)  Код EECR |= (1<<EEMPE); /* Write logical one to EEMPE */ EECR |= (1<<EEPE); /* Start eeprom write by setting EEPE */ Между установкой EEMPE и установкой EEPE должно пройти не более 4 тактов. Посмотрите, во что вылились эти операторы с вашими настройками компилятора. А чтобы работало железно - не используйте тут '|='. Вы ведь точно знаете сотояние всех остальных битов, вот и пишите каждый раз все биты через '='. Компилятор GCC. Кстати оптимизация О0. Если включить другую, то код ужимается раза в два и более при этом перестает работать. Что-то я упускаю в своем понимании. А как кстати тогда правильно если не использовать '|='?
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Dec 16 2014, 09:08
|

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

|
Цитата(smk @ Dec 16 2014, 10:56)  Компилятор GCC. Тогда используйте <avr/eeprom.h> и описанные в нем eeprom_write_byte(), eeprom_read_byte(). Там все проблемы времянок решены для всех уровней оптимизации: Код #include <avr/eeprom.h>
void test() { eeprom_write_byte((uint8_t *)0x0A, mode); } Цитата(smk @ Dec 16 2014, 10:56)  А как кстати тогда правильно если не использовать '|='? примерно так: Код void EEPROM_write(unsigned int Address, unsigned char Data) { while(EECR & (1<<EEPE)) /* Wait for completion of previous write */ ; EEAR = Address; /* Set up address and Data Registers */ EEDR = Data; EECR = (1<<EEMPE); /* Write logical one to EEMPE */ EECR = (1<<EEMPE)|(1<<EEPE); /* Start eeprom write by setting EEPE */ }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Dec 16 2014, 09:11
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата(Сергей Борщ @ Dec 16 2014, 11:08)  Тогда используйте <avr/eeprom.h> и описанные в нем eeprom_write_byte(), eeprom_read_byte(). Там все проблемы времянок решены для всех уровней оптимизации: Код #include <avr/eeprom.h>
void test() { eeprom_write_byte((uint8_t *)0x0A, mode); } примерно так: Код void EEPROM_write(unsigned int Address, unsigned char Data) { while(EECR & (1<<EEPE)) /* Wait for completion of previous write */ ; EEAR = Address; /* Set up address and Data Registers */ EEDR = Data; EECR = (1<<EEMPE); /* Write logical one to EEMPE */ EECR = (1<<EEMPE)|(1<<EEPE); /* Start eeprom write by setting EEPE */ } Спасибо. Только я теперь не пойму что они в даташитах пишут и зачем? Раньше, помню, работало.
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Dec 16 2014, 13:43
|

Шаман
     
Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221

|
Цитата(smk @ Dec 16 2014, 14:40)  Ну а какой операцией? Операцией присваивания, как и советовал Сергей Борщ. Цитата(Bear_ku @ Dec 16 2014, 14:45)  Нашел старую программу для ATmega128, все было сделано по ДШ и именно с "|=", работает без нареканий. Листинг кода посмотрите. В Вашем случае могла быть некоторая неявная оптимизация, например, битовыми операциями (не помню, попадают ли эти регистры для работы с ними битовыми операциями). Но в любом случае следует избегать непереносимого кода и зависеть от трюков конкретной версии компилятора.
|
|
|
|
|
Dec 16 2014, 14:31
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата(IgorKossak @ Dec 16 2014, 15:43)  Операцией присваивания, как и советовал Сергей Борщ.
Листинг кода посмотрите. В Вашем случае могла быть некоторая неявная оптимизация, например, битовыми операциями (не помню, попадают ли эти регистры для работы с ними битовыми операциями). Но в любом случае следует избегать непереносимого кода и зависеть от трюков конкретной версии компилятора. Да, компилятор я понимаю, это может быть причиной. А присваивание это я так понимаю состоит из трех этапов. Сначала вычитать, потом изменить и прописать обратно. В STM регистры специально заточены под присваивание. Но там обстоятельства таковы что это допустимо. Может Вы имеете в виду операции типа REGISTR |= 0x01; ?
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Dec 16 2014, 19:14
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Код ../trsm_m48.c:21: warning: passing argument 1 of '__eerd_byte_m48' makes pointer from integer without a cast Вот такое предупреждение. Что опять не так? Указатель нужен? Все заработало, Спасибо! Однако с предупреждением не вполне ясно и чую включу оптимизацию (хоть и нет нужды) но работать перестанет. Отпишусь...
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|