• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
STRINGI z FLASH'a
#1
Witam,

Napisałem spory program do obsługi GSM'a.
Wysyłam z telefonu SMS'ami polecenia, a Arduino coś tam wykonuje
i mi równiez SMS'em odpowiada.

Wykorzystuję dosyć sporo tekstów zapisanych w STRING'ach,
które są przechowywane w pamięci operacyjnej SRAM (2kB).

Chciałbym zapisać te teksty do pamięci FLASH (32kB), i stamtąd je odczytywać w programie.

Macie jakieś sprawdzone metody?

Pozdr.
Jeżeli pomogłem, to poproszę o punkt reputacji Big Grin
 
Odpowiedź
#2
Przecież wszystko masz ładnie opisane: https://www.arduino.cc/en/Reference/PROGMEM
Pomagam za darmo więc szanuj mój czas.
Wklejaj tekst a nie jego zdjęcie.
Nie pisz następnego postu jak nie odpowiedziałeś na poprzedni.
Jak mądrze zadawać pytania
 
Odpowiedź
#3
Dziękuję 'namok' za naprowadzenie...

Dla potomnych przedstawiam krótki kod w którym chyba wszystko jest już jasne.
Dzięki niemu zrozumiałem jak zrobić aby STRINGI nie zajmowały już pamięci SRAM,
a zostały zapisane w pamięci FLASH.

Pozdr.

Kod:
// ------------------------
// Zdefiniowanie biblioteki
// ------------------------
#include <avr/pgmspace.h>

// -------------------------------------
// Zdefiniowanie tekstów w pamięci FLASH
// -------------------------------------
const char tekst_0 [] PROGMEM = "Tekst 0";
const char tekst_1 [] PROGMEM = "Tekst 1";

const char* const tablica [] PROGMEM = {
 tekst_0, tekst_1};

// -----------------------
// Zdefiniowanie zmiennych
// -----------------------
char bufor [30];
byte poz;

// -------------------
// Ustawienia programu
// -------------------
void setup ()
{
 Serial.begin (9600);
 while (!Serial);
}

// ---------------------
// Pętla główna programu
// ---------------------
void loop ()
{
 poz = 0;
 STRING ();
 delay (1000);

 poz = 1;
 STRING ();
 delay (1000);
}

// ----------------------------------------------
// Funkcja wyświetlająca STRING'a z pamięci FLASH
// ----------------------------------------------
void STRING ()
{
 strcpy_P (bufor, (char*) pgm_read_word (& (tablica [poz])));
 Serial.println (bufor);
}
Jeżeli pomogłem, to poproszę o punkt reputacji Big Grin
 
Odpowiedź
#4
Witam serdecznie.
wiem ze post jest stary. ale podepne sie pod niego. bo mam podobny problem. moze ktos pomoze.
szukam sposobu zeby stringi z "progmem" byly wywolywane w bardziej ludzki sposob. niz to co jest wyzej. chcialbym wywolywac te stringi z pamieci za pomoca nazw ktore mogly by byc takie same lub podobne w znaczeniu. aby przegladajac listing programu widziec jaki napis bedzie wywolany.
z gory dziekuje za podpowiedzi.
 
Odpowiedź
#5
Jeśli umieścisz zmienne we FLASH'u, musisz się do nich odwoływać w specjalny sposób. Trzeba kopiować poszczególne komórki pamięci do bufora w RAM.
Ja to robię w bardzo podobny sposób jak wyżej. Tylko, że mój sposób jest szybszy i wygodniejszy.

Deklarujemy sobie tablicę we FLASH'u.
Kod:
const char tekst[] PROGMEM = "Jakis tekst";

Jak nie wszyscy wiedzą, każdy element takiej tablicy jest wskaźnikiem do przestrzeni, gdzie przechowywane są znaki.
To nie umieści tekstu w FLASH'u, a jedynie samą tablicę wskaźników.

Teraz należy umieścić sam tekst w FLASH'u.
Ja to robię tak:

Kod:
PGM_P const p_tekst[] PROGMEM = {tekst};

Jak chcę pobrać łańcuch znaków z FLASH'a do bufora w RAM'ie, na początku deklaruję bufor.

Kod:
char bufor[8];
Zależy jak długie stringi przechowujesz, to możesz sobie ten bufor powiększyć, ale 8 bajtów to pewnie na większość rzeczy wystarczy.

I teraz trzeba przekopiować naszą tablicę z FLASH'a do bufora w RAM.
Kod:
strcpy_P(bufor,(PGM_P) pgm_read_word(&(p_tekst[0])));

I mamy normalnego Stringa z którym możemy zrobić co tam chcemy. Na przykład wyświetlić na LCD.

Jeśli masz więcej stringów, to muszisz każdy zadeklarować oddzielnie.

Kod:
const char tekst1[] PROGMEM = "Jakis tekst1";
const char tekst2[] PROGMEM = "Jakis tekst2";
const char tekst3[] PROGMEM = "Jakis tekst3";
const char tekst4[] PROGMEM = "Jakis tekst4";
const char tekst5[] PROGMEM = "Jakis tekst5";

A następnie skopiować do tablicy:

Kod:
PGM_P const p_tekst[] PROGMEM =
{
 tekst1,
 tekst2,
 tekst3,
 tekst4,
 tekst5
};

Jak chcesz odczytać konkretny tekst do bufora, to w makrze

Kod:
strcpy_P(bufor,(PGM_P) pgm_read_word(&(p_tekst[0])));

piszesz numer tablicy, która Cię interesuje, p_tekst[2], p_tekst[5] itd.

"Bardziej ludzkiej " metody nie ma.
Nie ma też sensu odczytywanie wszystkich tablic na raz:
Kod:
   char bufor[5][8];
   
   for (unsigned char i = 0; i < 5; i++)
   {
       strcpy_P(bufor[i],(PGM_P) pgm_read_word(&(p_tekst[i])));
   }
Bo właśnie wrzuciliśmy wszystkie stringi do RAM, co przecież chcieliśmy uniknąć. A jak program jest opasły, to o przepełnienie stosu łatwo.

Ameryki tym tekstem nie odkryłem.
Zapraszam do zapoznania się z manualem avr-libc na stronie
http://www.nongnu.org/avr-libc/user-manual/pages.html
A w szczególności z rozdziałem Data in Program Space
 
Odpowiedź
#6
dzieki za konkretna odpowiedz. pozdrawiam.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości