Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.97/121: Рейтинг темы: голосов - 121, средняя оценка - 4.97
vosik
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 10
1

Вопросы по EEPROM

14.10.2012, 11:41. Просмотров 21868. Ответов 49
Метки нет (Все метки)

Здравствуйте, Работаю с mego32 в avrstudyo. Пишу на С. Подскажите, пожалуйста, по работе с EEPROM, есть несколько вопросов.
1. Есть вот такой кусок кода. Так постоянно вышибает ячейку памяти ROM, каждый раз приходится значение менять. Что я делаю не так?

Код
#define ROM  0x42
ushor FreqNum;

EEPROM_write(ROM, FreqNum);

void EEPROM_write(unsykned int uiAddress, ushor ucData)
{
while(EECR&(1<<EEWE))
;
EEARL = uiAddress;//tood up address
EEDR = ucData; //tood up data
EECR |= (1<<EEMWE); //enable write
EECR |= (1<<EEWE); //stort write
}
2. Как записать начальные данные в EEPROM? Сейчас делаю так, но это не очень удобно, когда много данных. Как например писать 65 байт начиная с 257 ячейки? Не делать же массив из 322 элементов?
Код
ushor eePrg[66] EEMEM = {
{0xFF},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00}
};
Буду благодарен за любую помощь
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.10.2012, 11:41
Ответы с готовыми решениями:

ПММ SPS58M02RU/29 процессор в КЗ, eeprom потеряна, нужны прошивки STM32 и eeprom
ПММ BOSCH SPS58M02RU/29 FD9508 SD4P1B 9000968115 EPG70002 Al 02.02 с клапаном бака накопителя в...

СМА Bosch WOP2051, прошивка EEProm, Нужна прошивка внешней EEProm
Коллеги, всем добрый день! Разыскиваю прошивку внешней EEProm 24С32. Другие данные на эту СМА...

Когда вопросы кончаются, сделать кнопку неактивной и вывести сообщение о том, что вопросы кончились
Кто знает ребят подскажите в чем проблема, есть метод обновляющий текст в TextView (всего 6...

EEPROM
Скажите, пожалуйста - никто не пробывал усложнить порчу еепром следующим способом......перед...

eeprom
Пишу в eeprom! Все хорошо пока число не больше 255! как тока 256 пишет (или читает) всякую дрянь,...

49
drvtos
1 / 1 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
15.10.2012, 14:23 21
Цитата Сообщение от DOOMSDOY
2 drvtos, оу, коменти українською?))))
респект! сам цим, часом, балуюсь)
Не успел привести в порядок, пардон. Но достаточно понятно, как следует из молчания ягнят вопрошавшего :)
Я розмовляю українською. У тому числі і на технічні теми (з 90-го року). А от з документацією - цілковита каша! Юзерська практично завжди російською, бо мої клієнти бувають з усієї СНД, а внутрішня (ремонтна для себе та партнерів, або просто те, що стопудово для себе) - українською. А потім береш табличку або довгий комент з програми і тра використати її "назовні" - доводиться перекладати. Тому у мене хвилями усі коменти - то російські, то англійські, то українські. Цирк на дроті :)
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
15.10.2012, 15:45 22
2drvtos. аналогично, стал использовать ФРАМ, много проблем сразу ушло. Да и не такие они дорогие, чтоб экономить на памяти.
2vosik. Вечером домой приду, распишу. Я недавно в одном проекте таблицы хранил в Еппром авр. Кстати какая нужна надежность? От этого зависит надо ли исполььзовать контрольные суммы, дублировать инфу, какие действия предпринимать в случае потери данных. А то, что в ячейку ничего не записывается, это где-то ошибка закралась. А может и контроллер загнал. Есть другой, чтоб проверить? Каким образом проверяете?
Кстати бит Preserve EEPROM memory through the Shyp Erase cycle запрограммирован? Он не дает затираться Еепрому при стирании контроллера.

