Fórum témák

» Több friss téma
Fórum » CCS PIC Compiler
 
Témaindító: (Felhasználó 1542), idő: Ápr 3, 2006
Lapozás: OK   96 / 118
(#) potyo válasza ernosz hozzászólására (») Jan 13, 2014 /
 
Hogy néznek ki ezek a .h és .c fájljaid? Mi van pontosan bennük? Hozzáadtad a projekthez ezeket a fájlokat is?

Amúgy találkoztam már én is ilyennel, hogy windows hibaüzenetet adott az, ha nem jól volt a forráskódban valami.
A hozzászólás módosítva: Jan 13, 2014
(#) ernosz válasza potyo hozzászólására (») Jan 13, 2014 /
 
Igyekeztem a lehető legegyszerűbb programot összeállítani, mert a lényeg az "alma.c" file kapcsolása - linkelése lenne főprogramhoz.
Ez a főprogram:
  1. #include <24HJ128GP502.h>
  2. #include "FT_Gpu.h"
  3. #include "alma.h"
  4. #include <stdio.h>
  5. #include <string.h>
  6.    
  7. #fuses XT,
  8. setup_oscillator (OSC_20000000);  
  9. #use delay(crystal=20mhz)
  10.  
  11.  void main()
  12. {
  13.         setup_adc_ports(no_ANALOGs);            delay_ms(10);
  14.         for(;;)
  15.         {              
  16.                 output_low(PIN_B15);      delay_ms(1000);      
  17.  
  18.                 led();          // ez a függvény van az "alma.c" file-ban            
  19.         }
  20. }


ez az "alma.h" file:
  1. // ez a függvény deklaráció
  2.  
  3. void led ();


és ez az "alma.c" file:
  1. // alma.c
  2. #include <24HJ128GP502.h>
  3.  
  4. void led()
  5. {
  6. output_high(PIN_B15);  delay_ms(1000);
  7. }


Fordítás után a következő hibaüzenetet kapom:

*** Error 112 "alma.c" Line 7(1,1): Function used but not defined: ... delay_ms 495 SCR=2882
1 Errors, 0 Warnings.
Build Failed.
Skipping link step. Not all sources built successfully.
BUILD FAILED: Mon Jan 13 19:19:53 2014

A kérdés továbbra is az, hogy hogyan lehet több ".c" forrásfile-ból, egy működőképes programot összeállítani. Szívesen tanulnék, csak nem találom az ösvényt !
(#) vicsys válasza ernosz hozzászólására (») Jan 13, 2014 /
 
Nem teljesen értem az alma.h funkcióját. Ellenben nem látom, hogy include-oltad volna az alma.c -t.
(#) potyo válasza vicsys hozzászólására (») Jan 13, 2014 /
 
Ha valahol azt látod, hogy
  1. #include "alma.c"

Na akkor az nem jó, .c fájlt sosem includolunk másik fájlba!
(#) ernosz válasza vicsys hozzászólására (») Jan 13, 2014 /
 
Éppen az lenne a kérdés, hogy hogyan kellene ezt helyesen beállítani. Fogalmam sincs erről az egészről. Ami információt elértem ezzel kapcsolatban abból nem derült ki mit kell tennem. Próbáltam korábban "__.c"-t include-olni, de akkor az sem sikerült, tehát éppen azt nem tudom, hogy ezt hogy lehet korrekt módon megoldani.
(#) vicsys válasza potyo hozzászólására (») Jan 13, 2014 /
 
Igen, szintaktikailag nem szabadna, de lehet. (és működik is, nem kiabál a fordító)
Viszont az include-olt header file előbb hívja meg a led() függvényt, mint ahogy az deklarálva lenne. Vagy nem? Miért nem a header-ben van megírva?
(#) potyo válasza ernosz hozzászólására (») Jan 13, 2014 /
 
Pedig a hibaüzenet egyértelmű, az alma.c fájl fordítása közben nem találja a delay_ms függvény definícióját. Mégpedig azért nem találja, mert az alma.c fáljban nem hoztad a fordító tudtára, hogy hol találja ezt a függvényt. Mivel CCS, ezért nem biztos, de ha jól sejtem, akkor az kellene neki, hogy az alma.c fájlba is betedd a
  1. setup_oscillator (OSC_20000000);
  2. #use delay(crystal=20mhz)

sorokat. Először próbáld csak az alsóval, aztán a felsővel is.

----------------

Az elmélet: minden .c fájlt a fordító külön fordít, egymástól viszonylag függetlenül. Ezért ha alma.c fájlban valami függvényt akarsz használni, ami nem magában abban a fájlban található, akkor azt a fordító tudomására kell hozni, hogy hol is találja, ugyanígy, mint ahogy a main.c-ben is
(#) potyo válasza vicsys hozzászólására (») Jan 13, 2014 /
 
Persze lehet, meg le is fordul, de egyenes út az útvesztőbe
A hozzászólás módosítva: Jan 13, 2014
(#) vicsys válasza potyo hozzászólására (») Jan 13, 2014 /
 
Szerintem egy kis program esetén, rövid az útvesztő ki lehet találni belőle. Egy komplex program esetén érthető...
(#) potyo válasza vicsys hozzászólására (») Jan 13, 2014 /
 
Jobb megszokni a rendet szerintem még az elején
(#) vicsys válasza potyo hozzászólására (») Jan 13, 2014 /
 
A volt főiskolai tanárom azt mondta:
Idézet:
„A lusta emberek forgatják a földet!”
Van benne igazság... Egy led villogtatást inkább beírom 4x is minthogy külön .h és .c állományokat hozzak létre, még egy függvényhez is lusta vagyok.
(#) Prendick válasza ernosz hozzászólására (») Jan 13, 2014 /
 
Az alma.c-be is be kell tenni a standard inkludokat, legalább az stdio-t. Abban deklarálódik a delay_ms és azt hiányolja a fordító a hibaüzenet szerint.

A fordító teljesen külön kezeli a c fájlokat, vagyis ha bármilyen alapfüggvényt hívsz, nem elég a főprogramban megadni. Alaptétel, hogy minden c fájl így kezdődik:

#include <24HJ128GP502.h>
#include <stdio.h>
#include <string.h>

Úgy kell felépíteni minden c fájlt, mintha az lenne az egyetlen. Közöttük a kapcsolatot a h-k jelentik.

Na, még hülyeséget is írtam. Természetesen a "delay" deklarációját kell betenni a hibakód miatt, de a többi se árt.
A hozzászólás módosítva: Jan 13, 2014
(#) potyo válasza ernosz hozzászólására (») Jan 13, 2014 / 1
 
A lényeg, mint írtam másik hozzászólásban, hogy a fordító minden .c fájlt külön egységként fordít. A fordítás eredményeként kapott objektum kódot utána a linker veszi kezelésbe, és linkeli össze egy egésszé. Igazából nincs kiemelt főprogram forráskód, hanem az van, hogy main() függvényt teszi a fordító oda, hogy indulás után az induljon el. Egyéb szempontból semmi kiemelt szerepe nincs a main függvénynek sem.

Tehát van egy main.c, egy alma.c és egy alma.h fájlunk. A .c fájlokat hozzá kell adni a projekthez, egyéb esetben a fordítónak valószínűleg fogalma sem lesz róla, hol találja egyiket vagy másikat. Minden .c fájlba be kell includolni azokat a .h fájlokat, amikhez tartozó dolgokat használni akarunk. Tehát pl. ha késleltetéseket használunk az alma.c fájlban, akkor kell a delay_ms függvényeket tartalmazó .h beincludolása. Ha pl. színusz függvényt akarunk számolni a main.c-ben, akkor kell a math.h a main.c-be. De ha az alma.c-ben nem számolunk színuszt, akkor oda nem kell a math.h - bár épp gondot sem okoz, csak felesleges.

A .c fájlokat tehát egymástól függetlenül fordítja a fordító. Akkor mégis mi alapján hívjuk a függvényt, a példában a led() függvényt? Az alapján, hogy a led() függvény az alma.h-ban deklarálva van, és az alma.h be van includolva a main.c-be. Ez alapján tudja a fordító, hogy az a függvény majd valahol ott lesz, és át kell adnia a linkernek, hogy keresse meg a függvény definícióját, és linkelje majd össze. A linker pedig jön, látja, hogy van egy hívás a led() függvényre, másik fájlban pedig ott a led() függvény maga, hát összeköti őket. Tehát .c fájlba kerül a függvény definíciója (ahol a {} is van), míg az ugyanolyan nevű .h fájlba kerülnek azon függvények deklarációi (a függvénytörzs nélkül, tehát {} jelek nélkül, csak a fejléc), amiket elérhetővé akarunk tenni másik forráskódok számára. Ami függvényt nem akarunk elérhetővé tenni, azokat nem tesszük be a .h fájlba.

A másik dolog a globális változók, amiket több fájlból el akarunk érni. Fontos, hogy a váltózó csak egyik .c fájlban legyen definiálva, sehol máshol. A változó definíció egyszerűen azt jelenti, hogy lefoglaljuk a helyet a változónak. Ha ezt a változót el akarjuk érni egy másik forrásfájlból, akkor a változó definícióját tartalmazó .c fájlhoz tartozó .h fájlba bele kell tennünk a változó deklarációját, ami azt jelenti, hogy ugyanazt beírjuk, csak elé teszük egy extern szócskát. Deklaráció olyasmi, hogy csak jelezzük, hogy az a változó majd ott lesz, de nem foglalunk neki helyet mégegyszer.

Tehát pl. alma.c-ben van egy szilva nevű unsigned változó, amit el szeretnénk érni main.c-ből. Akkor az alma.c-be egyszerűen beírjuk, hogy
  1. unsigned szilva;

alma.h-ba beírjuk, hogy
  1. extern unsigned szilva;

main.c-be bedig be kell includolnunk az alma.h fájlt. main.c fordításakor a fordító látja az extern unsigned szilva; változódeklarációt, ami kb. azt jelenti számára, hogy majd lesz egy szilva nevű változó valahol, át kell adni a linkernek, hogy ahol megtalálja, helyettesítse be. Az alma.c fájl is természetesen látja az extern unsigned szilva deklarációt, de mivel az alma.c fájlban ott van extern nélkül is, így tudja, hogy ott ugyanarról van szó. Alapesetben a globális változók csak forrásfájlon belül léteznek, és így lehet több azonos nevű globális változó is a projektben. Ha viszont valahol egyiket extern-ként deklaráljuk, akkor többé már nem lehet ugyanolyan nevű globális változó sehol máshol, mert a linker nem tudná, hogy mikor melyiket akarjuk elérni, ezért hibát fog jelezni. Ugyanígy nem lehet két ugyanolyan nevű függvényünk sem, mert akkor sem tudja, hogy melyiket akarjuk. Aztán kicsit még meg lehet keverni a dolgot a static kulcsszavakkal a függvények és globális változók előtt, de most mennem kell sörözni, esti mesének elég ennyi
A hozzászólás módosítva: Jan 13, 2014
(#) ernosz válasza potyo hozzászólására (») Jan 13, 2014 /
 
A "delay_ms" paranccsal egy kicsit tévútra vittem a témát, de az kiderült, hogy ezek szerint a "_.c" file-ok között nincs prioritás, és a kapcsolt "_.c"-ben is el kell végezni a beállításokat. Amit én szerettem volna az az, hogy egyes megírt funkciókat (pl. egy karakter kiírása, vagy egy szám konverziója) kikerüljön a fő programból, ahol minden függvénynek meg kell előznie a main() programrészt. Emiatt a program eleje és vége között egy végtelennek tűnő egér görgetés, és függvény káosz van. Azt hittem ez egyszerűbb lesz! Pl. a főprogram elején belinkelem a másodlagos c file.t, ami a csatolás helyén beolvasódik a főprogramba, együtt lefordul az egész és kész a kód. Csak ennyit akartam.
(#) Prendick válasza ernosz hozzászólására (») Jan 13, 2014 / 1
 
Valójában lehet, bár fordítója válogatja. Az include semmi más csak egy fájlbeszúrás. A gond az, hogy egyes kitüntetett típusú fájlokat a fordító egyedileg kezel. De ha pl. fogod az összes függvényedet a main előtt és átrakod egy alma.c1 nevű fájlba, az eredeti c-ből kitörlöd őket és beírod , hogy #include "alma.c1" közvetlenül a main elé, ha egyébként helyes sorrendben vannak a deklarációk, oda fogja befordítani a program, ahova kell. Ez csak olyan, mintha több darabba szeletelnéd a main.c-t, viszont ilyesmi a cél.

Csak ez nagyon nem ansi és roppant eretnekségnek tartják a c-s fiúk. Úgyhogy senkinek ne áruld el, hogy tőlem hallottad.

Nem tudom pontosan, hogy a CCS is így működik-e, de minden általam kipróbált c-s fordítónál működött.
(#) ernosz válasza potyo hozzászólására (») Jan 13, 2014 /
 
Köszönöm az alapos témakifejtést.
(#) vicsys válasza potyo hozzászólására (») Jan 14, 2014 /
 
Köszi, ez igen alapos megfogalmazás volt!
(#) Hp41C válasza potyo hozzászólására (») Jan 14, 2014 /
 
Egy kis kiegészítés:
A függvény deklarációja nem csak azért kell a függvényt használó modulnak (.c), hogy a linker fel tudja oldani a hivatkozást, hanem a paraméterek és a visszatérési értékek kezelése miatt is.
A forrásban levő eljárás(paramért_lista) sort fordítása során ismerni kell a paraméterek számát és típusát. Ezen információ alapján kell az aktuális paraméterek értékét a "stack" -re (kis teljesítményű kontrollereknél átmeneti RAM területre) tölteni. Ezek után egy hivatkozás kerül a fordított (obj) állományba az eljárás -ra, amit majd a linker felold. A visszatérés után (a C már csak ilyen) a hívó feladata a visszatérési érték levétele a "stack" ról (kiovasása az átmeneti RAM területről), ehhez a visszatérési érték típusát kell ismerni.
A .h állományban vagy magában a .c állományban (ha előbb hívjuk az eljárást, mint ahogy deklaráljuk) a {} nélküli deklaráció ezen információkat adja meg a fordítónak.
(#) djsms hozzászólása Jan 23, 2014 /
 
Üdv simért!
rs232-t szeretnék használni 115200-on.
Ezzel kapcsolatban lenne pár kérdésem:
-16f688 belső 8MHz-es oszcillátora mennyire lesz jó ehhez?
-jelillesztéshez max232-t használnék szokásos módon 100nF-os kondikkal. Fog ez menni ezen a sebességen?
Egy routerre kellene bejelentkezni soros konzolon és ott adatokat módosítgatni.
(#) Hp41C válasza djsms hozzászólására (») Jan 24, 2014 /
 
Csak az alábbi beállítással: SYNC =0; BRG16 = 1; BRGH = 1; SPBRGH = 0; SPBRG = 16;
(#) djsms válasza Hp41C hozzászólására (») Jan 24, 2014 /
 
Ezeket az #use_rs232-nél kellene megadni? Csak mert ilyen paraméterek nincsenek a helpben (csak hasonló) ccs 5-öt használok
Illetve ha a C4 és C5-öt adom meg akkor a hardveres uartot fogja használni?
Abból gondolom, hogy van egy kapcsoló, ami ezt tiltja. (Vagyis akkor ha külön tiltani kell akkor alapból a hardware-t használja)
  1. FORCE_SW
  2.  Will generate software serial I/O routines even when the UART pins are specified.
A hozzászólás módosítva: Jan 24, 2014
(#) sysy válasza Hp41C hozzászólására (») Jan 25, 2014 /
 
Biztos, hogy jó topicban vagy?
(#) djsms hozzászólása Jan 28, 2014 /
 
Kaptam egy 2,2"-os 320x240-es lcd panelt. Úgy nézem SPI-t használ, de google nem segített az életre keltésében
Kellene hozzá valami driver, ha tudna ebben valaki segíteni.
Erről az lcd-ről lenne szó.
(#) Gyimate válasza djsms hozzászólására (») Jan 28, 2014 /
 
Üdv!
Itt van hozzá adatlap, ebből mindent megtudhatsz: Bővebben: Link
(#) akos_b hozzászólása Feb 3, 2014 /
 
Sziasztok!

Egy villogót szeretnék készíteni aminek a sebessége soros portról vezérelhető. Az alábbi kódot raktam össze:
  1. #include <16F716.h>
  2. #zero_ram
  3. #fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT
  4. #use delay(clock=18000000)
  5. #use rs232(baud=9600, xmit=PIN_B3,rcv=pin_B2)
  6. int tar;
  7.  
  8. void main(){
  9.         tar = 100;
  10.         while(true) {
  11.        
  12.                 if(kbhit()){
  13.                         tar = getc();
  14.                         printf("Recived: %u",tar);
  15.                         putc(13);
  16.                 }
  17.        
  18.                 OUTPUT_HIGH(PIN_A0);
  19.                 DELAY_MS(tar);
  20.                 OUTPUT_LOW(PIN_A0);
  21.                 DELAY_MS(tar);
  22.         }
  23. }


Ez azonban csak akkor működik, ha kitörlöm a késleltetéses sorokat - amivel ugye az egész használhatatlanná válik. Hogyha benne hagyom, akkor váltogat 100 ms-enként, de semmilyen soros adatot nem vesz és nem is küld. Mi lehet a probléma?
(#) kurucz_peter hozzászólása Feb 4, 2014 /
 
Hali!

CCS optimiser témában lenne kérdésem. Egy 4.058-es CCS-em van. Belefutottam egy furcsa hibába. Nem értettem, hogy mi lehet a gond, aztán végső elkeseredettségemben elkezdtem kapcsolgatni az optimiser szinteket és láss csodát működött a program.
#opt7-el nem müxik viszont #opt6-al már igen. Honnan lehetne azt megtudni, hogy melyik optimalizációs szint ponosan mit optimalizál? Tud ebben valaki segíteni?

Köszi!

Üdv:
Péter
(#) Hp41C válasza akos_b hozzászólására (») Feb 4, 2014 /
 
Programozz fel egy timert -t 1 ms -es periódikus megszakítás kérésre. A megszakítási rutinjában egy belső változót csökkentsen, fa a változó 0, akkor váltsa a port bitet és töltse be a legutoljára kapott időzítés értéket a belső számlálóba. A főprogram figyelje az UART -ot, vegye át a táviratot és frissítse az időzítés értéket. Még jobb, ha az uart kezelése is megszakításos, ekkor még sok-sok feladat elvégzésére használható marad a kontroller.
(#) akos_b válasza Hp41C hozzászólására (») Feb 4, 2014 /
 
Köszi! A timeres megoldással működik. Viszont UARTos megszakítást nem sikerült megcsinálnom, mert Error 7 "main.c" Line 19(0,1): Invalid Pre-Processor directive hibát kapok a #INT_RDA sorra.
(#) vicsys válasza akos_b hozzászólására (») Feb 4, 2014 /
 
Megszakítást, csak a hardveres UART-nál tudsz kérni.
(#) Hp41C válasza vicsys hozzászólására (») Feb 4, 2014 /
 
A software uart rengeteg féle lehet. A programhurkos időzítéssel működő nem is lesz itt jó, hiszen a megszakítás kezelése is időt vesz igénybe. Az uart időzítését is meg lehet valósítani timerrel...
Következő: »»   96 / 118
Bejelentkezés

Belépés

Hirdetés
XDT.hu
Az oldalon sütiket használunk a helyes működéshez. Bővebb információt az adatvédelmi szabályzatban olvashatsz. Megértettem