Запись и чтение EEPROM данных типа unsigned int, unsigned long, float и других типов данных, размером более 8 бит, т.е. тех данных, которые размером более одного байта.
Все примеры здесь указаны для языка СИ.
Сначала приведем основной пример для чтения и записи типа unsigned char, т.к. это будут основные функции, на основе которых будет происходить чтение и запись ячеек еепром.
/* ------------------------------------------------------------------------ */ // Функции чтения и записи в еепром одного байта. /* ------------------------------------------------------------------------ */ void EEPROM_write (unsigned int uiAddress, unsigned char ucData) { unsigned char cSREG; /* Wait for completion of previous write */ while(EECR & (1<<EEWE)); /* Set up address and data registers */ EEAR = uiAddress; EEDR = ucData; cSREG = SREG; /* store SREG value */ /* disable interrupts during timed sequence */ #if __CODEVISIONAVR__ /* if CodeVisionAVR */ #asm("cli"); #else asm("cli"); #endif /* Write logical one to EEMWE */ EECR |= (1<<EEMWE); /* Start eeprom write by setting EEWE */ EECR |= (1<<EEWE); SREG = cSREG; /* restore SREG value (I-bit) */ } unsigned char EEPROM_read(unsigned int uiAddress) { /* Wait for completion of previous write */ while(EECR & (1<<EEWE)); /* Set up address register */ EEAR = uiAddress; /* Start eeprom read by writing EERE */ EECR |= (1<<EERE); /* Return data from data register */ return EEDR; }
Эти функции без проблем позволяют считывать из Еепром данные или наоборот, записывать какие либо данные в Еепром. Этих функций в целом достаточно для записи или чтения любых типов данных, просто используя циклы, когда количество байтов более одного. Но есть тут одно неудобство, при таком подходе (к примеру для записи), если тип записываемой переменной более одного char, например int, а это уже два байта, то придется каждый раз подготавливать данные в самом коде программы и потом в цикле или построчно (побайтно) уже производить запись.
Такой код неудобен, если в нашей программе в разных местах кода мы будем часто проводить подобные операции. Как минимум хотя-бы, в итоге, это потеря в размере flash. Как максимум, слишком много лишних движений.
Пример записи числа unsigned int в Eeprom без цикла
/* ------------------------------------------------------------------------ */ // Запись в Eeprom числа unsigned int (без цикла). /* ------------------------------------------------------------------------ */ unsigned int addr; unsigned int TimeStopTrunk; addr = 0x3F0; TimeStopTrunk = 0xAABB; // Пишем в Eeprom 2 байта. EEPROM_write((unsigned int) addr,(TimeStopTrunk>>8)); // Первый байт слова EEPROM_write((unsigned int) addr+1,(TimeStopTrunk&0xFF)); // Второй байт слова
Пример записи числа unsigned int в Eeprom с циклом
/* ------------------------------------------------------------------------ */ // Запись в Eeprom числа unsigned int (в цикле). /* ------------------------------------------------------------------------ */ unsigned int addr; unsigned int TimeStopTrunk[2]; unsigned char i; addr = 0x3F0; TimeStopTrunk = 0xAABB; writed[0]=TimeStopTrunk>>8; // Первый байт слова writed[1]=TimeStopTrunk&0xFF; // Второй байт слова // Пишем в Eeprom 2 байта. for( i = 0; i < 2; i++ ) { EEPROM_write(addr+i, writed[i]); }
На самом деле вариаций таких примером немалое количество, все их приводить конечно мы не будем, но вы понимаете, насколько можно замусорить исполняемый код своей программы? А сколько неудобств каждый раз объявлять переменные, обрабатывать и т.д. и т.п. А не удобнее ли все делать одной строчкой? Вот к этому мы и должны прийти!
В том, что хочу вам показать, есть только один минус, это один лишний прыжок в стек, т.к. из одной подпрограммы вызывается еще одна подпрограмма, проще говоря, функция. Но жертвы стоят того, просто необходимо в своей программе учитывать этот момент, чтобы не произошло переполнения стека. Тем не менее, данный подход реализован почти во всех библиотеках, и от этого никуда не деться. Если мы экономим на одном, мы теряем на другом. Вполне закономерно :)
Итак, вот упрощенная реализация чтения и записи числа int
/* ------------------------------------------------------------------------ */ // Чтение числа int из еепром. /* ------------------------------------------------------------------------ */ unsigned int EEPROM_read_int(unsigned int addr) { unsigned char buf[2]; unsigned char i; for( i = 0; i < 2; i++ ) buf[i] = EEPROM_read(addr+i); unsigned int &num = (unsigned int&)buf; return num; } /* ------------------------------------------------------------------------ */ // Запись числа int в еепром. /* ------------------------------------------------------------------------ */ void EEPROM_write_int(unsigned int addr, unsigned int num) { unsigned char buf[2]; unsigned char i; (unsigned int&)buf = num; for( i = 0; i < 2; i++ ) EEPROM_write(addr+i, buf[i]); }
Теперь все основные действия мы будем совершать всего одной строкой
/* ------------------------------------------------------------------------ */ // Чтение числа int из еепром. /* ------------------------------------------------------------------------ */ EEPROM_read_int((unsigned int) addr); /* ------------------------------------------------------------------------ */ // Запись числа int в еепром. /* ------------------------------------------------------------------------ */ EEPROM_write_int((unsigned int) addr,dataint);
В итоге невооруженным взглядом видно, насколько мы упростили себе жизнь :)
Таким образом, на основе этих функций мы можем создать новые функции и для других типов, например unsigned long или float. А также было бы очень неплохо в функции записи реализовать проверку на запись одинакового значения, и производить запись в ячейку памяти только в случае, если новые и старые данные различаются. Ну зачем нам лишний раз повторно переписывать ячейки в Eeprom, верно?
Короче код твой херня не проверенная
// Чтение числа int из еепром.
/* ------------------------------------------------------------------------ */
EEPROM_read_int((unsigned int) addr,dataint);
Тут dataint лишнее.
компилятор codevisionavr v3.12 ругается на эту строку: unsigned int &data = (unsigned int)&buf; -не допустимый символ.
в чем может быть проблема?
/* чтение из памяти EEPROM */
unsigned int eeplc24_read(unsigned int addr) {
unsigned char buf[2];
unsigned char i;
unsigned int data;
for( i = 0; i < 2; i++ ) buf[i] = eeplc24_read(addr+i);
unsigned int &data = (unsigned int)&buf;
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(addr);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}
unsigned int &data = (unsigned int&)buf;
//unsigned int data;
и по прежнему unsigned int &data = (unsigned int&)buf; -не допустимый символ.
unsigned int data = (unsigned int&)buf;
// Здесь объявляем переменную data.
unsigned int data;
// Наполняем буфер
for( i = 0; i < 2; i++ ) buf[i] = eeplc24_read(addr+i);
// Здесь заполняем data
data = (unsigned int) &buf;
// Или в одной строке объявляем переменную и сразу ее наполняем.
unsigned int data = (unsigned int) &buf;
// Или еще проще, если не использовать переменную data, а сразу работать с буфером, то есть просто удалить лишний код и использовать или возвращать напрямую переменную buf.
unsigned int eeplc24_read(unsigned int addr) function return size mismatch with entry 'eeplc24_read'
что делать...
/* запись в память EEPROM */
void eeplc24_write(unsigned int addr, unsigned int data) {
unsigned char buf[2];
unsigned char i;
(unsigned int)&buf = data; the expression must be a modifiable lvalue
for( i = 0; i < 2; i++ ) eeplc24_write(addr+i, buf[i]);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(addr);
i2c_write(data);
i2c_stop();
delay_ms(7); /* 10ms delay to complete the write operation */
}
/* чтение из памяти EEPROM */
unsigned int eeplc24_read(unsigned int addr) {
unsigned char buf[2];
unsigned char i;
unsigned int data = (unsigned int)& buf;
for( i = 0; i < 2; i++ ) buf[i] = eeplc24_read(addr+i);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS);
i2c_write(addr);
i2c_start();
i2c_write(EEPROM_BUS_ADDRESS | 1);
data=i2c_read(0);
i2c_stop();
return data;
}
void main(void)
{
Здесь читаем, и записываем в переменную M1_side_A=eeplc24_read(0);
}
Вот пример (лишнее убрал). В моем случае у меня разные! функции (названия)
EEPROM_read_int() и EEPROM_read().
unsigned int EEPROM_read_int(unsigned int addr) {
for( i = 0; i < 2; i++ ) buf[i] = EEPROM_read(addr+i);
}
Посмотрите на мои примеры в публикации, сравните с Вашими. Ваша ошибка, что Вы вызываете eeplc24_read(), а внутри этой функции еще раз eeplc24_read(). Все, Вы уходите в бесконечный цикл. Ваша функция убьет Вам еепром от огромного количества перезаписи еепром в бесконечном цикле.
Компилятор:Codevisionavr.
А куда мне -я начинающий. "Опыт приходит со временем ".
Прошивка контроллера аккумулятора Dyson DC62 V6 V7