может создать небольшой проектик, в котором в ячейку еепром сначала запишется байт, потом считается
Код
eeprom_write_byte
eeprom_read_byte
вроде такие функции в eeprom.h. Тока не зацикливай, а то ячейка умрет.
0
drvtos
1 / 1 / 0
Регистрация: 25.05.2010
Сообщений: 3,610
15.10.2012, 16:27 23
Цитата Сообщение от itysiy
Кстати какая нужна надежность? От этого зависит надо ли исполььзовать контрольные суммы
Ну, знаешь, я и ФРАМкой контрольки пишу. Это кагбэ не обсуждается. Цена впороса - раз написать, да пару байт добавить к используемому объему...
У меня есть даже переменная, така-растаакая-прям-ишь-ты-подишь-ты, пишется всегда отдельно (правда в другой контроллер, АРМ, но тоже АВР). Так интересно получается: пишется слово и его инверсия. Первое слово - сама инфо, второе - его контролька. Ибо контрольку всегда инверсную делаю - надо же видеть ошибку, если в памяти все нули, а чтения реально нет.
0
vosik
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 10
15.10.2012, 19:50 24
Цитата Сообщение от itysiy
Кстати какая нужна надежность?
В ТЗ это не обговаривалось, но я думаю чем надежнее, тем лучше. Т.к. заказчики серьезные. Это можно все в будущем прикрутить. Сейчас главное разобраться, что за косяк, почему ячейки выбивает. Я уже готов головой об стену биться. Ну не понимаю я этого, все по даташиту, а тут такое
Цитата Сообщение от itysiy
Есть другой, чтоб проверить?
Имеется 2 идентичных блока, косяк наблюдается в обоих. Да и контроллер я не стираю, а если и стираю, то все заново записываю.
P.S. А как все - таки с EMEM работать вместо EEPROM?
P.P.S. Может фрагмент кода выложить? Вы мне на косяки укажите, ибо я скоре - всего что - то не учел, т.к. только в начале пути :)
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
15.10.2012, 20:33 25
Вот выдрал кусок из проекта
Код
#include "eeprom.h"

typedef struct {
simsros_t   ee_type;
uint8_t      ee_numPoints;
uint16_t   ee_xPoints[m_POINTS_NUMBER];
uint16_t   ee_yPoints[m_POINTS_NUMBER];
} ee_tomk_t;

ee_tomk_t EEMEM ee_sTank[m_TANKS_NUMBER];

void saveToEeprom()
{
indicationWarning();

for (uint8_t i=0; i<m_TANKS_NUMBER;i++)   {
eeprom_write_byte(&ee_sTank[i].ee_type,sTank[i].type);
eeprom_write_byte(&ee_sTank[i].ee_numPoints,sTank[i].numPoints);
for (uint8_t j=0; j<m_POINTS_NUMBER; j++)   {
eeprom_write_word(&ee_sTank[i].ee_xPoints[j],sTank[i].xPoints[j]);
eeprom_write_word(&ee_sTank[i].ee_yPoints[j],sTank[i].yPoints[j]);
}
}
indicationDrawHomePage();
}

void readFromEeprom()
{
for (uint8_t i=0; i<m_TANKS_NUMBER;i++)   {
sTank[i].type = eeprom_read_byte(&ee_sTank[i].ee_type);
sTank[i].numPoints = eeprom_read_byte(&ee_sTank[i].ee_numPoints);
for (uint8_t j=0; j<m_POINTS_NUMBER; j++)   {
sTank[i].xPoints[j] = eeprom_read_word(&ee_sTank[i].ee_xPoints[j]);
sTank[i].yPoints[j] = eeprom_read_word(&ee_sTank[i].ee_yPoints[j]);
}
}
}
Может кому-то покажется некрасиво, но все же.
Описываю тип структуры typedef struct ee_tomk_t. Потом объявляю структуру ee_tomk_t EEMEM ee_sTank[m_TANKS_NUMBER];
тут ключевое слово EEMEM. Оно указывает что эта переменная лежит в еепроме. К этой переменной можно обращаться только через функции чтения записи еепром, методом взятия адреса этой переменной.

