Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: запись большого числа в EEPROM
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Integral
Народ, подскажыте как записать число больше 256 в 8-ми розрядную EEPROM?

Была идея разбыть число на отдельные цыфры и записать в отдельные ячейки. Считывать также само по отдельному числу и лепить в кучу.... Но я чувствую что есть более простой способ. Например использовать две соседные ячейки как старшые и младшые бити. Мне просто нужно знать с помощью каких функцый можно облегчить себе жызнь.....

использую CodeVisionAVR + mega16.

Заранее благодарю.
rezident
Вообще-то все люди спокойно делят числа большой разрядности на меньшие (на байты) и пишут их в EEPROM побайтово. Непонятно, почему вы аналогично делать стесняетесь?
Пишете-то программу на Си или на ассемблере?
Integral
На Си.

Покажыте пожалуйста на примере как поделить число и записать побайтово....
vovanse
Например так:

unsigned long a;
unsigned char a1,a2,a3,a4;

a1= a & 0x000000FF;
a2=(a & 0x0000FF00)>>8;
a3=(a & 0x00FF0000)>>16;
a4=(a & 0xFF000000)>>24;

обратно собрать

a=(unsigned long)a1;
a|=(unsigned long)a2<<8;
a|=(unsigned long)a3<<16;
a|=(unsigned long)a4<<24;
WHALE
зачем такие сложности?!
long a=123456;
eeprom long b;
b=a;
компилятор все сделает за вас.
Integral
Цитата(WHALE @ Aug 10 2008, 07:31) *
зачем такие сложности?!
long a=123456;
eeprom long b;
b=a;
компилятор все сделает за вас.


т.е. получается "eeprom long b;" означает создать переменную которая не будет терять свое значение после отключения питания?
Tiny
Я в СodeVision использовал встроенные функции

Цитата
CLI();
//прочесть из 0-й ячейку значение А
EEPROM_READ(0x00, А);
SEI();
//Записать в 0-ю ячейку значение А
CLI();
EEPROM_WRITE(0x00, А);
while(EECR & 0x02);//Дождаться окончания записи
asm("nop");//На всякий случай
asm("nop");
SEI();

Расчитываю длину значения в байтах, исходя из этого задаю адрес для записи следующего числа
bezobraznic
Цитата(Integral @ Aug 10 2008, 12:13) *
т.е. получается "eeprom long b;" означает создать переменную которая не будет терять свое значение после отключения питания?



Да!
WHALE
Только имейте в виду,что eeprom память имеет свои особенности.Например,если вы будете в цикле или подряд несколько значений записывать в eeprom,не забудьте организовать задержку между записями или проверку бита готовности,а то нарветесь на неожиданные глюки.
EmbedElektrik
а вообще такие дела делают с помощью union. и работать будет в любом компиляторе
defunct
Цитата(WHALE @ Aug 10 2008, 22:12) *
в eeprom,не забудьте организовать задержку между записями или проверку бита готовности,а то нарветесь на неожиданные глюки

Хм... ээээ... А разве компилятор не обязан заботиться об этом самостоятельно, если разрешает конструкции вида:
(eeprom long)b = a;

Поидее запись должна гарантироваться и так.

Цитата
а вообще такие дела делают с помощью union.

какие дела? и кто делает,
тут про записть в eeprom. как union этому поможет? ;>
Laptop
Если работаете со встроенным в микроконтроллер EEPROM, то спокойно объявляйте переменную нужной размерности в сегменте eeprom и все остальное включая проверку флагов и т.д. за вас организует компилятор. Только надо помнить что запись выполняется определенное время и может вызвать неоднозначности в выполнении критичных к времени участках. Просто учитывайте это время при написании программ.
WHALE
Цитата(defunct @ Aug 11 2008, 01:50) *
Хм... ээээ... А разве компилятор не обязан заботиться об этом самостоятельно, если разрешает конструкции вида:
(eeprom long)b = a;

увы и ах-разрешает такие записи и нифига не проверяет готовность 07.gif -надо ручками
demiurg_spb
А доработать что никак нельзя???
Зачем усложнять себе жизнь...
defunct
Цитата(WHALE @ Aug 11 2008, 07:17) *
увы и ах-разрешает такие записи и нифига не проверяет готовность 07.gif -надо ручками

А как он тогда пишет long переменные? (они же 4 байта и проверку перед каждым вручную не вставишь)..
асм листинг можете привести?
EmbedElektrik
Цитата(defunct @ Aug 11 2008, 01:50) *
Хм... ээээ... А разве компилятор не обязан заботиться об этом самостоятельно, если разрешает конструкции вида:
(eeprom long)b = a;

Поидее запись должна гарантироваться и так.
какие дела? и кто делает,
тут про записть в eeprom. как union этому поможет? ;>

как-как - разбить любое число на байты, а уж байты записывать в епром. CVAVR и IAR по разному с епромом работают
defunct
Цитата(EmbedElektrik @ Aug 11 2008, 19:27) *
как-как - разбить любое число на байты, а уж байты записывать в епром.

Есть более простой способ разбить любую переменную, структуру да и что угодно на байты - через указатель. пусть есть
anytype x;

eeprom_write( <куда>, (char *)&x, sizeof(x));

eeprom_read( <откуда>, (char *)&x, sizeof(x));
Laksus
Цитата(defunct @ Aug 11 2008, 14:34) *
А как он тогда пишет long переменные? (они же 4 байта и проверку перед каждым вручную не вставишь)..
асм листинг можете привести?

По моему, компилятор CVAVR все делает правильно. Вот поигрался,
CodeVisinAVR Version 1.25.8a Evaluation
Простейший пример кода Си
Код
#include <mega16.h>
long x,y=0x12345678;
eeprom long eex;
      
main()
{
x=PINB;
x *=y;

eex=x;

while (1);
}

сгенерированный код ассемблера
Код
;      21  eex=x;
    LDS  R30,_x
    LDS  R31,_x+1
    LDS  R22,_x+2
    LDS  R23,_x+3
    LDI  R26,LOW(_eex)
    LDI  R27,HIGH(_eex)
    CALL __EEPROMWRD
...
...
...
__EEPROMWRD:
...
    RCALL __EEPROMWRW
...
    RET

__EEPROMWRW:
...
    RCALL __EEPROMWRB
...
    RET

### Вот блок ожидания доступности EEPROM. Как указано в даташите:
"When the write access time has elapsed, the EEWE bit is cleared by hardware. The
user software can poll this bit and wait for a zero before writing the next byte. When
EEWE has been set, the CPU is halted for two cycles before the next instruction is
executed. (ATmega16, doc2466.pdf page 20)"

__EEPROMWRB:
    SBIS EECR,EEWE
    RJMP __EEPROMWRB1
    WDR
    RJMP __EEPROMWRB


__EEPROMWRB1:
    IN   R25,SREG
### Вот запрет прерываний
    CLI            
    OUT  EEARL,R26
    OUT  EEARH,R27
    SBI  EECR,EERE
    IN   R24,EEDR
    CP   R30,R24
    BREQ __EEPROMWRB0
### Выше была проверка содержимого, чтобы не писать в ячейку лишний раз

### И вот запись
    OUT  EEDR,R30
    SBI  EECR,EEMWE
    SBI  EECR,EEWE
__EEPROMWRB0:
    OUT  SREG,R25
    RET

При записи первого байта, командой
SBI EECR,EEWE
флаг EEWE ставится в единицу.
А затем при следующей попытке записи будет вертется в
__EEPROMWRB:
пока флаг EEWE не обнулится (в даташите пишуть - через 8.5 мсек).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.