реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Mega48-20 не пишет в EEPROM, Что я забыл?
smk
сообщение Dec 16 2014, 07:47
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Давно уже с АВРками дела не имел может что-то не так. Есть устройство с Mega48-20. Тактовая 4 МГц. Фуз еепрома стоит правильно, запись разрешена. Функции чтения-записи из даташита. Не пишет в еепром, в т.ч. и на симуляторе тоже. Что это может быть, что я забыл? Прерывания запрещаю. Пишется из главного цикла. Читать получается (0хFF).

Код
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<<EEPE); /* Start eeprom write by setting EEPE */
}

unsigned char EEPROM_read(unsigned int Address)
{
  while(EECR & (1<<EEPE)); /* Wait for completion of previous write */
  EEAR = Address; /* Set up address register */
  EECR |= (1<<EERE); /* Start eeprom read by writing EERE */
  return EEDR; /* Return data from Data Register */
}

    while(1)
    {
    if(mode)
    {
      PORTC = 0b00010000;
      delay(30000);
      PORTC = 0b00000000;
      delay(30000);
    }

    if(mem)
    {
      asm("cli");      
      EEPROM_write(0x0A, mode);
      EEPROM_write(0x0B, output);
      mem = 0;
      asm("sei");
    }
    //проверить питание
    }//while


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 16 2014, 08:00
Сообщение #2


Гуру
******

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



Код
EECR |= (1<<EEMPE); /* Write logical one to EEMPE */
EECR |= (1<<EEPE); /* Start eeprom write by setting EEPE */
Между установкой EEMPE и установкой EEPE должно пройти не более 4 тактов. Посмотрите, во что вылились эти операторы с вашими настройками компилятора. А чтобы работало железно - не используйте тут '|='. Вы ведь точно знаете сотояние всех остальных битов, вот и пишите каждый раз все биты через '='.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 16 2014, 08:56
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 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. Если включить другую, то код ужимается раза в два и более при этом перестает работать. Что-то я упускаю в своем понимании. А как кстати тогда правильно если не использовать '|='?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Dec 16 2014, 09:01
Сообщение #4


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(smk @ Dec 16 2014, 11:56) *
Компилятор GCC. Кстати оптимизация О0. Если включить другую, то код ужимается раза в два и более при этом перестает работать. Что-то я упускаю в своем понимании. А как кстати тогда правильно если не использовать '|='?


У вас все правильно написано. Непонятно, почему не работает. Возможно, ошибка вкралась в какое-то другое место - там, где вы делаете проверку или mem у вас никогда не бывает единичным. Последние предположения постороннему человеку проверить мудрено, т.к. вы привели лишь отрывки, в которых этих мест нет.
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 16 2014, 09:04
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(Xenia @ Dec 16 2014, 11:01) *
У вас все правильно написано. Непонятно, почему не работает. Возможно, ошибка вкралась в какое-то другое место - там, где вы делаете проверку или mem у вас никогда не бывает единичным. Последние предположения постороннему человеку проверить мудрено, т.к. вы привели лишь отрывки, в котороых этого места нет.

Бывает единицей. Проверял. Сам ничего не понимаю. Могу весь проект выложить. Он не большой. Еепром нужна чтоб запомнить последние настройки после нажатия кнопок. Прикрепленный файл  t.rar ( 18.63 килобайт ) Кол-во скачиваний: 47


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 16 2014, 09:08
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 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)
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 16 2014, 09:11
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 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 */
}


Спасибо. Только я теперь не пойму что они в даташитах пишут и зачем? Раньше, помню, работало.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 16 2014, 09:54
Сообщение #8


Гуру
******

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



Цитата(smk @ Dec 16 2014, 11:11) *
Только я теперь не пойму что они в даташитах пишут и зачем?
Это вы еще примеров в даташитах от ST не видели sm.gif


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 16 2014, 12:17
Сообщение #9


Шаман
******

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



Цитата(smk @ Dec 16 2014, 11:11) *
Спасибо. Только я теперь не пойму что они в даташитах пишут и зачем? Раньше, помню, работало.

Это зависит от Вашего понимания даташитов. Если там пишут "установить бит в 1", то это вовсе не означает, что это надо делать операцией |=.
А вот по поводу количества тактов между операциями сказано вполне ясно.
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 16 2014, 12:40
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(IgorKossak @ Dec 16 2014, 14:17) *
Это зависит от Вашего понимания даташитов. Если там пишут "установить бит в 1", то это вовсе не означает, что это надо делать операцией |=.
А вот по поводу количества тактов между операциями сказано вполне ясно.

Ну а какой операцией?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Bear_ku
сообщение Dec 16 2014, 12:45
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 9-09-11
Пользователь №: 67 076



Нашел старую программу для ATmega128, все было сделано по ДШ и именно с "|=", работает без нареканий.

Сообщение отредактировал Bear_ku - Dec 16 2014, 12:45
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Dec 16 2014, 13:43
Сообщение #12


Шаман
******

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



Цитата(smk @ Dec 16 2014, 14:40) *
Ну а какой операцией?

Операцией присваивания, как и советовал Сергей Борщ.

Цитата(Bear_ku @ Dec 16 2014, 14:45) *
Нашел старую программу для ATmega128, все было сделано по ДШ и именно с "|=", работает без нареканий.

Листинг кода посмотрите. В Вашем случае могла быть некоторая неявная оптимизация, например, битовыми операциями (не помню, попадают ли эти регистры для работы с ними битовыми операциями). Но в любом случае следует избегать непереносимого кода и зависеть от трюков конкретной версии компилятора.
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 16 2014, 14:31
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(IgorKossak @ Dec 16 2014, 15:43) *
Операцией присваивания, как и советовал Сергей Борщ.


Листинг кода посмотрите. В Вашем случае могла быть некоторая неявная оптимизация, например, битовыми операциями (не помню, попадают ли эти регистры для работы с ними битовыми операциями). Но в любом случае следует избегать непереносимого кода и зависеть от трюков конкретной версии компилятора.

Да, компилятор я понимаю, это может быть причиной. А присваивание это я так понимаю состоит из трех этапов. Сначала вычитать, потом изменить и прописать обратно. В STM регистры специально заточены под присваивание. Но там обстоятельства таковы что это допустимо. Может Вы имеете в виду операции типа REGISTR |= 0x01; ?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 16 2014, 14:55
Сообщение #14


Гуру
******

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



Откровенно говоря - не стоит полагаться на компилятор, когда речь идет о жестких времянках. Сегодня он соберет правильно, а оптимизатор следующей версии посчитает нужным вставить между этими командами несколько других. Формально никто ему этого запретить не может. Поэтому iar для подобных операций имеет встроенные функции записи в eeprom, а gcc - библиотечные, написанные на инлайн-асме. Вот уж внутрь этих функций точно ничего не попадет и эти функции будут работать всегда, независимо ни от настроек компиоятора, ни от его версии. Примеры кода в даташите скорее чисто информационные.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
smk
сообщение Dec 16 2014, 19:14
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 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

Вот такое предупреждение. Что опять не так? Указатель нужен?

Все заработало, Спасибо! Однако с предупреждением не вполне ясно и чую включу оптимизацию (хоть и нет нужды) но работать перестанет. Отпишусь...


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 15:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01481 секунд с 7
ELECTRONIX ©2004-2016