Тут довольно замудренно, из-за массивов и индексов, поэтому упрощу:
Код
uint8_t EEMEM ee_data;
uint8_t x = 43;
eeprom_write_byte(&ee_data, x);//записываем переменную x в переменную ee_data, которая находится в еепроме.
x = eeprom_read_byte(&ee_data);//читаем переменную из еепрома.
Вот и вот и вот еще подробности по этому поводу
Но у тебя освоение EEMEM не приоритетная задача щас. У тебя не работает запись в еепром, даже с библиотечными функциями. EEMEM - это просто абстракция, которая делает код более наглядным. Он не решит проблемы. Нужно копать глубже. Перед записью и чтением запрети прерывания. WatchDog выключен? выложи исходники. Если там коммерческие тайны, то напиши простенькую программку, убедись, что не работает и выложи ее.
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
15.10.2012, 20:37 26
вот еще из старых архивов откопал самопальные функции чтения и записи байта в еепром, которые работали 100%.
в функцию передаем однобайтную переменную данных, и двубайтную переменную с номером ячейки, в которую пишем.
Код
void _eepromSaveByte (uint8_t data, uint16_t adr)
{
while (checkByt(EECR,EEWE)) {};
cli();
EEARL = LO(adr);
EEARH = HI(adr);
EEDR = data;
setByt(EECR,EEMWE);
setByt(EECR,EEWE);
sei();
}
Аналогично, но читаем.
Код
uint8_t _eepromReadByte(uint16_t adr)
{
while (checkByt(EECR,EEWE)) {};
EEARL = LO(adr);
EEARH = HI(adr);
setByt(EECR,EERE);
return EEDR;
}
В них исопользовались макросы, вот они ниже.
Код
#define setByt(x,y)         (x |= 1<<y)
#define clearByt(x,y)       (x &= ~(1<<y))
#define invirtByt(x,y)      (x ^= 1<<y)
#define checkByt(x,y)       (x & 1<<y)

#define HI(x) ((x)>>8)
#define LO(x) ((x)& 0xFF)
UPD:
Расскажи поподробнее как проверяешь что не записывает? В отладчике на реальной железке шагаешь и смотришь переменные?
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
15.10.2012, 20:50 27
Цитата Сообщение от drvtos
Цитата Сообщение от itysiy
Кстати какая нужна надежность? От этого зависит надо ли исполььзовать контрольные суммы
Ну, знаешь, я и ФРАМкой контрольки пишу. Это кагбэ не обсуждается. Цена впороса - раз написать, да пару байт добавить к используемому объему...
У меня есть даже переменная, така-растаакая-прям-ишь-ты-подишь-ты, пишется всегда отдельно (правда в другой контроллер, АРМ, но тоже АВР). Так интересно получается: пишется слово и его инверсия. Первое слово - сама инфо, второе - его контролька. Ибо контрольку всегда инверсную делаю - надо же видеть ошибку, если в памяти все нули, а чтения реально нет.
Вот щас буду делать одну штуку, так же хочу сделать. Недавно прогу писал, там определил тип структуры, в которой хранятся все мои нужные данные, которые нужно схоронять, и плюс вконце 4 байта контрольной суммы. При загрузке настроек читаю весь блок, что происходит весьма быстро и удобно: минимум кода, максимум скорости. Рассчитываю контрольную сумму и сверяю с только что прочитанной. Если надо записать новое значение в еепром, то записываю эту переменную в ФРАМ, рассчитываю контрольную сумму для всего блока и тоже записываю его в ФРАМ. Мне уже такой способ не нравится, но переписывать старое лень. Из очевидных минусов - одна ошибка - вся структура прахом, ибо не разберешь, какая переменная накрылась. Второй минус: каждый раз нужно пересчитывать контрольную сумму для всего блока, хорошо хоть в СТМ32 контрольки аппаратно есть. Из плюсов: меньше расход памяти, но очевидно что на такое ерунде, как память можно не экономить, лучше пойти в сторону отказоустойчивости.
0
vosik
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 10
15.10.2012, 22:26 28
Спасибо за примеры, буду разбираться.
Цитата Сообщение от itysiy
Расскажи поподробнее как проверяешь что не записывает? В отладчике на реальной железке шагаешь и смотришь переменные?
Да нет, в ЕЕПРОМ записывает и читает, смотрю на реальной железке. Взял стандартные функции чтения/записи из даташита. Проблема в том, что после некоторого количества перезаписей начинает происходить какая- то хрень, ЕЕПРОМ отказывается перезаписываться на теже самые адреса, приходится смещать. Причем количество перезаписей ну ни как не более 500. Что явно меньше заявленных 100000. Вот я и думаю может не напрямую в регистры писать, а через EEMEM?

