Например TDA7294

Форум РадиоКот :: Просмотр темы - Проблемы с EEPROM AtMega16
Форум РадиоКот
https://radiokot.ru/forum/

Проблемы с EEPROM AtMega16
https://radiokot.ru/forum/viewtopic.php?f=57&t=147509
Страница 1 из 1

Автор:  Sebor [ Сб авг 12, 2017 21:42:04 ]
Заголовок сообщения:  Проблемы с EEPROM AtMega16

Здравствуйте уважаемые форумчане!
Прошу оказать содействия в части написания программы на языке Си, в среде AVR-Studio для AtMega16-PU, работающий на частоте 16 мГц в корпусе DIP-40.
Вкратце суть проблемы: имеется компьютерный блок питания переделанный под ИРН. Устанавливается нужное напряжение или ток энкодером. При нажатии на кнопку энкодера, выставленное напряжение фиксируется программным отключением опроса энкодера, тем самым исключается возможность случайно сбить выставленное напряжение или ток. Всё отлажено, всё работает, душа радуется. А что бы каждый раз не крутить ручку энкодера после подачи напряжения на ИРН, я решил сохранять текущее значение регистра OCR0, отвечающего за работу ШИМ, в EEPROM. В теории должно было быть так: нужно мне 12 Вольт, я выставляю, нажимаю кнопку фиксации напряжения, работа энкодера блокируется, а значение регистра OCR0 заносится в ПЗУ. Поработал, отключил питание, покурил, снова включаю ИРН и после инициализации программы и теста семисегментного индикатора, читаю из ПЗУ значение переменной и отправляю её в OCR0. В итоге у меня на выходе те же 12 В. И ничего крутить не надо.
На практике же не хочет он у меня ни записывать, как я понял, ни читать. Читает только один раз после прошивки, когда происходит сброс после программирования, причём значение переменной равно 0xFF, на основании чего я и делаю вывод, что туда ничего и не записывалось. Если же просто передёрнуть питание, то стартовое значение OCR0 равно 0, как будто у меня в программе и нет этих строк.
При запуске в симуляторе AVR-Studio всё работает как часы, в железе нет! Пример написания функций чтения и записи EEPROM взят из книги А. В. Евстифеева «Микроконтроллеры семейств Tiny и Mega фирмы ATMEL».
Ещё бы хотел заметить, что это моё не первое обращение к EEPROM. Делал я музыкальный звонок на AtMega16 + SD-card на 16 мелодий, там номер проигранного файла увеличивается на единицу и сохраняется в ПЗУ. При последующем включении, номер воспроизводимого файла читается из ПЗУ и так по кругу. Причём кроме:
#include "eeprom.h"
и двух строк
trek = eeprom_read_byte(0);//читаем содержимое переменной из ЕЕПРОМ
и
eeprom_write_byte(0, trek); // записываем новые данные в EEPROM
больше в программе ничего нет связанного с ПЗУ.
Код естественно не мой, сборный с просторов инета, немало я с ним тоже повозился, адаптируя, но всё работает уже как года два.
Тот же подход я применил и к текущей задаче, но выходит такой вот облом. Пошёл к Евстифееву, написал две функции один в один по его примерам:
//=========
//Функция чтения байта из EEPROM
//=========
void EEPROM_read(unsigned char Adres)
{
EEAR=Adres;// загрузить адрес используемой ячейки
EECR |=(1<<EERE);// установить бит разрешающий чтение
EncData= EEDR;// прочитать данные из ячейки
}
//=========
//Функция записи байта в EEPROM
//=========
void EEPROM_write(unsigned char Adres, unsigned char EncData)
{
EEAR=Adres;// загрузить адрес используемой ячейки
EEDR=EncData;//загрузить сохраняемые данные
EECR |=(1<<EEMWE);// установить бит разрешающий запись
EECR |=(1<<EEWE);// записать данные в ячейку
}
обращаюсь к ним из программы:
EEPROM_read(Adres);//читаем содержимое переменной из ЕЕПРОМ
и
EEPROM_write(Adres,EncData); // записываем текущее значение EncData в EEPROM
но, ничего это мне не дало.
Вот и прошу совета, может я что-то и упустил из виду. Сам уже не знаю, в какую сторону копать. Грешу ещё на МК, но он у меня впаян, поэтому и решил спросить совета, прежде чем выпаивать.
Извиняюсь, что много букв получилось. Спасибо!

