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

AVR Studio dołączanie plików do programu.

omicronNs 24 Mar 2010 15:34 2694 6
  • #1 7874442
    omicronNs
    Poziom 21  
    Witam. Zacznę od końca. Napisałem takie coś celem poznania "hierarchii" w jakiej widzą się poszczególne pliki, które są includowane.

    Główny (bla.c)
    
    #include "owire.h"
    
    int main(void)
    {
    	while(1)
    		owire_send_byte(0x44);
    }
    


    1Wire header (owire.h)
    
    #include <avr/io.h>
    
    /**********************************************************************************
    Konfiguracja pinu DQ
    **********************************************************************************/
    #define DDR_DQ DDRB
    #define PORT_DQ PORTB
    #define PIN_DQ PINB
    #define DQ 0
    
    #define INITDQ PORT_DQ&=~(1<<DQ);
    #define DQOUT DDR_DQ|=(1<<DQ);
    #define DQIN DDR_DQ&=~(1<<DQ);
    
    /****************************************************************************************************
    Ilość urządzeń 1wire
    ****************************************************************************************************/
    #define AMOUNT 1
    
    /****************************************************************************************************
    Definicje funkcji
    ****************************************************************************************************/
    u08 owire_init(void);
    
    void owire_send_byte(u08);
    
    u08 owire_get_byte(void);
    
    void owire_send_rom(u08);
    
    void owire_search_rom(void);
    
    /****************************************************************************************************
    Funkcje
    ****************************************************************************************************/
    #include "owire.c"
    


    1Wire funkcje (owire.c)
    
    #include <avr/io.h>
    #include <util/delay.h>
    
    /****************************************************************************************************
    Tablica kodów ROM
    ****************************************************************************************************/
    u08 rom[AMOUNT][8];
    
    /****************************************************************************************************
    Wysyła sygnał RESET i odbiera sygnał PRESENCE PULSE. Jeśli powodzenie zwraca 0.
    ****************************************************************************************************/
    u08 owire_init(void)
    {
    	u08 ret;
    	
    	INITDQ
    	DQOUT
    	_delay_ms(0.6);	
    	DQIN
    	_delay_us(70);
    	ret = (PIN_DQ&(1<<DQ));
    	_delay_ms(0.6);
    	
    	return ret;
    }
    
    /****************************************************************************************************
    Wysyła pojedynczy bit na linię
    ****************************************************************************************************/
    void owire_send_bit(u08 data)
    {
    	DQOUT
    	_delay_us(10);
    	if(data&0x01)
    		DQIN
    	_delay_us(70);
    	DQIN
    	_delay_us(10);
    }
    
    /****************************************************************************************************
    Odbiera pojedynczy bit z linii
    ****************************************************************************************************/
    u08 owire_get_bit(void)	
    {
    	u08 data;
    
    	DQOUT
    	_delay_us(5);
    	DQIN
    	_delay_us(5);
    	data=((PIN_DQ>>DQ)&0x01);
    
    	_delay_us(80);
    	return data;
    }
    
    /****************************************************************************************************
    Wysyła bajt danych na linię
    ****************************************************************************************************/
    void owire_send_byte(u08 data)
    {
    	u08 licznik;
    	
    	for(licznik=0;licznik!=8;licznik++)
    	{
    		owire_send_bit((data>>licznik));
    	}
    	
    	_delay_us(40);
    }
    
    /****************************************************************************************************
    Odbiera bajt danych z linii
    ****************************************************************************************************/
    u08 owire_get_byte(void)
    {
    	u08 licznik, data=0;
    	
    	for(licznik=0;licznik!=8;licznik++)
    	{
    		data|=(owire_get_bit()<<licznik);
    	}
    	
    	_delay_us(40);
    	return data;
    }
    
    /****************************************************************************************************
    Wysyła 64-bitowy numer identyfikacyjny ROM z tablicy rom[AMOUNT][8] wybranego urządzenia.
    ****************************************************************************************************/
    void owire_send_rom(u08 numer)
    {
    	u08 licznik;
    	
    	for(licznik=0;licznik!=8;licznik++)
    	{
    		owire_send_byte(rom[numer][licznik]);
    	}
    	
    	_delay_us(40);
    }
    
    /****************************************************************************************************
    Zczytuje kody ROM wszystkich urządzeń na linii 1wire
    ****************************************************************************************************/
    void owire_search_rom(void)
    {
    	u08  discrp = 0, last_bit = 0, dscnt = 0, last_zero, a, b, tmp;
    
    	do
    	{
    	
    		while(owire_init());
    		owire_send_byte(0xf0);
    		
    		last_zero = 0;
    		for(a = 0; a < 64; a++)
    		{
    		
    			b = owire_get_bit();
    			tmp = owire_get_bit();
    			
    			if((b == 0)&&(tmp == 0))
    			{
    				if(a == discrp)
    					b = 1;
    				else if(a > discrp)
    					b = 0;
    				else
    					b = last_bit;
    				if(b == 0)
    					last_zero = a;
    			}
    			
    			owire_send_bit(b);
    			rom[dscnt][(a / 8)]|=(b << (a % 8));
    			last_bit = b;
    		}
    		
    		dscnt++;
    		discrp = last_zero;
    	} while((dscnt < AMOUNT)&&(discrp > 0)); 
    	
    }
    


    Drzewo plików:
    AVR Studio dołączanie plików do programu.

    Same funkcje na 100% działają. Tylko problem mam ze zmuszeniem tego do kompilacji. Przy próbie jej przeprowadzenia wyrzuca błąd, że nie widzi definicji DQINIT, DQOUT, itp. Całego pliku owire.h mi nie widzi. Jak to poincludować wszystko żeby było tak jak powinno?

    
    Build started 24.3.2010 at 15:38:53
    avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99   -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT bla.o -MF dep/bla.o.d  -c  ../bla.c
    avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99   -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT owire.o -MF dep/owire.o.d  -c  ../owire.c
    ../owire.c:7: error: 'AMOUNT' undeclared here (not in a function)
    ../owire.c: In function 'owire_init':
    ../owire.c:16: error: 'INITDQ' undeclared (first use in this function)
    ../owire.c:16: error: (Each undeclared identifier is reported only once
    ../owire.c:16: error: for each function it appears in.)
    ../owire.c:17: error: expected ';' before 'DQOUT'
    ../owire.c:19: error: 'DQIN' undeclared (first use in this function)
    ../owire.c:20: error: expected ';' before '_delay_us'
    ../owire.c:21: error: 'PIN_DQ' undeclared (first use in this function)
    ../owire.c:21: error: 'DQ' undeclared (first use in this function)
    ../owire.c: In function 'owire_send_bit':
    ../owire.c:32: error: 'DQOUT' undeclared (first use in this function)
    ../owire.c:33: error: expected ';' before '_delay_us'
    ../owire.c:35: error: 'DQIN' undeclared (first use in this function)
    ../owire.c:36: error: expected ';' before '_delay_us'
    ../owire.c:38: error: expected ';' before '_delay_us'
    ../owire.c: In function 'owire_get_bit':
    ../owire.c:48: error: 'DQOUT' undeclared (first use in this function)
    ../owire.c:49: error: expected ';' before '_delay_us'
    ../owire.c:50: error: 'DQIN' undeclared (first use in this function)
    ../owire.c:51: error: expected ';' before '_delay_us'
    ../owire.c:52: error: 'PIN_DQ' undeclared (first use in this function)
    ../owire.c:52: error: 'DQ' undeclared (first use in this function)
    make: *** [owire.o] Error 1
    Build failed with 20 errors and 0 warnings...
    
    
  • Pomocny post
    #2 7874498
    mirekk36
    Poziom 42  
    Na sam początek to trzeba by było sobie poczytać co to jest definicja funkcji a co to jest deklaracja - bo to są dwie różne rzeczy, a po opisach które widać w tych przedstawionych plikach widać, że kolega miesza pojęcia a to właśnie m.in się mści przy prawidłowym includowaniu plików.

    Zasada jest taka, że jeśli zrobiłeś sobie np plik z funkcjami do 1wire i nazwałeś go powiedzmy owire.c to jednocześnie tworzysz drugi plik o takiej samej nazwie tyle że z rozszerzeniem *.h czyli owire.h

    W tym nagłówkowym owire.h umieszczasz wszystkie deklaracje funkcji, które chcesz udostępnić na zewnątrz tzn te z których np będzie korzystał moduł główny programu. Ale deklaracje są tym - co ty nazwałeś definicjami ;) czyli same nagłówki funkcji.

    Następnie robisz po pierwsze #include "owire.h" w swoim pliku z funkcjami owire.c, a po drugie wtedy spokojnie możesz załączyć w pliku głównym programu, który zdaje się u ciebie zwie się (tak bez sensu) bla.c także tego #include "owire.h"

    Wtedy wszystko ruszy.

    Podobnie jak z funkcjami trza zrobić ew ze zmiennymi globalnymi, które są używane w pliku owire.c jeśli są, tyle żeby umieścić ich tylko deklaracje w owire.h to trzeba poprzedzić je słówkiem extern. Czyli np masz definicję zmiennej w pliku owire.c

    int ala=122;

    to w pliku owire.h musisz wpisać tylko jej deklarację bez definicji, czyli:

    extern int ala;

    i też wszystko ładnie ruszy. Oczywiście wystawiasz do widoku publicznego też tylko te zmienne globalne, które potrzebujesz w innych modułach a nie żeby zaraz koniecznie wszystkie.
  • Pomocny post
    #3 7874534
    zumek
    Poziom 39  
    omicronNs napisał:

    1Wire header (owire.h)
    
    #include <avr/io.h>
    //...
    /****************************************************************************************************
    Funkcje
    ****************************************************************************************************/
    #include "owire.c"
    

    Po co do pliku nagłówkowego, dodajesz plik *.c - wywalić :!:



    1Wire funkcje (owire.c)
    
    #include <avr/io.h>
    #include <util/delay.h>
    

    A gdzie się podział owire.h :?:
    Przy kompilacji pliku owire.c, kompilator "nie wie", co to jest np. DDR_DQ
  • #4 7874543
    omicronNs
    Poziom 21  
    Hmm czyli deklaracje są to definicje, lecz umieszczone w pliku nagłówkowym? Rzeczywiście ruszyło bez problemów. Ale trochę to nielogiczne, dołączam do programu plik *.h , w którym przecież nie ma mowy o odpowiednim pliku *.c , więc skąd program bierze sobie funkcje?
  • Pomocny post
    #5 7874553
    mirekk36
    Poziom 42  
    omicronNs napisał:
    Hmm czyli deklaracje są to definicje, lecz umieszczone w pliku nagłówkowym? Rzeczywiście ruszyło bez problemów. Ale trochę to nielogiczne, dołączam do programu plik *.h , w którym przecież nie ma mowy o odpowiednim pliku *.c , więc skąd program bierze sobie funkcje?


    Wszystko jest piękne i logiczne ;) .... skąd bierze funkcje? ano załączyłeś plik owire.c do projektu, widać go u ciebie w drzewku projektu. Stąd wie że ma go kompilować. Gdyby nie AVR Studio to musiałbyś ręcznie "wmajstrować" go do pliku makefile, a tak AVR Studio samo pilnuje makefile na podstawie drzewka projektu.
  • #6 7874564
    omicronNs
    Poziom 21  
    Chyba zaczynam rozumieć. Do tej pory miałem inne wyobrażenie działania kompilatora. Teraz wszystko gra. Dzięki wielkie Wam. :D
  • Pomocny post
    #7 7876043
    tmf
    VIP Zasłużony dla elektroda
    To właściwie nie działanie kompilatora tylko linkera. Plik h zawierajacy deklaracje mówi kompilatorowi jak dana funkcja wygląda i jak ją wywołać. Dopiero linker składa to do kupy i łączy wywołania funkcji z właściwym kodem. Także jeśli dołączyłbyś plik nagłówkowy, bez pliku źródłowego zawierającego implementacje to kompilator przeszedłby to bez problemów, dopiero linker wyrzuciłby błędy o braku definicji funkcji.
REKLAMA