zapis do eeprom

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

zapis do eeprom

Post autor: nasiono » 11 sie 2005, 16:45

Witam.
Mam pytanie jak zapisywać/odczytywać dane do/z wew. eepromu uP avr 2313 pod C
w WinAvr.

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 11 sie 2005, 17:05

A chociażby tak jak traktuje o tym dokumentacja avrlibc : http://www.nongnu.org/avr-libc/user-man ... eprom.html

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 11 sie 2005, 17:16

Codziło mi raczej oo bsługe wewnętrznej pamięci.
Czy mógł by ktoś rzucić jakiś prosty przykłąd zapisu i odczytu danej float do eepromu?
Był bym wdzięczny bo z angielskim u mnie marnie ,a z przykładu skapuje pewnie od razu.

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 11 sie 2005, 17:28

avr-libc pisze:handling the data EEPROM contained in the AVR microcontrollers
To jest własnie dla wewnętrznej pamięci EEPROM 8)
avr-gcc-list pisze: #include <eeprom.h>

// An example eeprom variable definition. Use type specifiers to define
// various other types (int, char, etc).
//
float eSomeVariableName __attribute__((section(".eeprom"))) = 10.0; //
initial value

//--------------------------------------------------------------------------
---
// Write a 4-byte float to the specified eeprom address.
//
void eWriteFloat(float *numPtr, void *addr)
{
BYTE *ptr, *num;

ptr = (BYTE*)addr;
num = (BYTE*)numPtr;
eeprom_wb((int)ptr++, *num++); // use gcc AVR extension
eeprom_wb((int)ptr++, *num++);
eeprom_wb((int)ptr++, *num++);
eeprom_wb((int)ptr++, *num++);
}

//--------------------------------------------------------------------------
---
// Read a 4-byte float from the specified address.
//
float eFloat(float *ptr)
{
float a;

eeprom_read_block(&a, (int)ptr, 4); // use gcc AVR extension
return a;
}


// An example of accessing an eeprom variable:
float localFloat;

localFloat = 23.4 + eFloat(&eSomeVariableName);
Poczytaj też wątek : http://lists.gnu.org/archive/html/avr-g ... 00004.html

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 12 sie 2005, 15:04

Dzięki za pomoc.
Ale mam jeszcze jedno pytanie w związku z tym linkiem
czemu nie wykorzystują tam funkcji - eeprom_is_ready()-
i czy macie jakieś przykłady z wykorzystaniem -eeprom_busy_wait() -
albo chociasz czy mógł by ktoś napisać jak to wykorzystać.

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 12 sie 2005, 15:15

W moim poprzednim poście podałem link do wątku na avr-gcc-list i tam jest wykorzystana funkcja eeprom_is_ready() :

Kod: Zaznacz cały

void eWriteFloat(float *numPtr, void *addr)
 {
     BYTE *ptr, *num;

     ptr = (BYTE*)addr;
     num = (BYTE*)numPtr;
     eeprom_wb((int)ptr++, *num++);
     while(!eeprom_is_ready());
     eeprom_wb((int)ptr++, *num++);
     while(!eeprom_is_ready());
     eeprom_wb((int)ptr++, *num++);
     while(!eeprom_is_ready());
     eeprom_wb((int)ptr++, *num++);
     while(!eeprom_is_ready());
 }
Natomiast eeprom_busy_wait() możesz zastosować podobnie jak wyżej, bo

Kod: Zaznacz cały

while(!eeprom_is_ready());
działa tak samo jak

Kod: Zaznacz cały

do {} while (!eeprom_is_ready())
czyli jak funkcja eeprom_busy_wait()

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 12 sie 2005, 15:45

Dzięki znowu Wojtku.

wydawało mnie się ,że jusz pojołęm o co w tym chodzi
więc postanowiłem napisać pryzkłądowy program który z zmiennej przepisuje wart do eepromu a nastepnie odczytuje ją wprost do PORTB ale niestety kompilator klnie na mnie niemiłosiernie buntując sie jednocześnie ,wdzięczny był bym gdy byś pomógł mi i tym razem i sprawdził co w kodzie piszczy(a raczej niepiszczy).