Автор:  roman.com [ Сб авг 12, 2017 22:42:01 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

а ещё в даташите перед записью (чтением) байта в EEPROM рекомендуют сначала проверять окончание предыдущей записи в EEPROM...

while(EECR & 0b00000010); // Ожидаем окончание предыдущей записи // По окончании записи бит EEWE сбрасывается аппаратно.

кто его знает.. как часто вызываются функции...

void EEPROM_write ...
void EEPROM_read ...

Автор:  Z_h_e [ Вс авг 13, 2017 07:05:41 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

Sebor писал(а):
EECR |=(1<<EEMWE);// установить бит разрешающий запись
EECR |=(1<<EEWE);// записать данные в ячейку
Данная последовательность должна быть выполнена не более чем за 4 такта. При выключенной оптимизации скомпилируется скорее всего в большее. Кроме того надо выключить прерывания. Есть библиотечная функция, посмотрите ее.

Автор:  Ivanoff-iv [ Вс авг 13, 2017 16:41:29 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

хз, в кодевижне просто объявил переменную в еепроме и обращайся с ней как с обычной.
пс знаю, что не самая лучшая программа (в плане качества результата) но мне не в космос на ней летать — у меня на этот случай ассемблер. :)

Автор:  Sebor [ Вс авг 13, 2017 21:10:18 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

а ещё в даташите перед записью (чтением) байта в EEPROM рекомендуют сначала проверять окончание предыдущей записи в EEPROM...

while(EECR & 0b00000010); // Ожидаем окончание предыдущей записи // По окончании записи бит EEWE сбрасывается аппаратно.

кто его знает.. как часто вызываются функции...

void EEPROM_write ...
void EEPROM_read ...


Я обратил на это внимание, но думал, что отправляю всего один байт и только по нажатию кнопки. Так что бы не топтаться там ожидая, решил пропустить этот момент.
Дописал эти строки - результат нулевой.

Добавлено after 10 minutes 11 seconds:
Sebor писал(а):
EECR |=(1<<EEMWE);// установить бит разрешающий запись
EECR |=(1<<EEWE);// записать данные в ячейку
Данная последовательность должна быть выполнена не более чем за 4 такта. При выключенной оптимизации скомпилируется скорее всего в большее. Кроме того надо выключить прерывания. Есть библиотечная функция, посмотрите ее.


Честно сказать, никогда не обращал внимания на оптимизацию, т. к. не считаю себя таким уж программистом, да и не приходилось впихивать невпихуемое :)) . Как оказалось оптимизация на максимуме и просмотр кода в пошаговом режиме в дизассемблере показал, что так оно и есть. Про прерывания знаю и не забыл отключить перед вызовом функции с последующим включением.

Добавлено after 1 hour 39 minutes 58 seconds:
Всем привет! Вопрос решён, в том плане, что всё работает, как и было задумано. Осталось только вкурить-почему? Функция чтения из ПЗУ у меня вызывалась из подпрограммы тестирования индикатора
//=========
//Функция проверки индикатора
//=========
void TestSeg(void)
{
HighData=0x00;//включить все сегменты ст разряда
MidiData=0x00;//включить все сегменты ср разряда
LitlData=0x00;//включить все сегменты мл разряда
if(TimTest>=5000){
Dis_Fun &=~(1<<3);// отключить тест индикатора
Dis_Tim &=~(1<<2);// отключить таймер тестового режима
Dis_Tim |=(1<<0);//вкл таймер на работу энкодера
TimTest=0;
cli();
EEPROM_read(Adres);//читаем содержимое переменной из ЕЕПРОМ
EncData=EEDR;//
OCR0=EncData;// отпрвить в регистр ШИМ
sei();
}
}
На мой взгляд, вроде ничего криминального, но чтение как бы игнорировалось. Я попробовал перенести строки обращения к ПЗУ в самое начало программы, по окончании инициализации, перед тем как разрешить прерывания перед главным циклом программы. И всё как бы встало на свои места,
с каким напряжением блок выключил, с таким он и включился. В тонкостях попробую разобраться, если хватит сала в голове. Всем спасибо!

Автор:  Ярослав555 [ Ср ноя 15, 2017 13:50:15 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

хз, в кодевижне просто объявил переменную в еепроме и обращайся с ней как с обычной.
пс знаю, что не самая лучшая программа (в плане качества результата) но мне не в космос на ней летать — у меня на этот случай ассемблер. :)

В ИАРе так же в плане переменных, а качество компилятора получше.

Автор:  Dimon456 [ Ср ноя 15, 2017 16:28:44 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

Чтение
Спойлер
Код:
unsigned char EEPROM_read(unsigned int uiAddress)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEPE));
/* Set up address register */
EEAR = uiAddress;
/* Start eeprom read by writing EERE */
EECR |= (1<<EERE);
/* Return data from Data Register */
return EEDR;
}
Запись
Спойлер
Код:
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEPE));
/* Set up address and Data Registers */
EEAR = uiAddress;
EEDR = ucData;
/* Write logical one to EEMPE */
EECR |= (1<<EEMPE);
/* Start eeprom write by setting EEPE */
EECR |= (1<<EEPE);
}
Обратите внимание
Спойлер
Код:
/* Wait for completion of previous write */
while(EECR & (1<<EEPE));
и на
Код:
unsigned int uiAddress

Автор:  ARV [ Ср ноя 15, 2017 21:11:29 ]
Заголовок сообщения:  Re: Проблемы с EEPROM AtMega16

Z_h_e писал(а):
Есть библиотечная функция, посмотрите ее
безоговорочно правильный совет!

Страница 1 из 1 Часовой пояс: UTC + 3 часа
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/