logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

AVR C - struktura - problem początkującego

gafek 13 Kwi 2009 15:15 1731 3
  • #1 6409576
    gafek
    Poziom 17  
    Witam,
    Nie jestem zbyt doświadczony w programowaniu w C dla AVR. Stawiam dopiero pierwsze kroki,więc popełniam (choć staram się nie popełniać :) ) wiele błędów wynikających ze zwykłej niewiedzy. Stanąłem więc przed kolejnym problemem, z którym nie potrafię jak na razie sobie poradzić.

    Chciałem poćwiczyć ze strukturami,więc napisałem na prędce coś takiego:
    
    #include <mega32.h>
    #include <stdio.h>
    #include <lcd.h>
    #include <string.h>
    #include <stdlib.h>
    
    #asm
       .equ __lcd_port=0x15 ;PORTC
    #endasm
    
    char lcd_buffer[33];
    char test []="123456";
    
    eeprom struct eeprom_structure {
                 char a;
                 int  b;
                 char c[11];
                 } se[10]=  {    
                            {'a',1,"pierwszy"},
                            {'b',2,"drugi"},
                            {'c',3,"trzeci"}
                            };  
                         
    void main(void)
    {
    lcd_init(16);
    
    
    
    se[0].a='h'; //nowa wartośc .a
    se[0].b=10;  //nowa wartość .b
    
    
    //Trzy próby - żadna z nich nie działa.. :(
    //strcpy(se[0].c ,"nowy_tekst"); 
    //strcpy(se[0].c,test); 
    //se[0].c="nowy tekst"; 
    
    sprintf(lcd_buffer,"%c %u %s",se[0].a,se[0].b,se[0].c);
    lcd_puts(lcd_buffer);
    
    while (1);
    }
    


    Jak widać zadeklarowałem prostą strukturę w pamięci eeprom. Jej pierwsze trzy elementy są od razu inicjowane. Następnie chciałem zmienić te elementy programowo. Z elementem a (char) i elementem b (int) nie ma problemu. Schody zaczynają się dopiero ze stringiem.

    analogicznie spróbowałem najpierw :
    
    se[0].c="nowy tekst"; 
    

    i otrzymałem przykrą wiadomość, że : the expression must be a modifiable lvalue

    W zwykłym C uczyłem się ,że zadziała
    
    strcpy(se[0].c ,"nowy_tekst");
    


    Niestety Codevision wywala mi błąd :
    function argument #1 of type 'eeprom unsigned char [11]' is incompatible with required parameter of type 'unsigned char *'

    W końcu spróbowałem:
    
    strcpy(se[0].c ,test);
    


    też bez powodzenia.


    Jak poprawnie przekazać nową wartość do pola c w tej strukturze ??

    Dla wytrawnego programisty problem na pewno jest trywialny,ale niestety ja dopiero się uczę...
    Pomóżcie, bo mi się świąteczne jajko w żolądku chce cofnąć.... :)

    Pozdrawiam !
    Andrzej.
  • #2 6409702
    BoskiDialer
    Poziom 34  
    Modyfikator eeprom pewnie coś psuje. Nie znam tego kompilatora, ale spróbuj coś takiego:
    void strcpye(eeprom char* dptr, const char* sptr)
    {
      while((*dptr++ = *sptr++) != 0)
        ;
    }
  • #3 6409775
    mirekk36
    Poziom 42  
    Witam,

    a ja ze strukturami albo uniami robię tak i zawsze działa to świetnie w takich przypadkach o jakich piszesz. Najpierw definiuję sobie typ:

    typedef union {
    	uint8_t bytes[2];
    	struct {
    		uint8_t max_ilosc_minut_drzemki;
    		uint8_t max_czas_alarmu;
    		uint8_t tryb_zmiany_kolorow;
    	} var;
    } e_zmienne;


    albo taka struktura:
    typedef struct {
    	uint8_t min_bcd;
    	uint8_t godz_bcd;
    	uint8_t dzien_bcd;
    	uint8_t miesiac_bcd;
    	uint8_t dni_tygodnia;
    	uint8_t active;
    	uint8_t drzemka;
    	uint8_t drzemka_minuty;
    	uint8_t drzemka_co_ile_minut;
    	uint8_t rodzaj_alarmu;
    	uint16_t timeout;
    } ualarm;


    może on być zdefiniowany w jakimś pliku nagłówkowym, dzięki czemu później wszędzie można przez wskaźnik się do tego odwoływać.

    później definiuję sobie tak:

    #define EEMEM __attribute__((section(".eeprom")))
    
    ualarm ee_alarmy[10] EEMEM;
    e_zmienne eeprom_zmienne EEMEM;
    e_zmienne *eep_zm = eeprom_zmienne;
    
    e_zmienne ram_zmienne;
    e_zmienne *ram_zm = ram_zmienne;
    


    dzięki czemu później w kodzie ładnie to działa np tak:

    najpierw wczytuję ładnie z epromu do podobnych struktur w ramie, gdy potrzeba użyć:

    eeprom_read_block(alarmy, ee_alarmy, sizeof(alarmy));
    eeprom_read_block(ram_zm, eep_zm, sizeof(ram_zm));


    a potem działam na strukturach w ramie:

    ram_zmienne.var.max_czas_alarmu = 10;
    
    alarmy[0].active = 0;


    a gdy już trzeba zapisać coś albo wszystko znowu do eeprom to:

    eeprom_write_block(alarmy, ee_alarmy, 12);
  • #4 6411873
    gafek
    Poziom 17  
    Dzięki za odpowiedź.

    Rzeczywiście modyfikator "eeprom" strasznie gmatwa w tym wszystkim. Kiedy działam na ramie wszystkie książkowe sposoby jak najbardziej działają ,C "zachowuje" się jak C :) Kłopoty dopiero zaczynaja się po zastosowaniu modyfikatora. :( Na razie będe musiał stosować się do zasady przyjętej przez mirekk36. Operować danymi w ramie i zapamiętywać potem w EEpromie.
REKLAMA