Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[AVR][C] - includowanie plików typu .c i .h

mirekk36 28 Paź 2008 08:54 3412 8
  • #1 28 Paź 2008 08:54
    mirekk36
    Poziom 42  

    Witam,

    czy może ktoś mi w jakiś może nawet w trochę łopatologiczny sposób podpowiedzieć jaka jest zasada (o ile da się to krótko opisać?) jeśli chodzi o sposoby includowania plików tak żeby wciąż nie występowały błędy podczas kompilacji n/t powtórnych deklaracji itp itp.

    powiem co do tej pory wiem a czego nie to może uda się to jakoś uładzić?

    otóż napisałem sobie np plik "makra_mk.h"

    Code:
    #ifndef MAKRA_H_INCLUDED
    
    #define MAKRA_H_INCLUDED

    // Makra upraszczające dostęp do portów
    // *** PORT
    #define PORT(x) XPORT(x)
    #define XPORT(x) (PORT##x)
    // *** PIN
    #define PIN(x) XPIN(x)
    #define XPIN(x) (PIN##x)
    // *** DDR
    #define DDR(x) XDDR(x)
    #define XDDR(x) (DDR##x)

    // NOP
    #define nop() {asm volatile("nop"::);}

    #endif // MAKRA_H_INCLUDED


    już nie istotna jego zawartość, ale..... wprawdzie dałem na początku jak widać takie coś jak:

    Code:
    #ifndef MAKRA_H_INCLUDED
    
    #define MAKRA_H_INCLUDED


    choć przyznam, że tego za bardzo jeszcze nie rozumiem - ale gdzieś tam było coś takiego ;)

    piszę też sobie np jakąś swoją obsługę do uart'a i tworzę plik .c w którym wiadomo - deklaruję jakieś zmienne w tym volatile, deklaruję funkcję uart_init(); a także procedury obsługi stosownych przerwań do uart'a.

    ....... i teraz chciałbym w swoim głównym pliku projektu zainkludować to wszystko. Co robię tak np:

    Code:
    #include <avr/io.h>
    
    #include <avr/interrupt.h>
    #include <avr/sleep.h>
    #include <inttypes.h>
    #include <util/delay.h>


    #include "makra_mk.h"
    #include "uart_mk.c"

    int main(void)
    {
        uart_init();
        while(1);
    }


    no i oczywiście za chwilę kompilator "płacze" że ooo jej nie ma żadnych definicji typów i w ogóle niczego jesli chodzi o plik uart_mk.c , więc .... pakuję do pliku uart_mk.c to:

    Code:
    #include <avr/io.h>
    
    #include <avr/interrupt.h>
    #include <inttypes.h>

    no i już lepiej - nie krzyczy o to wszystko tylko jakby nie widział z kolei moich makr, więc dowalam mu jeszcze do mojego uart_mk.c:

    Code:
    #include "makra_mk.h"


    no i znowu zaczyna się płacz kompilatora z kolei, że:

    Code:
    uart_mk.c:43: multiple definition of `uart_init'


    ..... kurczę może ktoś obeznany dobrze z tym wszystkim udzieliłby początkującemu kilku wskazówek - czym się kierować chcąc unikać takich błędów, zapętleń jakby.... hmmm???? please

    0 8
  • #2 28 Paź 2008 09:06
    Freddie Chopin
    Specjalista - Mikrokontrolery

    NIGDY nie inkludujesz nigdzie plikow C. w pliku naglowkowym danego modulu dodajesz po prostu deklaracje funkcji w postaci (na przyklad)

    int uart_init(void);

    pliki h dolaczasz do swoich modulow c tak, aby byly one autonomiczne.

    zmienne robisz globalne za posrednictwem 'extern'

    w pliku c jakiegos modulu deklarujesz wiec zmienna np:

    volatile int zmienna;

    a w pliku naglowkowym: extern volatile int zmienna;

    tym sposobem mozesz uzywac tej zmiennej w calym projekcie.

    w plikach naglowkowych NIGDY nie dajesz kodu, ani zmiennych!

    4\/3!!

    0
  • #3 28 Paź 2008 09:51
    mirekk36
    Poziom 42  

    hmmm zrobiłem więc zgodnie z twoją instrukcją i wydzieliłem z mojego pliku uart_mk.c nowy plik uart_mk.h w którym dałem wszystkie #define oraz deklarację funkcji void UART_init(void);

    w pliku głównym tam gdzie mam main() dałem :

    #include "uart_mk.h"

    no i krzyczy mi kompilator, że nie widzi funkcji UART_init

    ale jak w pliku głównym dam jednak

    #include "uart_mk.c" to wtedy się kompiluje - czyli jednak tak jakby trzeba było inkludować te pliki .c ?????? czy coś jeszcze źle robię ???

    0
  • #4 28 Paź 2008 09:55
    Freddie Chopin
    Specjalista - Mikrokontrolery

    wrzuc wszystkie pliki istotne dla sprawy, wywalajac z projektu reszte. plikow C nie inkludujesz nigdy [; trust me.

    4\/3!!

    0
  • #5 28 Paź 2008 10:12
    mirekk36
    Poziom 42  

    no wierzę wierzę, tylko zastanawiam się dlaczego u mnie taka głupota wyskakuje i to zarówno w AVR Studio i w Eclipse ....

    czyli mam np taki prosty narazie plik uart_mk.c :

    Code:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <inttypes.h>

    #include "uart_mk.h"

    void UART_init(void)  // inicjalizacja UART
    {

      UBRRH = (uint8_t)(__UBRR>>8);     // ustaw prędkość transmisji
      UBRRL = (uint8_t)__UBRR;

      UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);

      // 1 bit stopu, ramka: 8 bitów, bez parzystości (8,n,1)
      UCSRC |= (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
    }


    jak widzisz powyżej posiada on #include "uart_mk.h" - czy tak powinno w nim to wyglądać?

    a poniżej sam plik uart_mk.h :

    Code:
    #ifndef UART_MK_H_
    
    #define UART_MK_H_

    #define UART_BAUD   9600         // prędkość transmisji w bit/s

    #define UART_MAX_GETSTR   24         // maksymalna długość tekstu dla UART_getstr()
    #define UART_BUF_SIZE_TX 32         // wielkość buforów UART (musi być potęgą 2)
    #define UART_BUF_SIZE_RX 254      // wielkość buforów UART (musi być potęgą 2)
    #define UART_DE_PORT D            // port linii DE konwertera RS485
    #define UART_DE_BIT   7            // bit portu linii DE konwertera RS485

    #define __UBRR (F_CPU/16/UART_BAUD-1)   // przeliczenie wartości baud_rate do rejestrów UBRRH i UBRRL

    // maski potrzebne dla działania buforów cyklicznych
    #define UART_TMASK_TX      (UART_BUF_SIZE_TX-1)   // maska bufora nadawczego
    #define UART_RMASK_TX      (UART_BUF_SIZE_TX-1)
    #define UART_TMASK_RX      (UART_BUF_SIZE_RX-1)   // maska bufora odbiorczego
    #define UART_RMASK_RX      (UART_BUF_SIZE_RX-1)

    void UART_init(void);  // inicjalizacja UART

    #endif /* UART_MK_H_ */


    jak widać na końcu tego pliku mam zgodnie z tym co pisałeś deklarację mojej funkcji inicjującej: void UART_init(void);

    no i teraz w głównym pliku gdzie mam mój main();

    podaję tylko #include "uart_mk.h"

    natomiast w main:

    int main(void)
    {
    UART_init();
    while (1);
    }

    co niestety owocuje krzykiem kompilatora, że nie widzi funkcji UART_init, że nie jest nigdzie zdefiniowana

    dodam tylko, że teraz próbowałem pliki uart_mk.c i uart_mk.h wrzucić do jakiegoś mojego folderu o nazwie MK_LIB ale oczywiście podałem w ścieżkach do przeszukiwania ten folder i to działa. Zresztą wrzucałem też do do folderu projektu i tak samo ;(

    Dodano po 3 [minuty]:

    tak się dopytam, a skąd będzie kompilator wiedział że ma podciągnąć plik uart_mk.c ???? skoro nie ma go u mnie w inkludach ---- czy na podstawie tego będzie może wiedział, że skoro inkluduję uart_mk.h to ma zainkludować niby plik c o takiej samej nazwie tylko z rozszerzeniem *.c ???

    0
  • Pomocny post
    #6 28 Paź 2008 10:19
    snow
    Poziom 28  

    Nie wiem jak w avrstudio, pewnie trzeba dołączyć do projektu. W WinAvr się w pliku makefile dopisywało że ma użyć pliku *.c

    0
  • #7 28 Paź 2008 10:33
    mirekk36
    Poziom 42  

    aaaa no właśnie coś mi tu "smierdzi" że trzeba "zagrzebać" gdzieś w związku z tym w tym całym makefile. Czyli jednak gdzieś trzeba zapodać temu kompilatorowi, że ma kompilować pliki *.c bo sam ich nie zobaczy na podstawie istniejąych tylko plików *.h

    no tak czyli teraz muszę szukać jak to zrobić w AVRStudio i w Eclipse

    0
  • Pomocny post
    #8 28 Paź 2008 10:58
    Freddie Chopin
    Specjalista - Mikrokontrolery

    w AVR studio pliki po prostu musza byc dodane do projektu i cala filozofia na ten temat.

    4\/3!!

    0
  • #9 28 Paź 2008 11:38
    mirekk36
    Poziom 42  

    Freddie Chopin -> no tak to już zauważyłem ;) teraz męczę się więc z wyszukaniem tego w eclipse. Już znalazłem nawet tam miejsce na dodanie dodatkowych obiektów typu *.o i jak podam ten mój plik .c to go ładnie "łyka" tylko, że z kolei przy takim podejściu w tym pliku .c kompilator nie widzi zmiennej F_CPU ..... no nic jeszcze pokombinuję

    Dodano po 20 [minuty]:

    pięknie no i poszło w eclipse - wystarczyło zrobić import do projektu całego pliku z folderem i ślicznie działa (oczywiście dziwi mnie to dlaczego musiałem zaznaczyć a przypadkowo to wypróbowałem - aby zaimportował wybrany plik .c razem z całym folderem źródłowym - ważne jednak że działa ;)

    eclipse - mniaaaam ;)

    0
  Szukaj w 5mln produktów