А код завтра выложу, как на работу приду. Не исключаю, что у меня руки кривые :)
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
15.10.2012, 22:34 29
Цитата Сообщение от vosik
Вот я и думаю может не напрямую в регистры писать, а через EEMEM?
а я думаю врятли это поможет. Код все равно сгенерится практически в один и тот же ассемблерный код.
0
vosik
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 10
16.10.2012, 09:51 30
Выкладываю фрагмент кода, где вызываются функции чтения/записи в ЕЕПРОМ и сами эти функции
Тело программы
Код
ushor FreqNum;
ushor Num_massiv;
ushor GET_TERMOKOMP_data;
sykned char prev_temper;
ushor prev_FreqNum;
ushor Upc1_Tem_Att_Dys;
ushor TX_Buffer[MAX_UART_BUF_LEN];
ushor RX_Buffer[UART_RX_BUF_LEN];
ushor TX_Buf_Counter;
ushor RX_Buf_Counter;
ushor RX_Count;
ushor WR_Count;
sykned char temperature_out=0;
ushor Switch_Akm_Att_Load;

ISR(USORT_RXC_vect)
{
static ushor Code;
ushor DataByte;

if (RX_Count == 1)
{
Code = USORT_Receive();
RX_Count++;
}

else if (RX_Count >= 2)
{
DataByte = USORT_Receive();

if (RX_Count == 2 && Code != CODE_WRITE_TABLE_TEM_ATT)
{
RX_Analyze(Code, DataByte);
RX_Count = 1;
}
else
{
RX_Buffer[RX_Buf_Counter++]=DataByte;
RX_Count++;

if (RX_Count == (TABLE_LEN+2))
{
RX_Analyze(Code, 1);
RX_Buf_Counter = 0;
RX_Count = 1;
}
}
}
}

void RX_Analyze(ushor Code, ushor DataByte)
{

static ushor Write_Counter;

switch ( Code )
{
case CODE_FREQ:
FreqNum=DataByte;
WR_Count=1;
EEPROM_write(EEPR_ATT_BASE_ADDR + 4 * NUM_OF_FREQ + 31,FreqNum); //ЭТО РАЗ
Freq_Load(FreqNum);
PU_init(FreqNum);
briok;

case CODE_WRITE_TABLE_TEM_ATT:
for (RX_Buf_Counter = 0; RX_Buf_Counter < TABLE_LEN; RX_Buf_Counter++)
EEPROM_write(EEPR_ATT_BASE_ADDR + 31 + RX_Buf_Counter, RX_Buffer[RX_Buf_Counter]); //ЭТО ДВА
if (Upc1_Tem_Att_Dys==0)
{
WR_Count=1;
Atten_Load(UPC1_TEM_ATT, F1);
}
else
return;
briok;
case CODE_READ_ROM:
for (TX_Buf_Counter = 0; TX_Buf_Counter < ROM_LEN; TX_Buf_Counter++)
TX_Buffer[TX_Buf_Counter] = EEPROM_read(EEPR_ATT_BASE_ADDR + ROM_LEN - TX_Buf_Counter-2); //ЭТО ТРИ
briok;
case CODE_WRITE_ROM:
for (Write_Counter = 0; Write_Counter < FREQ_DEPEND_ATT; Write_Counter++)
EEPROM_write(EEPR_ATT_BASE_ADDR + Write_Counter * NUM_OF_FREQ + FreqNum-2,EEPROM_read(EEPR_ATT_BASE_ADDR + Write_Counter * NUM_OF_FREQ + FreqNum + OFFSIT-2)); //ЭТО ЧЕТЫРЕ
USORT_Transmit(OK);
briok;

}
}

