glebka 1 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба Делаю проект на MEGA 168, использюю ICC. Пишу 4 слова в EEPROM, читаю только последнее записанное.Пример взял из даташита.В чем может быть проблема. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба После записи каждого байта неплохо бы дождаться окончания этой процедуры (около 8 мс). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба Делаю проект на MEGA 168, использюю ICC. Пишу 4 слова в EEPROM, читаю только последнее записанное.Пример взял из даташита.В чем может быть проблема. Без исходников сказать ничего нельзя! Здесь уже неоднократно поднималась тема EEPROM например http://electronix.ru/forum/index.php?showtopic=16140 (правда для IAR) но там есть исходники их можно адаптировтаь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glebka 1 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба Код такой 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба DelayMilliSec( 10 ); Совершенно лишняя процедура, я имел в виду совсем другое. А именно while(EECR&(1<<EEPE)){}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба При чтении не надо ждать окончания записи, тем более после установки бита EERE и запрещать прерывания не обязательно (если конечно в прерываниях вы не обращаетесь к EEPROM) и что значит EECR|+(1<<EERE); может быть? EECR|=(1<<EERE); А еще при записи, прерывания луше разрешить до ожидания окончания записи и ждать при включенных прерываниях Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба Похоже в Этом EEAR=Addr; может быть ошибка. EEAR обрабатывается как 16-битный регистр? И вообще, проинспектируйте полученный после компиляции ассемблерный листинг (если это возможно в данной среде). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
beer_warrior 0 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба А не может ли быть следующего: 1.Читаете по указателю с последнего места записи - те указатель не возвращается к началу? 2.Пишете все по одному адресу - указатель не сдвигался? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glebka 1 4 июля, 2006 Опубликовано 4 июля, 2006 · Жалоба А не может ли быть следующего: 1.Читаете по указателю с последнего места записи - те указатель не возвращается к началу? 2.Пишете все по одному адресу - указатель не сдвигался? Прописал в макро номера страниц и при записе, и при чтении просто читаю макро и использую EEPromWrite( EEPROM_SERID_BYTE0_ADDR,gSerialID[0]); Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба ...Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно. Имелось в виду следующее: поскольку доступ к 16-битным регистрам 8-битным ядром осуществляется за две команды, то имеет значение очерёдность такого доступа, а именно: - читать надо сначала младший, потом старший; - писать надо сначала старший, потом младший; - обращение должно быть ТОЛЬКО парным, т. е. не должно быть обращения к одной из двух половин без обращения ко второй. Подробнее в описании в главе "Accessing 16-bit Registers". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба ...Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно. Имелось в виду следующее: поскольку доступ к 16-битным регистрам 8-битным ядром осуществляется за две команды, то имеет значение очерёдность такого доступа, а именно: - читать надо сначала младший, потом старший; - писать надо сначала старший, потом младший; - обращение должно быть ТОЛЬКО парным, т. е. не должно быть обращения к одной из двух половин без обращения ко второй. Подробнее в описании в главе "Accessing 16-bit Registers". Это относится только к регистрам которые могут железом поменяться (таймеры) для адреса eeprom это не действует можно в любом порядке читать и писать! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
glebka 1 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба Уррра.заработалою. Код 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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба Совет по оптимизации: Код 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 0 5 июля, 2006 Опубликовано 5 июля, 2006 · Жалоба ...Вопрос к IgorKossak если можно по поддробней про обработку адресса,как это сделать правильно. Имелось в виду следующее: поскольку доступ к 16-битным регистрам 8-битным ядром осуществляется за две команды, то имеет значение очерёдность такого доступа, а именно: - читать надо сначала младший, потом старший; - писать надо сначала старший, потом младший; - обращение должно быть ТОЛЬКО парным, т. е. не должно быть обращения к одной из двух половин без обращения ко второй. Подробнее в описании в главе "Accessing 16-bit Registers". Это относится только к регистрам которые могут железом поменяться (таймеры) для адреса eeprom это не действует можно в любом порядке читать и писать! Согласен, здесь это не актуально, но чтобы не плодить правила и когда-нибудь не ошибиться в связи с этим, я бы следовал этому правилу всегда. Тем более, что это не накладно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Crystaly 0 7 июля, 2006 Опубликовано 7 июля, 2006 · Жалоба Уррра.заработалою. Код 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. Все. Вот такая штука значительно облегчила мне жизнь :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться