Перейти к содержанию
    

Делаю проект на MEGA 168, использюю ICC. Пишу 4 слова в EEPROM, читаю только последнее записанное.Пример взял из даташита.В чем может быть проблема.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

После записи каждого байта неплохо бы дождаться окончания этой процедуры (около 8 мс).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Делаю проект на MEGA 168, использюю ICC. Пишу 4 слова в EEPROM, читаю только последнее записанное.Пример взял из даташита.В чем может быть проблема.

Без исходников сказать ничего нельзя!

Здесь уже неоднократно поднималась тема EEPROM

например http://electronix.ru/forum/index.php?showtopic=16140 (правда для IAR)

но там есть исходники их можно адаптировтаь

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Код такой

 

void EEPromWrite( unsigned int Addr, unsigned char Val )

{

macroGlobalIntDisable;

EEAR=Addr;

EEDR=Val;

 

//Write logical one to EEMPE

EECR|=(1<<EEMPE);

 

//Start eeprom write by setting EEPE

EECR|=(1<EEPE);

 

while(EECR&(1<<EEPE)){};

DelayMilliSec( 10 );

macroGlobalIntEnable;

macroToggleWatchdog;

 

return;

}

 

 

unsigned char EEPromRead( unsigned int Addr )

{

macroGlobalIntDisable;

 

 

 

//Setup nadress register

//EEAR=Addr;

EEARH=0x00;

EEARL=Addr;

 

//start eepromread by writing EERE

EECR|+(1<<EERE);

 

//Return data from Data register

//Wait for complection of previous read

while(EECR&(1<<EEPE)){};

macroGlobalIntEnable;

return EEDR;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

DelayMilliSec( 10 );

Совершенно лишняя процедура, я имел в виду совсем другое.

А именно

while(EECR&(1<<EEPE)){};

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При чтении не надо ждать окончания записи, тем более после установки бита EERE и запрещать прерывания не обязательно (если конечно в прерываниях вы не обращаетесь к EEPROM)

 

и что значит

EECR|+(1<<EERE);

 

может быть?

EECR|=(1<<EERE);

 

А еще при записи, прерывания луше разрешить до ожидания окончания записи и ждать при включенных прерываниях

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже в Этом

EEAR=Addr;

может быть ошибка.

EEAR обрабатывается как 16-битный регистр?

И вообще, проинспектируйте полученный после компиляции ассемблерный листинг (если это возможно в данной среде).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А не может ли быть следующего:

1.Читаете по указателю с последнего места записи - те указатель не возвращается к началу?

2.Пишете все по одному адресу - указатель не сдвигался?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А не может ли быть следующего:

1.Читаете по указателю с последнего места записи - те указатель не возвращается к началу?

2.Пишете все по одному адресу - указатель не сдвигался?

 

Прописал в макро номера страниц и при записе, и при чтении просто читаю макро и использую

 

EEPromWrite( EEPROM_SERID_BYTE0_ADDR,gSerialID[0]);

 

 

Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно.

Имелось в виду следующее: поскольку доступ к 16-битным регистрам 8-битным ядром осуществляется за две команды, то имеет значение очерёдность такого доступа, а именно:

- читать надо сначала младший, потом старший;

- писать надо сначала старший, потом младший;

- обращение должно быть ТОЛЬКО парным, т. е. не должно быть обращения к одной из двух половин без обращения ко второй.

Подробнее в описании в главе "Accessing 16-bit Registers".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно.

Имелось в виду следующее: поскольку доступ к 16-битным регистрам 8-битным ядром осуществляется за две команды, то имеет значение очерёдность такого доступа, а именно:

- читать надо сначала младший, потом старший;

- писать надо сначала старший, потом младший;

- обращение должно быть ТОЛЬКО парным, т. е. не должно быть обращения к одной из двух половин без обращения ко второй.

Подробнее в описании в главе "Accessing 16-bit Registers".

Это относится только к регистрам которые могут железом поменяться (таймеры) для адреса eeprom это не действует можно в любом порядке читать и писать!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уррра.заработалою.

 

Код

 

unsigned char EEPromRead( unsigned int Addr )

{

 

//Setup adress register

EEAR=(Addr&0xFF);

 

 

//start EEPOM read by writing EERE

SetBit(EECR,0);

 

//Return data from Data register

return EEDR;

}

 

void EEPromWrite( unsigned int Addr, unsigned char Val )

{

macroGlobalIntDisable;

EEAR = Addr; // Load address

EEDR = Val; // Load data to be written

 

 

 

//Set logical one to EEMPE

SetBit(EECR,2);

 

//Set logical one to EEPE

SetBit(EECR,1);

 

macroToggleWatchdog;

while(EECR&(1<<EEPE)){};

 

macroGlobalIntEnable;

 

return;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совет по оптимизации:

Код

 

unsigned char EEPromRead( unsigned int Addr )

{

unsigned char data;

 

macroGlobalIntDisable; // на тот случай если в каком-нибудь прерывании между

// следующими двумя строками кода поменяется

// содержимое EEAR

//Setup adress register

EEAR=(Addr&0xFF);

 

 

//start EEPOM read by writing EERE

SetBit(EECR,0);

data = EEDR;

macroGlobalIntEnable;

//Return data from Data register

return data;

}

 

void EEPromWrite( unsigned int Addr, unsigned char Val )

{

macroToggleWatchdog;

while(EECR&(1<<EEPE)){}; // Это лучше делать здесь, а не в конце,

// т. к. не всегда пишутся два байта подряд

macroGlobalIntDisable;

 

// а ещё лучше записать так:

// for (;;)

// {

// macroGlobalIntDisable;

// if (EECR&(1<<EEPE))

// macroGlobalIntEnable;

// else

// break;

// }

// в этом случае нахождение системы в состоянии

// с запрещёнными прерываниями будет минимальным

// Этот цикл желательно также вставить в начало

// функции EEPromRead вместо macroGlobalIntDisable

 

EEAR = Addr; // Load address

EEDR = Val; // Load data to be written

 

 

 

//Set logical one to EEMPE

SetBit(EECR,2);

 

//Set logical one to EEPE

SetBit(EECR,1);

 

macroGlobalIntEnable;

 

return;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно.

Имелось в виду следующее: поскольку доступ к 16-битным регистрам 8-битным ядром осуществляется за две команды, то имеет значение очерёдность такого доступа, а именно:

- читать надо сначала младший, потом старший;

- писать надо сначала старший, потом младший;

- обращение должно быть ТОЛЬКО парным, т. е. не должно быть обращения к одной из двух половин без обращения ко второй.

Подробнее в описании в главе "Accessing 16-bit Registers".

Это относится только к регистрам которые могут железом поменяться (таймеры) для адреса eeprom это не действует можно в любом порядке читать и писать!

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уррра.заработалою.

 

Код

 

unsigned char EEPromRead( unsigned int Addr )

{

 

//Setup adress register

EEAR=(Addr&0xFF);

 

 

//start EEPOM read by writing EERE

SetBit(EECR,0);

 

//Return data from Data register

return EEDR;

}

 

void EEPromWrite( unsigned int Addr, unsigned char Val )

{

macroGlobalIntDisable;

EEAR = Addr; // Load address

EEDR = Val; // Load data to be written

 

 

 

//Set logical one to EEMPE

SetBit(EECR,2);

 

//Set logical one to EEPE

SetBit(EECR,1);

 

macroToggleWatchdog;

while(EECR&(1<<EEPE)){};

 

macroGlobalIntEnable;

 

return;

}

Я пишу на ассемблере, но дело не в этом. Я когда-то тоже писал в EEPROM несколько байт подряд, ждал предыдущей записи. Когда байтов было 2 - все ОК. Но когда стало 4 - не работало. Я долго парился пока не обнаружил, что просто повторно срабатывает прерывание (запись шла внутри прерывания) - слишком долго это все.

Короче я сделал такую вещь - небольшая структура типа буфера, похожая на стек (но не совсем стек, скорее куча), состоит из тела, указателя, размера.

Тело - содержит пакеты из трех байт, два байта адрес и один байт данные, размер тела = 3*N байт, где N-размер тела в пакетах;

Указатель - 2 байта, содержат адрес вершины кучи;

Размер - 1 байт, содержит количество положенных пакетов в кучу. Если =0 - куча пустая.

Подпрограммы такие: ПОЛОЖИТЬ_В_КУЧУ и ОБСЛУЖИТЬ_КУЧУ. В начале программы кучу инициализировать - указатель на начало тела, размер=0.

ПОЛОЖИТЬ_В_КУЧУ вызывается в любом месте программы, где надо записать в EEPROM очередное число. Берет адрес, данные, ложит в кучу по указателю, передвигает указатель на 3, увеличивает размер на 1. На время работы с кучей запретить прерывания.

ОБСЛУЖИТЬ_КУЧУ вызывается сравнительно редко по прерыванию, проверяет размер кучи если =0 ничего не делает, иначе проверяет завершилась ли предыдущая запись в EEPROM, если нет - ничего не делает, если да - берет из кучи по указателю данные, адрес, направляет в регистры EEPROM, запускает запись, передвигает указатель на 3 обратно, уменьшает размер на 1. Все.

Вот такая штука значительно облегчила мне жизнь :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...