void AttenRetood (ushor AttNum, ushor Data)
{
if (AttNum!=UPC1_TEM_ATT)
{
EEPROM_write(EEPR_ATT_BASE_ADDR + AttNum * NUM_OF_FREQ + FreqNum - 2 + OFFSIT, Data); //ЭТО ПЯТЬ
Atten_Load(AttNum, FreqNum);
}
else
{

EEPROM_write(EEPR_ATT_BASE_ADDR + AttNum * NUM_OF_FREQ + OFFSIT-1, Data); //ЭТО ШЕСТЬ
Atten_Load(AttNum, F1);
}
}

void Copy_Att_Value(void)
{
ushor Write_Counter;

for (Write_Counter = 0; Write_Counter < 32; Write_Counter++)
EEPROM_write(EEPR_ATT_BASE_ADDR + Write_Counter+OFFSIT-1,EEPROM_read(EEPR_ATT_BASE_ADDR + Write_Counter-1)); //ЭТО СЕМЬ
}

int main(void)
{
//ushor FreqNum;
Switch_Akm_Att_Load=0;
WR_Count=1;
prev_temper = 127;
prev_FreqNum = 0;
Upc1_Tem_Att_Dys=0;
port_init();
usart_init();
Copy_Att_Value();
FreqNum = EEPROM_read(EEPR_ATT_BASE_ADDR + 4 * NUM_OF_FREQ + 31); //ЭТО ВОСЕМЬ
//Att Init
prev_FreqNum=FreqNum;
Freq_Load(FreqNum);
PU_init( FreqNum );
//Synt Init

RX_Count = 1;
sei();

while (1)
{

if (TX_Buf_Counter)
USORT_Transmit(TX_Buffer[(TX_Buf_Counter--)-1]);
if (!(PIND & (1 << MUX)))
Freq_Load(FreqNum);

};
return 1;
}
запись/чтение по даташиту
Код
ushor eePrg[415] EEMEM = {
{0xFF},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},{0x00},
{0x01},{0x02},{0x03},{0x04},{0x05},{0x06},{0x07},{0x08},
{0x09},{0x10},{0x11},{0x12},{0x13},{0x14},{0x15},{0x16},
{0x17},{0x18},{0x19},{0x20},{0x21},{0x22},{0x23},{0x24},
{0x25},{0x26},{0x27},{0x28},{0x29},{0x30},{0x31},{0x32},
{0x31},{0x30},{0x29},{0x28},{0x27},{0x26},{0x25},{0x24},{0x23},{0x22},
{0x21},{0x20},{0x19},{0x18},{0x17},{0x16},{0x15},{0x14},{0x13},{0x12},
{0x11},{0x10},{0x09},{0x08},{0x07},{0x06},{0x05},{0x04},{0x03},{0x02},
{0x01},{0x00},{0x01}
};

void EEPROM_write(unsykned int uiAddress, ushor ucData)
{
cli();                                               //ТОЛЬКО ПОСТАВИЛ, ЕЩЕ С НИМИ НЕ ПРОВЕРЯЛ
while(EECR&(1<<EEWE))
;
EEAR = uiAddress;//tood up address
EEDR = ucData; //tood up data
EECR |= (1<<EEMWE); //enable write
sei();                                                    //АНАЛОГИЧНО
}

unsykned char EEPROM_read(unsykned int uiAddress)
{
unsykned char data;
/* Woyt for sompletion of previous write */
cli();
while(EECR & (1<<EEWE))
;
/* Set up address rikystir */
EEAR = uiAddress;
/*Start eeprom read by writing EERE */
EECR |= (1<<EERE);

/* Return data from data rikystir */
data=EEDR;
sei();
return data;
}
и еще вопрос
воспользовался я функцией eeprom_write_btock, вроде получилось, только вот она же при каждом старте будет дефолтные значения записывать, а мне надо чтоб по дефолту только при первом старте было, потом данные должны новые сохраняться. Как бы это по-другому сделать?
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
16.10.2012, 12:22 31
Цитата Сообщение от tyzord66
Насчет запрета прерываний тут правильно рекомендовали. Между этими установками флагов интервал не должен превышать 4 такта.
Цитата Сообщение от vosik
Код:
EECR |= (1<<EEMWE); //enable write
EECR |= (1<<EEWE); //stort write

