Autor: Dondu
Kurs języka C: Spis treści
Dyrektywa #include odpowiada za wstawienie w jej miejsce wskazanego jako jej argument pliku nagłówkowego. Pliki te łączone są przez preprocesor przed właściwym procesem kompilacji.
Pliki nagłówkowe zawierają z reguły deklaracje zmiennych, funkcji, klas i innych struktur danych. Pliki nagłówkowe z reguły występują w parze z plikiem programu. Na przykład gdy stosujemy gotową bibliotekę do obsługi wyświetlacza LCD, będziemy mieli dwa pliki o przykładowych nazwach:
- LCD.c (zawiera właściwy kod obsługi wyświetlacza LCD)
- LCD.h (zawiera deklaracje zmiennych, funkcji, klas i innych struktur danych).
Jednakże w programie wykorzystującym tę bibliotekę, linkujemy za pomocą dyrektywy #include jedynie plik LCD.h (plik nagłówkowy). Pliku LCD.c nie linkujemy!
Nazwę pliku nagłówkowego podaje się na dwa sposoby.
Sposób 1 - Plik wskazany pomiędzy znakami < oraz >
#include <nazwa pliku>
Tak wskazany plik oznacza dla preprocesora, że powinien szukać pliku o podanej nazwie we własnych plikach nagłówkowych. Na przykład:
#include <stdio.h> #include <string.h>
Sposób 2 - Plik wskazany pomiędzy cudzysłowami
#include "nazwa pliku"
Tak wskazanego pliku, preprocesor szukać będzie w katalogu, w którym znajduje się kompilowany plik zawierający tak napisaną dyrektywę #include.
Ścieżki do plików
W obu sposobach możesz podawać nazwę pliku wraz ze ścieżką względną lub bezwzględną na normalnych zasadach obowiązujących w systemie, na którym działa preprocesor (np. Linux, Windows, itp).
#include <avr/io.h> #include "/user/include/moj_plik.h" #include "../user/include/moj_plik.h" #include "C:\\MojeProjekty\projekt1\moj_plik.h"
Kurs języka C: Spis treści
Pliku LCD.c nie linkujemy!
OdpowiedzUsuńNo nie wiem, ale w AVRStudio6 nie linkowanie tego pliku powoduje błędy kompilacji, więc jak to z tym jest ?.
Kod:
//Pomiar napięcia przetwornikiem A/C i prezentacja wyniku na LCD 2x16 HD44780
#define F_CPU 8000000L
#include
#include
#include "HD44780.h"
#include "HD44780.c"
#include
//#include "rprintf.c"
//#include "libm.a"
// libprintf_flt.a
//definicja napiecia referencyjnego
#define VREF 2.56
//definicja ADCIN (wejście ADC)
#define ADCIN PC5
void main(void)
{
char wynik[]=" ";//bufor tekstowy, wyczyszczenie bufora
float adc;//zmienna do obliczeń napięcia
LCD_Initalize(); //inicjalizacja LCD
LCD_GoTo(0, 0); //Ustawienie kursora w pozycji (0,0)
LCD_WriteText("ADC test: 10 bit");
//Inicjalizacja ADC
ADCSRA = (1<<ADEN) //włączenie ADC
|(1<<ADPS0) //ADPS2:0: ustawienie preskalera na 128
|(1<<ADPS1)
|(1<<ADPS2);
//- wybór wewnętrznego napięcia referencyjnego 2,56V z zewnętrznym
// kondensatorem na pinie AREF
//- wybór kanału pomiarowego na pinie ADC5
ADMUX = (1<<REFS1) | (1<<REFS0) // 2,56V + kondensator
|(1<<MUX2) | (1<<MUX0); // wybór kanału ADC5
DDRC &=~ (1<<ADCIN); //Ustawienie Wejścia ADC
for(;;)
{
ADCSRA |= (1<<ADSC);//ADSC: Uruchomienie pojedynczej konwersji
while(ADCSRA & (1<<ADSC)); //czeka na zakończenie konwersji
adc=ADC*VREF/1024; //przeliczenie wartości na napięcie
sprintf(wynik,"U=%1.3f [V]",adc); //konwersja na łańcuch znakowy
LCD_GoTo(3, 1); //Ustawienie kursora w pozycji (1,1)
LCD_WriteText(wynik); //Wyświetlenie wyniku
_delay_ms(500); //opóźnienie
}
}
Nie pokazałeś, jakie błędy powoduje.
OdpowiedzUsuńBrak linkowania pliku "HD44780.c
OdpowiedzUsuńpowoduje takie błędy:
Error 4 undefined reference to `LCD_GoTo' E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\Debug/.././ADC prog2.c 26 1 ADC prog2
Error 6 undefined reference to `LCD_GoTo' E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\Debug/.././ADC prog2.c 52 1 ADC prog2
Error 3 undefined reference to `LCD_Initalize' E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\Debug/.././ADC prog2.c 25 1 ADC prog2
Error 5 undefined reference to `LCD_WriteText' E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\Debug/.././ADC prog2.c 27 1 ADC prog2
Error 7 undefined reference to `LCD_WriteText' E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\Debug/.././ADC prog2.c 53 1 ADC prog2
Oraz 2 ostrzeżenia:
Warning 2 format '%f' expects argument of type 'double', but argument 3 has type 'float' [-Wformat] E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\ADC prog2.c 51 7 ADC prog2
Warning 1 return type of 'main' is not 'int' [-Wmain] E:\PROGRAMOWANIE\MIKROKONTROLERY\AVRStudio\kurs_avrgcc\ADC\ADC prog2\ADC prog2\ADC prog2.c 18 6 ADC prog2
Program pochodzi z Drzaśkowego pamiętnika dotyczącego obsługi ADC.
Program nr.2. Dodam, że nawet mimo poprawnej kompilacji, zamiast wyniku dostajemy znak [?], ale to zapewne sprawa formatowania.
Muszę przyznać, że trudno się uczyć języka, jeśli nawet w przykładowych programach z kursów występują błędy, które potrafią skutecznie zniechęcić do nauki.To samo występuje w kursach XYZ.
Czasami może człowieka coś trafić....
Sprawdzę pliki Drzaśkowego Pamiętnika, bo rzeczywiście są błędy.
OdpowiedzUsuńPostaram się zrobić, to do piątku.
Jednak przyczyną nie jest braku linkowania pliku *.c
Przepraszam że odkopuję ten stary temat, ale mam ten sam problem co kolega powyżej, udało sie może coś ustalić?
OdpowiedzUsuńU mnie błąd ma tę samą postać - zalinkowanie tylko pliku .h powoduje warningi "xxx function declared but not defined" oraz errory "undefined reference to xxx". Zalinkowanie pliku C rozwiązuje problem
Sprawdź proszę, czy funkcja jest statyczna (static) - jeśli tak, to to jest przyczyną. Jeśli nie to zapraszam na forum, bo tutaj trudno jest wklejać kody programu.
OdpowiedzUsuńMiałem podobny problem po przejściu z WinAvr na AtmelStudio. Projekt który kompilował się bez problemu zaczął generować błedy. Problemem były różnice w rozszerzeniach nazw plików. Plik główny miał nazwę main.cpp natomiast dołączany funkcje.c . Po zmianie rozszerzenia na funkcje.cpp błędy "undefined reference" ustąpiły.
OdpowiedzUsuńRozszerzenie cpp wskazuje, że jest to plik c++ - gcc automatycznie w takim przypadku wywołuje do kompilacji avr-g++ - kompilator języka C++. Ponieważ C i C++ to dwa różne języki mogą wystąpić pewne niezgodności. Także problemem nie jest przejście z WinAVR na Atmel Studio, lecz złe rozszerzenie pliku.
Usuń