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

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

mirekk36 28 Paź 2008 08:54 3907 8
  • #1 5675127
    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"

    #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:

    #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:

    #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:

    #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:

    #include "makra_mk.h"


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

    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
  • #2 5675139
    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!!
  • #3 5675249
    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ę ???
  • #5 5675278
    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 :

    
    #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 :

    #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 ???
  • Pomocny post
    #6 5675304
    snow
    Poziom 31  
    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
  • #7 5675328
    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
  • #9 5675453
    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 ;)
REKLAMA