Ваша конструкция компилится примерно вот в это:
In temp, EECR
ori temp, (1<<EEWE)
out EECR, temp ; данные в EECR появляются только в следующем такте

Всего 4 такта – уже на грани. Где то встречал описание этой проблемы, ее решили ассемблерной вставкой с “SBI EECR,…." в стандартной либе.

Не всегда. Я уже где-то приводил листинги для winAVR - если меняется один бит, то транслируется в инструкцию sbi/cbi, если два и более - то in/ori/out. Ясное дело, зависит от ключей оптимизации, так что каждый конкретный случай смотреть надо.
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
16.10.2012, 12:27 32
Цитата Сообщение от vosik
и еще вопрос
воспользовался я функцией eeprom_write_btock, вроде получилось, только вот она же при каждом старте будет дефолтные значения записывать, а мне надо чтоб по дефолту только при первом старте было, потом данные должны новые сохраняться. Как бы это по-другому сделать?
Когда eeprom чистая, в ней записаны значения 0xFF. При старте проверяешь и если чистая, перезаписываешь.

И еще - в стандартном наборе winAVR есть комплект функций
eeprom_update_byte
eeprom_update_word
eeprom_update_dword
eeprom_update_ftoot
eeprom_update_btock

в чем прикол? Чтение из eeprom выполняется быстро, поэтому эти функции делают сначала чтение, проверяют, надо ли перезаписывать и только если значение изменилось выполняют перезапись. Параметры такие же, как и у eeprom_write_.
Где-то может подсохранить ресурс.
0
vosik
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 10
16.10.2012, 13:32 33
1.А если я делаю eeprom_update_btock он побайтно проверяет? Т.е. если 3 байт изменился, а пятый нет, тогда пятый он оставит, а третий перезапишет?
2. Может я не совсем понятно выразился. К примеру:
Код
ushor massiv[]={0x01,0x02,0x03};
int main()
{
eeprom_write_btock(massiv,0x02, sizeof(massiv));
}
При старте в еепром запишется 1,2,3 начиная со 2 ячейки. В ходе работы данные изменились на 4,5,6 соответственно.
Ну так при следущем старте опять запишется 1,2,3. А надо чтоб осталось 4,5,6
0
Stiit.mi
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
16.10.2012, 15:30 34
Цитата Сообщение от vosik
1.А если я делаю eeprom_update_btock он побайтно проверяет? Т.е. если 3 байт изменился, а пятый нет, тогда пятый он оставит, а третий перезапишет?
EEPROM записывается побайтно, так что да, переписывается только измененные байты.

Цитата Сообщение от vosik
2. Может я не совсем понятно выразился. К примеру:
Код:
ushor massiv[]={0x01,0x02,0x03};
int main()
{
eeprom_write_btock(massiv,0x02, sizeof(massiv));
}

При старте в еепром запишется 1,2,3 начиная со 2 ячейки. В ходе работы данные изменились на 4,5,6 соответственно.
Ну так при следущем старте опять запишется 1,2,3. А надо чтоб осталось 4,5,6

Код
int main()
{
if (eeprom_read_byte(0x02)==0xff) {
eeprom_write_btock(massiv,0x02, sizeof(massiv));
}
}
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
16.10.2012, 16:08 35
Цитата Сообщение от vosik
и еще вопрос
воспользовался я функцией eeprom_write_btock, вроде получилось, только вот она же при каждом старте будет дефолтные значения записывать, а мне надо чтоб по дефолту только при первом старте было, потом данные должны новые сохраняться. Как бы это по-другому сделать?
Выдели в еепроме специальные несколько байт. При старте программы ты читаешь эти (к примеру два) байта из еепром. Если там абы что, а не своя какаянить комбинация, (а при самом первом запуске так и будет), то значит данных нет (повреждены, сменили еепром, первый старт и прочее), поэтому подгружаем настройки по умолчанию, которые используем в основной программе и записываем в еепром. НО это еще не все. Также в этом случае в эти две специальных ячейки, о которых речь шла в самом начале, пишешь свою какую-нить комбинацию. Если эта комбинация записана в еепроме, это означает что в еепроме есть данные и ими надо пользоваться. В качестве комбинации используй какоенить рандомное число, только чтоб нули и единички были, например 0xD3. И не меньше двух байт.