#include <avr/io.h>
#include <avr/eeprom.h>
float Eliczba EEMEM = 0; /* #define EEMEM __attribute__((section(".eeprom")))
dokumentacja AVR LIB*/
int main(void)
{

float liczba=0xFF;

DDRB = 0;
PORTB = 0;

ZA_Float(&liczba,&Eliczba); //zapisz do Eliczba(eepromu) zmienną liczba
PORTB=CZ_Float(&Eliczba); //odczytaj z Eliczba wartość na PORTB

while(1);
}
/*88888888888888888888888888888888888888888888888888888888888888*/
//czytaj//
float CZ_Float(float *ptr)

{
float a;

eeprom_read_block(&a, (int)ptr, 4);
return a;
}

//zapisz
void ZA_Float(float *numPtr, void *addr)
{
BYTE *ptr, *num;

ptr = (BYTE*)addr;
num = (BYTE*)numPtr;
eeprom_wb((int)ptr++, *num++);
eeprom_wb((int)ptr++, *num++);
eeprom_wb((int)ptr++, *num++);
eeprom_wb((int)ptr++, *num++);
}

[ Dodano: 12-08-2005, 16:46 ]
Przepraszam!!!
chochlik przycioł w ch.....
oczywiście nie wojtku tylko RADKU!

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 12 sie 2005, 15:56

W moim WinAVR kompiluje się takie cuś :

Kod: Zaznacz cały

#include <avr/io.h>
#include <avr/eeprom.h>
#define EEMEM __attribute__((section(".eeprom")))
#define BYTE unsigned char
float EEMEM Eliczba = 0;
void ZA_Float(float *numPtr, void *addr);
float CZ_Float(float *ptr);
int main(void)
{

float liczba=0xFF;

DDRB = 0;
PORTB = 0;

ZA_Float(&liczba,&Eliczba); //zapisz do Eliczba(eepromu) zmienną liczba
PORTB=CZ_Float(&Eliczba); //odczytaj z Eliczba wartość na PORTB

while(1);
}
/*88888888888888888888888888888888888888888888888888888888888888*/
//czytaj//
float CZ_Float(float *ptr)

{
float a;

eeprom_read_block(&a, ptr, 4);
return a;
}

//zapisz
void ZA_Float(float *numPtr, void *addr)
{
BYTE *ptr, *num;

ptr = (BYTE*)addr;
num = (BYTE*)numPtr;
eeprom_write_byte(ptr++, *num++);
eeprom_write_byte(ptr++, *num++);
eeprom_write_byte(ptr++, *num++);
eeprom_write_byte(ptr++, *num++);
}


[ Dodano: 12-08-2005, 16:58 ]
PS. NIe zapomnij o skonfigurowaniu portu B jakio wyjście (DDRB = 0xFF)

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 12 sie 2005, 17:36

Dzięki za szybką odpowiedź. ostatnie 2 pytania (chyba) to

1.czy jest możliwość szybkiego wpisywania do zmiennej w eepromie jakiejś wart np. 0xAA
bez przypisywania tej wart do jnnej zmiennej a dopiero potem do epromu

przykład o co mnie chodzi :

jest:

float liczba=0xFF;
ZA_Float(&liczba,&Eliczba);

a żeby było coś w rodzaju:

ZA_Float( 0xAA ,&Eliczba);

Pytanie numer 2:

czemu służy uint16_t eeprom_read_word();

Awatar użytkownika
radzio
Użytkownik
Posty: 573
Rejestracja: 07 gru 2004, 23:06
Lokalizacja: Sosnowiec
Kontakt:

Post autor: radzio » 12 sie 2005, 17:51

Ad 1.
Jeśli skorzystasz z funkcji avr-libc

Kod: Zaznacz cały

void eeprom_write_byte(uint8_t * addr, uint8_t value) 
To spokojnie jako wartość możesz podać bezpośrednio stałą, ponieważ value nie jest typu wskaźnikowego.

Ad 2.
Funkcja

Kod: Zaznacz cały

uint16_t eeprom_read_word();

jak jej nazwa sama wskazuje służy do odczytu słowa, czyli dwóch bajtów (operuje na typach dwubajtowych jak np int)

nasiono
-
Posty: 46
Rejestracja: 29 lip 2005, 0:01

Post autor: nasiono » 17 sie 2005, 11:36

Witam ponownie.
Prubuje tak wpisać wartość - 0 - od razu do zemiennej umieszczoenej w eepromie -Erekord-:
eeprom_write_byte( &Erekord , 0 );

ale wywala mi taki komunikat

passing arg 1 of `eeprom_write_byte' from incompatible pointer type

czy mógł by mi ktoś powiedzieć co robie nie tak ewentualnie pokazać jak to powinno wyglądać.

czarutek
Użytkownik
Posty: 236
Rejestracja: 02 lis 2004, 11:51
Lokalizacja: Warszawa
Kontakt:

Post autor: czarutek » 17 sie 2005, 11:58

Ja tylko w kwestii formalnej i ku przestrodze:
Nie należy liczyć na to, że zawartość EEPROM w 2313 i wielu z serii AT90Sxxxx nie będzie się psuć przy wyłączaniu zasilania.

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 17 sie 2005, 20:08

:arrow: nasiono
Jakiego typu jest zmienna Erekord? Zawsze można ją zrzutować:

Kod: Zaznacz cały

eeprom_write_byte( (uint8_t*)&Erekord , 0 );
Z rzutowaniem trzeba jednak ostrożnie - trzeba wiedzieć co się robi, ponieważ wyłączamy praktycznie część ostrzeżeń ze strony kompilatora.
:arrow: czarutek
Masz rację tylko częściowo. Sam wykonałem kilka projektów wykorzystujących pamięć eeprom. Rzeczywiście trzeba liczyć się z tym, że możemy tracić dane jeśli napięcia zasilania się obniża, a nie mamy żadnego zabezpieczenia przed działaniem procesora przy niskim zasilaniu (można chociażby uśpić procesor odpowiednio wcześnie - korzystając z komparatora, albo wykrycia zaniku częstotliwości sieci w urządzeniach z niej zasilanych).
Z mojego doświadczenia wynika jednak, że jest to związane z pójściem programu w maliny a nie z błędem konstrukcji samego EEPROMa.

Zauważcie także, że AT90s2313 nie jest już produkowany. Producent zaleca zamiast tego ATtiny2313. Według mojej opini 2x lepszy procesor za porównywalną cenę ;]

czarutek
Użytkownik
Posty: 236
Rejestracja: 02 lis 2004, 11:51
Lokalizacja: Warszawa
Kontakt:

Post autor: czarutek » 17 sie 2005, 20:24

Nadmiar mleka... :oops:
Ostatnio zmieniony 18 sie 2005, 10:17 przez czarutek, łącznie zmieniany 1 raz.

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 17 sie 2005, 21:02

czarutek pisze:Postępując dokładnie według not, w najbanalniejszym programie asemblerowym, EEPROM po prostu ginie, a co dopiero pod jakimś BASCOMem!
Aby eeprom nie ginął należy zepewnić odpowiednie warunki zasilania. Rozumiem przez to odpowiednio szybko narastające oraz opadające zbocza przy włączaniu i wyłączaniu. Problemem jest to, że AT90S2313 nie posiada zerowania na BOD, jedyny obwód jaki posiada to POR. Zauważ, że w układach takich jak 89C2051 trzeba było stosować zewnętrzny układ zerowania i nikt wtedy nie narzekał - to inżynierowie ATMELa tak nas rozleniwili, że złościmy się na każdy dodatkowy scalaczek?

Ja tam 90S... będę bronił ;] Budowałem na tym pracę dyplomową i nic a nic z EEPROMu nie traci ;D

ODPOWIEDZ