zapis do eeprom
zapis do eeprom
Witam.
Mam pytanie jak zapisywać/odczytywać dane do/z wew. eepromu uP avr 2313 pod C
w WinAvr.
Mam pytanie jak zapisywać/odczytywać dane do/z wew. eepromu uP avr 2313 pod C
w WinAvr.
A chociażby tak jak traktuje o tym dokumentacja avrlibc : http://www.nongnu.org/avr-libc/user-man ... eprom.html
To jest własnie dla wewnętrznej pamięci EEPROMavr-libc pisze:handling the data EEPROM contained in the AVR microcontrollers
Poczytaj też wątek : http://lists.gnu.org/archive/html/avr-g ... 00004.htmlavr-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);
W moim poprzednim poście podałem link do wątku na avr-gcc-list i tam jest wykorzystana funkcja eeprom_is_ready() :
Natomiast eeprom_busy_wait() możesz zastosować podobnie jak wyżej, bo
działa tak samo jak
czyli jak funkcja eeprom_busy_wait()
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());
}Kod: Zaznacz cały
while(!eeprom_is_ready());Kod: Zaznacz cały
do {} while (!eeprom_is_ready())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!
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!
W moim WinAVR kompiluje się takie cuś :
[ Dodano: 12-08-2005, 16:58 ]
PS. NIe zapomnij o skonfigurowaniu portu B jakio wyjście (DDRB = 0xFF)
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)
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();
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();
Ad 1.
Jeśli skorzystasz z funkcji avr-libc
To spokojnie jako wartość możesz podać bezpośrednio stałą, ponieważ value nie jest typu wskaźnikowego.
Ad 2.
Funkcja
jak jej nazwa sama wskazuje służy do odczytu słowa, czyli dwóch bajtów (operuje na typach dwubajtowych jak np int)
Jeśli skorzystasz z funkcji avr-libc
Kod: Zaznacz cały
void eeprom_write_byte(uint8_t * addr, uint8_t value) 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)
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ć.
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ć.
Jakiego typu jest zmienna Erekord? Zawsze można ją zrzutować:
Kod: Zaznacz cały
eeprom_write_byte( (uint8_t*)&Erekord , 0 );
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ę ;]
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?czarutek pisze:Postępując dokładnie według not, w najbanalniejszym programie asemblerowym, EEPROM po prostu ginie, a co dopiero pod jakimś BASCOMem!
Ja tam 90S... będę bronił ;] Budowałem na tym pracę dyplomową i nic a nic z EEPROMu nie traci ;D