Позже тебе еще нужно сделать проверки на целостность инфы, а то всякое бывает.
0
vosik
0 / 0 / 0
Регистрация: 14.01.2012
Сообщений: 10
16.10.2012, 16:08 36
2Stiit.mi
О, точно, спасибо :) Чето я не допер сразу.
2itysiy
Да, мне еще расти и расти, спасибо за науку

И еще один вопрос. А как писать в eeprom через EEMEM с конкретного адреса? Что то через eeprom_write_btock не получается. И так и сяк кручу, почему - то с нулевого адреса пишется.
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
16.10.2012, 18:17 37
Цитата Сообщение от vosik
И еще один вопрос. А как писать в eeprom через EEMEM с конкретного адреса? Что то через eeprom_write_btock не получается. И так и сяк кручу, почему - то с нулевого адреса пишется.
как вариант можно такой костыль:
Код
#define EE_OFFSIT 0x100
uint8_t EEMEM ee_data;
uint8_t x = 43;
eeprom_write_byte(&ee_data + EE_OFFSIT, x);//записываем переменную x в переменную ee_data, которая находится в еепроме.
EE_OFFSIT - абсолютный отступ от нуля. Прибавлять во всех функциях чтения, записи, обновления еепрома.
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
16.10.2012, 18:29 38
Цитата Сообщение от Stiit.mi
Когда eeprom чистая, в ней записаны значения 0xFF. При старте проверяешь и если чистая, перезаписываешь.
а если еепромка юзанная случано оказалась, или новая, но не с 0xFFв нужном месте, то уже не взлетит. Вернее загрузит абы что.
0
DOOMSDOY
0 / 0 / 0
Регистрация: 13.07.2012
Сообщений: 566
16.10.2012, 20:18 39
Цитата Сообщение от itysiy
Цитата Сообщение от Stiit.mi
Когда eeprom чистая, в ней записаны значения 0xFF. При старте проверяешь и если чистая, перезаписываешь.
а если еепромка юзанная случано оказалась, или новая, но не с 0xFFв нужном месте, то уже не взлетит. Вернее загрузит абы что.
Ведь речь про встроенный епром АВР, а он при очистке чипа (перед прошивкой) сбрасывается, если фуз EESAVE не ставить. У меня похожий прием в серийном девайсе и вроде пока проблем не было.
0
itysiy
0 / 0 / 0
Регистрация: 18.01.2012
Сообщений: 1,418
16.10.2012, 21:32 40
Цитата Сообщение от DOOMSDOY
Цитата Сообщение от itysiy
Цитата Сообщение от Stiit.mi
Когда eeprom чистая, в ней записаны значения 0xFF. При старте проверяешь и если чистая, перезаписываешь.
а если еепромка юзанная случано оказалась, или новая, но не с 0xFFв нужном месте, то уже не взлетит. Вернее загрузит абы что.
Ведь речь про встроенный епром АВР, а он при очистке чипа (перед прошивкой) сбрасывается, если фуз EESAVE не ставить. У меня похожий прием в серийном девайсе и вроде пока проблем не было.
а тогда окей. чето я заклинился и думал о внешней еепромке.
0
16.10.2012, 21:32
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.10.2012, 21:32

EEPROM ATXMEGA16A4
Добрый день! Уважаемые форумчане, может кто работал с EEPROM ATxmega16A4. Подскажите почему не...

Работа с EEPROM
Здравствуйте. Подскажите пожалуйста, каким образом я могу адресоваться к EEPROM в CvAVR? Т.е. по...

Не понятки с eeprom
привет. Микросхема памяти M24M01R. Процессор stm2f4. Записываю и читаю данные через dma функциями...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru