Keresés

Új hozzászólás Aktív témák

  • #90088192
    törölt tag

    Igazából processzor típusonként és C fordítónként is változhat, hogy melyik milyen algoritmust használ. De az eléggé általános, hogy valamilyen gyorsan konvergáló iteratív algoritmussal történik, nem pedig táblázatból olvassák ki. Régebben, még az FPU-k előtti időkben volt inkább jellemző pl. játékprogramokban a táblázatok használata, ahol nem volt szükség nagy pontosságra, viszont nagyon gyorsnak kellett lennie.

    Mindig valami új, azért érdeklődöm, mert tirisztor gyújtás szöget akarok kiszámolni a szinusz hullám integrálásával ami megadott kimenő teljesítmény mellett értendő
    A másik pedig egy inverter IGBT gyujtasa ami impulzus alapon nyugszik, vagyis egyfajta kvantalast akarok csinálni.

    Tudom ez nem C de a matek igen, hiszen egy processzor lesz megbízva a számítással. :R

    Köszönöm

  • #90088192
    törölt tag

    A processzorok általában egy speciális iterációs algoritmussal számítják ki a szögfüggvényeket. Ezt úgy hívják, hogy CORDIC, aminek az az alapja, hogy a szöget felbontják olyan kisebb szögek összegére, amiknek a tangense 1/kettőhatvány. Az ilyen szögekkel történő forgatásnál a szorzást shifteléssel lehet helyettesíteni, ezért lesz hatékonyabb ez a módszer a Taylor-sor használatánál.

    Köszönöm a részletes választ, nem sok ismeretem van ezen a téren ezért érdeklődöm.

    Akkor C Ben van direkt szögfüggvéy számolás, ami lefordithato gépi nyelvre és végre hajtható.
    Persze most X86 utasítás alapú proci amiről beszélünk. :R

  • #90088192
    törölt tag

    Akkor atfogalmazom, a processzor egy megadott szögből, képes-e kiszámolni a hozzá tartozó értéket a szögfüggvénynek megfelelően, vagy csak táblázatból lesi ki? Ez a kérdés magában a C nyelvben is. Van e egy táblázat amiből kilesi, vagy van rá eljárás ami ki tudja számolni/meg tudja közelíteni? :R

    Hülyeséget kérdeztem?

  • #90088192
    törölt tag

    Vagy nem teljesen érthető a kérdésed, vagy nekem vagy nagyon hétfő.

    Ha jól azt szeretnéd elérni, hogy ne kiszámolja, hanem rögtön adja vissza az értéket, ugye? Gondolom ez a sebesség miatt kell.

    A lookup table-re keress rá. Ezt sokféleképpen lehet implementálni. Talán a legegyszerűbb, hogy minden fokra legenerálod előre egy tömbbe és majd arra hivatkozol. Valahogy így:

    const float degree_to_sin[] = 
    {
        0,     /* 0 degree */
        0.017, /* 1 degree */
        ...
    };
    float res = degree_to_sin[1]; // res = sin(1)

    Persze ilyenkor a pontossággal lehetnek gondok.

    Akkor atfogalmazom, a processzor egy megadott szögből, képes-e kiszámolni a hozzá tartozó értéket a szögfüggvénynek megfelelően, vagy csak táblázatból lesi ki? Ez a kérdés magában a C nyelvben is. Van e egy táblázat amiből kilesi, vagy van rá eljárás ami ki tudja számolni/meg tudja közelíteni? :R

  • #90088192
    törölt tag

    Tudtommal az Intel processzorok tartalmaznak transzcendens (sin, log,...) floating point műveleteket. Egyébként valószínűleg vegyesen használnak táblázat adatokat, és közelítéseket. Igen hatékony tört közelítések léteznek ezekre. A szögfüggvények hatványsorai ugyan gyorsan konvergálnak, de tudtommal nem ezeket használják. Lehet, hogy táblázatból kikeresik a legközelebbi érték sinusát, majd az akörüli Taylor sor néhány tagjából egy törtet számítanak ki. Ez csak tipp.

    Köszönöm, akkor jól sejtettem, a mértani sorozat nem írható fel egyszerűen egy/több lineáris függvénnyel, ami könnyen számolható egyszerű alapmuveletekkel. :R

  • #90088192
    törölt tag

    Nekem lenne egy kérdésem: a szög függvény számítható dolog, vagy adathalmazként van tárolva?
    Értem ez alatt, hogy a pl Sin 45 az 0.707.
    Tömbben van tárolva és arra hivatkoznak az elérhető könyvtárak vagy van valami módja annak hogy több adat bevonása nélkül kiszamoljuk?

  • #90088192
    törölt tag

    A számítástudomány az tényleg sokkal előrébb járt, mint maguk a számítógépek, George Boole (a Boole-algebra (a számítógépeknél alkalmazott logika) megalkotója halála után még majdnem egy évszázadott kellett várni az első digitális számítógépre, az információelméletről meg Shannon kb. mindent elmondott az 1940-es években.

    A GOTO-problematika viszont nem ide tartozik, az színtisztán gyakorlati kérdés - azt Ada Lovelace nem láthatta előre, amikor Babbage gépére talált ki pár soros programokat, hogy milyen érzés lesz olyan kódot túrni, amit egy tíz évvel ezelőtt más céghez távozott kolléga írt :)

    Az, hogy feltétlenül kell egy olyan utasítás, ami megváltoztatja a program végrehajtási helyét, az soha nem is volt kérdés, persze, hogy kell. Sőt, több is kell, mert olyanok is kellenek, amik különféle feltételek alapján változtatják meg.

    Az összes processzorban vannak ilyen utasítások, senkinek semmi baja nincs ezzel, senki nem akarja kiírtani, vagyis tulajdonképpen bármilyen program fut a gépeden az tele van JMP-kkel (a GOTO gépi kódú megfelelőjének ez a mnemonikja).

    Viszont a magasabb szintű nyelvekbe ezt egyre inkább becsomagolták, mint ahogy minden egyéb ilyen nyers dolgot is, hiszen a programozók általában nem arra vágynak, hogy megváltoztassák a programszámláló tartalmát, mert csak, hanem valamilyen összetett struktúrát hoznak létre: hurkot, feltételes programvégrehajtást, ilyeneket. Márpedig ha ők ilyeneket akarnak létrehozni, akkor adjunk a kezükbe olyan eszközöket, amikkel ezt csinálják közvetlenül, ahelyett, hogy JMP-vel bohóckodnának.

    Ezzel együtt a GOTO megmaradt egy csomó magasabb szintű nyelvben is, egyszerűen azért, mert az azokban meglévő struktúrák lefedték a GOTO-használat nagyon-nagyon-nagy részét, de nem az összeset, így aztán maradtak olyan helyek, amikor az ember azt használja, mert adott esetben nincs jobb megoldás rá.

    Magam laikus létben 110% van egyet értek veled. :R

  • #90088192
    törölt tag

    Idézet innen: > Ezekben a különböző számítógépeken futó BASIC programok szinte mindig inkompatibilisek voltak egymással: az egyik géptípusra írt programot más számítógéptípusokon nem lehetett futtatni.

    Ez azért nem a magas szintű nyelvekre jellemző tulajdonság. Továbbá: > Az 1990-es évek elejére sokan leírták a Basicet, mivel a Basic alapú mikroszámítógépek kora lejárt, PC-n a C/C++ és a Pascal nyelvek vívtak ki vezető szerepet.

    Igazából nem csak sokan leírták a BASIC-et, hanem a valóságban meg is szűnt. A Visual Basic már nem BASIC, csak BASIC-alapján készült. De már a Visual Basic is inkább csak a VBA-ban létezik. A Vb.Net meg egészen más dimenzió.

    sztanozs elítélt, mert pascal témakörben készült irományokból idéztem. De ezek az idézetek nem csak a Pascal-ra vonatkoznak, hanem általánosan is igazak. Mint ahogyan írták, Pascalban nincs is return. Ettől függetlenül lehet a függvény törzsében is értéket adni a függvénynek a függvénynév:=valami formátumban(ej, de régen Pascaloztam). De látható, hogy a C-hez viszonyítva ennyivel szigorúbb nyelvben is tiltják a Goto-t(alapból nem is lehet használni benne, csak direktívával lehet bekapcsolni).

    De ha mindenképpen ragaszkodunk ahhoz, hogy csak szigorúan C nyelvre létrehozott irományokat fogad el valaki, akkor az olyannak meg itt van ez. Itt ezt írja:
    > A strukturált programozást a goto utasítás elkerülésére, a program olvashatóbbá tételére találták ki, ezért a goto használata egyáltalán nem javasolt.

    Ezt direkt a C nyelvre írták(nem Pascal-ra).

    A "ma" használt nyelvek között már a BASIC nem található meg. Sőt, az ismertebb nyelvek közül pl. a Java-ban nem is létezik a goto. Ebben a nyelvben pl. a #6219-es hsz-emben írt kódot nem is lehetne megírni. Java-ban a break-nek van 1 olyan "kibővített" funkciója, hogy egymásba ágyazott ciklusok esetén label használatával meg lehet adni, hogy a break melyik ciklusra vonatkozik. De ez nem egyenlő a goto-val(amivel össze-vissza LEHET ugrálni).

    Szóval akárhol nézegetek utána, mindenhol a legfinomabb megfogalmazás is az, hogy nem ajánlják a használatát.

    Látod, a lényeg Nem ajánott, abból semmilyen logikával nem következik a tiltott.

    Vagyis aki tudja elkerülni, de ez nem azt jelenti hogy nem lehet használni. Ezért vaskalapos és hibás az ELTE logika.

    Csak ezt nehéz beismerni.

    Tudod tekintély elvű marhaság.

    El lehet mondani, hogy próbáljuk ne használni, de ha épp az a legegyszerűbb, legolvashatobb megoldás, akkor miért ne?

    Én elkezdtem C Ben illeszto programot írni PIC re, érdekes, nekem eszembe sem jutott GOTO-t használni pedig előképzettség részemről 0.
    Van amit nem lehet tanítani, max megérteni.
    Ezért tartom marhaságnak a tiltást.
    A legtöbb okos sokkal többet tud mint amit valójában megért, mert bemagolt frazisokat hajtogatva okosnak lehet tűnni. Nem azt jelenti, hogy érti is miről beszél :( (nem személyes, nem neked szól, ne vedd magadra kérlek :R )

  • #90088192
    törölt tag

    BASIC != Visual Basic. A BASIC nem magas szintű nyelv(legalábbis ez alapján). Amit írsz, hogy pont azért olyan amilyen, hogy Egyszerű legyen használni, ez a Visual Basic-re igaz. A BASIC-et nem volt 1szerű használni. Ha azt látod, hogy GOTO 100, akkor honnan tudod, hogy mi van a 100-as sorban? De szükség volt a GOTO-ra a sorok számozása miatt. A Visual Basic-et valóban 1szerű használni, de ott meg szükségtelen a GOTO használata. Tényleg csak hagyománytiszteletből maradt benne.

    Azért a marcsának és a csajnak nem ugyanaz az eredménye. Marcsánál nincs, ami olajozza/ápolja a matériát! :(

    Nekem a BASIC magas szintű az ASM és a gépi kodhoz hasonlítva. Nem tudom hol a határ, de nem volt megerőltető a BASIC Ben való programozás. Az ASM viszont tortúra számomra már látvány szinten, így sosem volt hozzá szerencsém.

    A csaj és Marcsa esetén a végeredmény ugyan az :K

    Megszabadulhat az ember pár gramm feherjetol.

  • #90088192
    törölt tag

    Hogy miért találták ki? Hát pl. azért, mert a BASIC-ben pl. lehetetlen volt a programozás nélküle(ott még a sorok számozva voltak. De itt is írják:
    > Léteztek olyan ősnyelvek, amelyekben nélkülözhetetlen volt

    Hát többek között ezért. Na meg azért, mert akkor még nem bizonyították be, hogy GOTO nélkül mindent meg lehet oldani, nincs szükség rá.

    Egyébként itt osztályozzák a programnyelveket, ahol látszik, hogy a C/C++ is magas szintű nyelv.

    Köszönöm, ami ismereteim illeti, én úgy tudom, a számítás tudomány jóval megelőzte a valós felhasználást (lásd belső égésű motorok, az összes típus fel lett találva, mielőtt azt meg tudták volna építeni), vagyis a matematika, strukturális alapok megvoltak már rég, főleg ha az alacsonyabb rendű nyelveket vesszük figyelembe. Hiszen a szövő gépet is programozni kellett. A logikai adott, ott sem volt GOTO.

    Vagyis valamiért megjelent, a BASIC nagyon jó példa, pont azért olyan amilyen, hogy Egyszerű legyen használni.
    Vagyis ezzel el is érkeztünk a GOTO lét jogosultságához.
    Azért létezik kb minden program nyelvben, mert lehet maszturbalni, meg lehet egy gyönyörű csajjal szeretkezni. Mindkettő rendelkezésre áll, mindkettőnek ugyan az az eredménye. Persze lehet tiltani a csajt, maradj csak a marcsanal. De akkor minek vannak csajok? :R

  • #90088192
    törölt tag

    Látom, hogy hozzászólásonként válaszolsz. #6181-ben leírtam, hogy nevemfel #6179-ben lévő megoldása a legjobb arra a feladatra(nem az enyém).
    #6184-ben Stroustrup-ot idéztem, aki azt írta, hogy:
    >A "soha ne tegyük ezt" alakú szabályokat haszontalannak tekintem.
    A #6190-ben idéztem László Józsefet:
    >A goto utasítást a Pascal-ban nem használjuk, mert ugye programozók vagyunk.
    Majd a #6197-ben innen is idéztem 2 programnyelvtől független idézetet.

    A véleményem a #6209-ben foglaltam össze. A goto-cimke párossal összevissza lehet ugrálni, áttekinthetetlen lesz a kód tőle. Ha cimkét látsz, akkor egyrészt nem tudod, hogy fentről, vagy lentről tévedt oda a vezérlés. De azt sem tudod ránézésre, hogy amik utána vannak utasítások, azok micsodák(pl. a cimke 1 ciklus kezdetét jelzi-e, vagy egy - vagy több - if ágból ugrottak-e oda). Ugyanakkor, ha goto-t látsz, akkor sem tudod, hogy az a cimke felfelé, vagy lefelé ugrik-e. Az összevissza ugrálás lehetősége miatt mondom én azt, hogy a goto - cimke párost soha! Míg ha azt látod, hogy while(f), akkor totózás nélkül, kapásból tudod, hogy mi következik(1 cimkével ellentétben).

    Én ugyan nem vagyok programozó, de remélem, hogy az ELTE-n(is) vaskalaposan ragaszkodnak a struktúrált programíráshoz, és tiltják a goto-t azokban a nyelvekben is, amelyekben még létezik. Mert ahogy a fenti linkemen is írják:
    >a mai magasszintű nyelvekbe azonban többnyire hagyománytiszteletből került be, nincs rá szükség. (mármint a goto-ra).

    Mint lelkes amatőr, megkérdezhetem, miért is találták ki a GOTO utasítást?
    Mert ugye valami oka volt.
    Ahogy tudom, a ciklusok és elágazások egyidősek a GOTO val. :R

  • #90088192
    törölt tag

    Én a break-et is tiltanám, biztos-ami-biztos alapon. Végül is az is csak egy goto (coated in synthetic sugar)...

    Még milyen dolog a return, tessék rekurziv logikát használni ;]

  • #90088192
    törölt tag

    Most már értem, a karakter kiírásban, az y_offset a koordinatat határozza meg, a string kiiaratasban, meg ugye léptetését kell csinálni, hogy ne egymásra írja a karaktereket. Vagyis SZVSZ nem tudok vele semmit csinálni, hiszen van ahol csak 1db karaktert akarok kiiratni, akkor pedig nem működne ha jól sejtem :R

    Ahogy többet gondolkodom, egyre jobban értem miért hoztad fel :R

    Akkor kellene még egy paraméter, ami megmondja hányadik karakter a referencia koordinátától. Vagyis ha a szorzata 0 akkor lényegtelen :R

    Tetszik, csak nehezen értettem meg. Elnézést :R

  • #90088192
    törölt tag

    :R

    :DDD

    Az a string kiiratas most már értem.

    Most már értem, a karakter kiírásban, az y_offset a koordinatat határozza meg, a string kiiaratasban, meg ugye léptetését kell csinálni, hogy ne egymásra írja a karaktereket. Vagyis SZVSZ nem tudok vele semmit csinálni, hiszen van ahol csak 1db karaktert akarok kiiratni, akkor pedig nem működne ha jól sejtem :R

  • #90088192
    törölt tag

    Arra gondoltam, hogy egy korábbi hozzászólásodban így hívtad meg a write_char-t:

    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);

    És ebben a második paraméterben használod a Font_width-et is, ezt lehetne kiiktatni, ha egy struktúrában úgyis átadod a font paramétereket. Ehhez át kellene alakítani egy kicsit a paraméterezést (pl. ahogy javasoltam: kettéválasztani egy y és egy j paraméterre, és a write_char függvényen belül elvégezni az y+j*Font_width számolást).

    :R

    :DDD

    Az a string kiiratas most már értem.

  • #90088192
    törölt tag

    Persze, teheted a font paramétereket egy struktúrába, és akkor elég átadni erre a struktúrára mutató pointert a font választáshoz (vagy csúnyább esetben mehet az egész egy globális változóba). Pl:

    #include "font1.h"
    #include "font2.h"

    struct font_type
    {
    long int *font;
    int font_width;
    int font_height;
    int font_offset;
    };

    struct font_type myfont[2];

    myfont[0].font = Font1;
    myfont[0].font_width = Font1_width;
    myfont[0].font_height = Font1_height;
    myfont[0].font_offset = Font1_offset;

    myfont[1].font        = Font2;
    myfont[1].font_width  = Font2_width;
    myfont[1].font_height = Font2_height;
    myfont[1].font_offset = Font2_offset;


    int write_char(int page_select, int y_offset, int character_code,struct font_type *use_font)
    {
    ...
    send_data_screen(use_font->font);
    ...
    }

    write_char(line,y_offset+j*myfont[0]->font_width,test[j],&myfont[0]);

    write_char(line,y_offset+j*myfont[1]->font_width,test[j],&myfont[1]);

    De lehet, hogy jobb lenne az y_offset paramétert szétszedni egy y és egy j paraméterre, és a font_width-tel való szorzást beletenni a függvénybe, hogy ne kelljen azt is font-tól függően átadni:

    int write_char(int page_select, int y, int j, int character_code,struct font_type *use_font)
    {
    int y_offset = y+j*use_font->font_width;
        ...
        send_data_screen(use_font->font);
        ...
    }

    Köszönöm :)

    Az y_offset át kell hogy nevezzem mert megtévesztő, ez az x tengelyen való eltolást jelöli, semmi dolga nincs magával a fonttal, vagy nem teljesen értelek :DDD

    Próbáltam utána olvasni a struktúrának, egyenlőre nem vagyok vele meg kibékülve, de dolgozom rajta :R

    A másik dolog amin ügyeskedek, a font magassága se jelentsen problémát, vagyis képes legyek több memória lapra kivetítve is elküldeni az adatokat. Arra mar rá jöttem, a font sima decimálisban van(olyat találtam mind a 16 bit egy számot alkot, ami a magasságát teszi ki a karakternek), akkor egyszer 8 pozíciót jobbra, máskor 8 pozíciót balra kell tolni és maris megvan a 8-8 bit, vagy legalábbis remélem :C

    A memória olvasást megoldottam, így mar tudok 1 db pixelt bárhol kapcsolni, anélkül, hogy befolyásolnám az adott lapon levő többi pixelt :K

    Köszönet a segítségért meg egyszer :R

  • #90088192
    törölt tag

    Ha jól értem, paraméterben szeretnéd átadni a write_char() függvényednek azt, hogy milyen betűkészletet használjon. Ehhez össze kell szedned, mi definiálja a betűkészletet. Egyrészt a Font[] tömb, másrészt a Font_width, Font_height, Font_offset (ha nem hagytam ki valamit). Ezeket fel kell venned még plusz paraméterként és átadnod a write_char()-nak, pl:

    int write_char(int page_select, int y_offset, int character_code,
    long int *font, int font_width, int font_height, int font_offset)

    És így tudod pl. meghívni:

    write_char(line,y_offset+j*Font_width,test[j],Font,Font_width,Font_height,Font_offset);

    Mivel az y_offset számolásában is használod a Font_width-et, így szebb lenne ezt a függvényen belül végezni.

    Ha pedig mindegyik betűkészlet ugyanolyan méretű, akkor elég csak a font tömböt átadni, nem kellenek a betűméretek.

    Köszönöm :R

    Valahol láttam, de nem tálalom, egy olyan megoldást ahol külön h ban tároltak minden fontot, és talán struct megoldással átvették mindig az aktuális tömböt, és a hozzá tartozó magasság és egyébb paramétereket.

    Erre lenne ötlet? :R

    Előre is köszönöm :R

  • #90088192
    törölt tag

    Hello :)

    Elmétek kiapadhatatlan tudás forrását, szeretném ismételten megcsapolni :R

    Lenne egy olyan problémám, hogy a tömb nevét szeretném változtatni attól függően milyen betűtípust akarok használni. Font neven fut, és ha változóval próbáltam helyettesíteni nem ment.
    Gondolom van rá megoldás, csak nekem új :R

    Előre is köszönöm

    Ez lenne a példa részlet:
    int write_char(int page_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=( Display_width/2) && y_offset <= Display_width - Font_width && charcater_code>=32 && charcater_code<=128) //Check which side of the screen need to be activated
    {
    goto_xy( page_select, y_offset);

    for(x=( charcater_code - Font_offset ) * Font_width; x<(( charcater_code - Font_offset)* Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen( Font[x]); //Sends out the relevant section of the Array
    }
    } else if( y_offset<( Display_width/2) && y_offset>=0 && charcater_code>=32 && charcater_code<=128)
    {
    goto_xy( page_select, y_offset); //Selects pages of writing
    for(x=( charcater_code - Font_offset)* Font_width; x<(( charcater_code - Font_offset) * Font_width)+ Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    { if( y_offset + (x-( charcater_code - Font_offset) * Font_width)!=( Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen( Font[x]);
    }
    else
    { //If the Character is belong to the right side
    goto_xy( page_select,( Display_width/2)); //Selects pages of writing
    send_data_screen( Font[x]); //Sends out the relevant section of the Array


    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;

    }

    }

  • #90088192
    törölt tag

    Szerintem csak annyi a gond, hogy a data_read() egy függvény, aminek a visszatérési értékét (ill. ehhez hozzácsapva még biteket) akarod átadni a send_data_screen()-nek. Viszont hiányzik a "()", így ténylegesen nem hívod meg a data_read-et, hanem a függvény címét adod át. Próbáld meg így:

    send_data_screen(data_read() | (BASE_ADDRESS_PIXEL << x%Display_pages));

    :W :W :W :W :W
    :R :R :R :R :R :R

    Az volt az :DDD

    Köszönöm

  • #90088192
    törölt tag

    A lényeg éppen lemaradt, hogy mi a Display_pages. Tippre egy ilyen szignatúrájú függvény: int (*)(void). Vélelmezhetően így kellene meghívnod: Display_pages().

    Hello :R

    #define Display_pages 8

    8 X 8bites lapokra van vertikálisan felosztva a képernyő.

    Ennyi lenne :K

  • #90088192
    törölt tag

    Hello Mindenkinek

    Segítséget szeretnek kerni, falba ütköztem, de nem értem miért.

    ../screen.c: In function 'put_pixel':
    ../screen.c:128:35: error: invalid operands to binary | (have 'int (*)(void)' and 'int')
    send_data_screen(data_read | (BASE_ADDRESS_PIXEL << x%Display_pages));

    Maga a probléma, amit addig értek(?), hogy nem lehet bináris műveletet elvégezni pointeren.

    Azt nem értem miért lett az pointer :DDD

    A program részletek amik relevánsak(Elnézést még nem kommenteltem az új szekciót mert nem működik):

    int data_read(void)
    {
    int data_in;
    DISPLAY_RS = 1;
    DISPLAY_RW = 1;
    DISPLAY_DATA_DIRECTION = 1;
    DelayUs(Hardware_delay*2);
    data_in = S_DATA_IN;
    DelayUs(Hardware_delay*4);
    DISPLAY_DATA_DIRECTION = 0;
    return(data_in);

    }

    int send_data_screen (long int Data_out) //Sends Data to the Display hardware
    {
    if(Data_out<=(Dislpay_height/Display_pages)*(Display_width/2) ) //Checks is the data length is valid
    {
    DISPLAY_EN = 0; //Turns Display Off
    DISPLAY_RS = 1; //Enables Data mode
    DelayUs(Hardware_delay);
    S_DATA_OUT = Data_out; //Insert Data to the hardware line
    strobe_E(); //Turns Display On/off
    DISPLAY_RS = 0; //Disables Data mode

    }else{
    return(1);
    }
    }
    int put_pixel(int x, int y)
    {
    if(x>=0 && x<=63 && y>=0 && y<=127)
    {
    goto_xy(x/Display_pages,y);
    send_data_screen(data_read | (BASE_ADDRESS_PIXEL << x%Display_pages));

    }else{
    return(1);
    }
    }

  • #90088192
    törölt tag

    Koszonom :R
    Remélem erre gondoltál :)

    Különben igen érdekes maga a probléma, a bal oldali képernyő gyakorlatilag túlcsordul(Módosítottam a kodon így is duplázza az oszlopokat, es elkezd a 0. oszlopba írni)

    Maga a problémás részlet:

    void write_char(int line_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=(Display_width/2) && y_offset<=Display_width-Font_width) //Check which side of the screen need to be activated
    {
    lcd_select(1); //if the offset is bigger than 63 than the right side

    set_y(y_offset-Display_width/2); //Deducts the the half of the display size Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<=((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    } else if(y_offset<=(Display_width/2)-1 && y_offset>=0) {

    lcd_select(0); //selects the left side of the screen

    set_y(y_offset); //Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(y_offset+(x-(charcater_code-Font_offset)*Font_width)!=(Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen(font6x8[x]);

    }else{ //If the Character is belong to the right side

    lcd_select(1); //If yes selects the the right side
    set_y(0); // Resets the offset
    set_x(line_select); //Selects line of writing
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;
    }

    }

    Es az egesz en block

    #include "font6x8.h"
    #include "screen.h"
    #include "membrane.h"

    #define Font_width 6
    #define Font_offset 32
    #define Font_height 8
    #define Display_width 128
    #define Dislpay_height 64
    #define Display_rows 8

    //#define Font_type font6x8

    void InitalizePorts_display(void)
    {
    S_DATA_OUT=0;
    S_DATA_IN=0;
    DISPLAY_Dir=0;
    DISPLAY_CS1=1;
    DISPLAY_CS2=1;
    DISPLAY_RS=1;
    DISPLAY_RW=0;
    DISPLAY_EN=0;

    /* Command port direction settings */

    DISPLAY_CS1_Direction =0 ;
    DISPLAY_CS2_Direction =0 ;
    DISPLAY_RS_Direction =0 ;
    DISPLAY_RW_Direction =0 ;
    DISPLAY_EN_Direction =0 ;

    DelayUs(100);
    }

    void lcd_select(int s)

    {
    if(s==0)
    {
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 0; //Deselects Right side of the screen
    DelayUs(15);
    }else if(s==1)
    {
    DISPLAY_CS1 = 0; //Deselects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    DelayUs(15);
    }else{
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    DelayUs(15);
    }
    }

    void strobe_E(void) //Turns enabling line off/on
    {
    DelayUs(5);
    DISPLAY_EN = 0; //Turns Display Off
    DelayUs(5);
    DISPLAY_EN = 1; //Turns Display On
    DelayUs(5);
    }

    void set_y(int y) //Set Y coordinate 0-63 on the active side of the screen
    {
    DISPLAY_RS = 0; //Sets Instruction mode
    DelayUs(5);
    S_DATA_OUT = (0b01000000+y); //Set Y coordinate
    strobe_E();
    }

    void set_x(int x) //Select one of the 8 bit line out of the 8
    {
    if(x<=Display_rows-1 && x>=0) // Verify input parameter is in range
    {
    DelayUs(5);
    DISPLAY_RS = 0; //Sets Instruction mode
    DelayUs(5);
    S_DATA_OUT = 0b10111000+x; //select the desired line from the 8 X 8bit lines
    strobe_E();
    }else{
    MEMBRANE_MUTE=1;
    }
    }


    void send_data_screen (long int Data) //Sends Data to the Display hardware
    {
    DISPLAY_RS = 1; //Enables Data mode
    DelayUs(5);
    S_DATA_OUT = Data; //Insert Data to the hardware line
    strobe_E();
    }
    void dsp_on(void)
    {
    DISPLAY_RS = 0; //Instruction mode
    DelayUs(2);
    S_DATA_OUT = 0b00111111; //Turns display controller ON
    DelayUs(2);
    DISPLAY_EN = 1; //Turns Enable line ON
    strobe_E();
    }

    void clr_scr (int Fill)

    {
    int x; int y;
    lcd_select(2); //Select both side of the display for quicker action
    for(y=0;y<=Display_rows-1;y++) //Loop for the rows
    {
    set_y(0); //Set y to 0
    set_x(y); //Selects line of writing
    for(x=0; x<(Display_width/2); x++) //Loop for the columns
    {
    send_data_screen(Fill);
    }
    }


    }

    void write_char(int line_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=(Display_width/2) && y_offset<=Display_width-Font_width) //Check which side of the screen need to be activated
    {
    lcd_select(1); //if the offset is bigger than 63 than the right side

    set_y(y_offset-Display_width/2); //Deducts the the half of the display size Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<=((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    } else if(y_offset<=(Display_width/2)-1 && y_offset>=0) {

    lcd_select(0); //selects the left side of the screen

    set_y(y_offset); //Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(y_offset+(x-(charcater_code-Font_offset)*Font_width)!=(Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen(font6x8[x]);

    }else{ //If the Character is belong to the right side

    lcd_select(1); //If yes selects the the right side
    set_y(0); // Resets the offset
    set_x(line_select); //Selects line of writing
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;
    }

    }

    void string_out(char* message, float variable, int line, int y_offset)
    {
    int Maximum_num_char= Display_width/Font_width; //Maximum number of characters what can be placed in one row

    char test[Maximum_num_char],i=0,j;
    char a[Maximum_num_char];
    sprintf(a, "%s%f", message, variable);
    while(a[i]!='\0') {test[i]=a[i]; i++;}
    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);

    }

    Megvan a probléma, igen érdekes Hardvere jellegű, azt gondoltam valami hülyeséget csináltam a karakter kódolással. Nem :DDD

    Ez a jó:

    int strobe_E(void) //Turns enabling line off/on
    {
    DelayUs(10);
    DISPLAY_EN = 1; //Turns Display On
    DelayUs(10);
    DISPLAY_EN = 0; //Turns Display Off
    DelayUs(10);

    }

    és ez a rossz:

    int strobe_E(void) //Turns enabling line off/on
    {
    DelayUs(10);
    DISPLAY_EN = 0; //Turns Display Off
    DelayUs(10);
    DISPLAY_EN = 1; //Turns Display On
    DelayUs(10);

    }

  • #90088192
    törölt tag

    Ez így olvashatatlan. Kérlek vedd ki a hardcodeolt értékeket és használj függvényeket, illetve makrókat _értelmezhető_ névvel.

    Koszonom :R
    Remélem erre gondoltál :)

    Különben igen érdekes maga a probléma, a bal oldali képernyő gyakorlatilag túlcsordul(Módosítottam a kodon így is duplázza az oszlopokat, es elkezd a 0. oszlopba írni)

    Maga a problémás részlet:

    void write_char(int line_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=(Display_width/2) && y_offset<=Display_width-Font_width) //Check which side of the screen need to be activated
    {
    lcd_select(1); //if the offset is bigger than 63 than the right side

    set_y(y_offset-Display_width/2); //Deducts the the half of the display size Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<=((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    } else if(y_offset<=(Display_width/2)-1 && y_offset>=0) {

    lcd_select(0); //selects the left side of the screen

    set_y(y_offset); //Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(y_offset+(x-(charcater_code-Font_offset)*Font_width)!=(Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen(font6x8[x]);

    }else{ //If the Character is belong to the right side

    lcd_select(1); //If yes selects the the right side
    set_y(0); // Resets the offset
    set_x(line_select); //Selects line of writing
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;
    }

    }

    Es az egesz en block

    #include "font6x8.h"
    #include "screen.h"
    #include "membrane.h"

    #define Font_width 6
    #define Font_offset 32
    #define Font_height 8
    #define Display_width 128
    #define Dislpay_height 64
    #define Display_rows 8

    //#define Font_type font6x8

    void InitalizePorts_display(void)
    {
    S_DATA_OUT=0;
    S_DATA_IN=0;
    DISPLAY_Dir=0;
    DISPLAY_CS1=1;
    DISPLAY_CS2=1;
    DISPLAY_RS=1;
    DISPLAY_RW=0;
    DISPLAY_EN=0;

    /* Command port direction settings */

    DISPLAY_CS1_Direction =0 ;
    DISPLAY_CS2_Direction =0 ;
    DISPLAY_RS_Direction =0 ;
    DISPLAY_RW_Direction =0 ;
    DISPLAY_EN_Direction =0 ;

    DelayUs(100);
    }

    void lcd_select(int s)

    {
    if(s==0)
    {
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 0; //Deselects Right side of the screen
    DelayUs(15);
    }else if(s==1)
    {
    DISPLAY_CS1 = 0; //Deselects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    DelayUs(15);
    }else{
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    DelayUs(15);
    }
    }

    void strobe_E(void) //Turns enabling line off/on
    {
    DelayUs(5);
    DISPLAY_EN = 0; //Turns Display Off
    DelayUs(5);
    DISPLAY_EN = 1; //Turns Display On
    DelayUs(5);
    }

    void set_y(int y) //Set Y coordinate 0-63 on the active side of the screen
    {
    DISPLAY_RS = 0; //Sets Instruction mode
    DelayUs(5);
    S_DATA_OUT = (0b01000000+y); //Set Y coordinate
    strobe_E();
    }

    void set_x(int x) //Select one of the 8 bit line out of the 8
    {
    if(x<=Display_rows-1 && x>=0) // Verify input parameter is in range
    {
    DelayUs(5);
    DISPLAY_RS = 0; //Sets Instruction mode
    DelayUs(5);
    S_DATA_OUT = 0b10111000+x; //select the desired line from the 8 X 8bit lines
    strobe_E();
    }else{
    MEMBRANE_MUTE=1;
    }
    }


    void send_data_screen (long int Data) //Sends Data to the Display hardware
    {
    DISPLAY_RS = 1; //Enables Data mode
    DelayUs(5);
    S_DATA_OUT = Data; //Insert Data to the hardware line
    strobe_E();
    }
    void dsp_on(void)
    {
    DISPLAY_RS = 0; //Instruction mode
    DelayUs(2);
    S_DATA_OUT = 0b00111111; //Turns display controller ON
    DelayUs(2);
    DISPLAY_EN = 1; //Turns Enable line ON
    strobe_E();
    }

    void clr_scr (int Fill)

    {
    int x; int y;
    lcd_select(2); //Select both side of the display for quicker action
    for(y=0;y<=Display_rows-1;y++) //Loop for the rows
    {
    set_y(0); //Set y to 0
    set_x(y); //Selects line of writing
    for(x=0; x<(Display_width/2); x++) //Loop for the columns
    {
    send_data_screen(Fill);
    }
    }


    }

    void write_char(int line_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=(Display_width/2) && y_offset<=Display_width-Font_width) //Check which side of the screen need to be activated
    {
    lcd_select(1); //if the offset is bigger than 63 than the right side

    set_y(y_offset-Display_width/2); //Deducts the the half of the display size Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<=((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    } else if(y_offset<=(Display_width/2)-1 && y_offset>=0) {

    lcd_select(0); //selects the left side of the screen

    set_y(y_offset); //Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-Font_offset)*Font_width; x<((charcater_code-Font_offset)*Font_width)+Font_width; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(y_offset+(x-(charcater_code-Font_offset)*Font_width)!=(Display_width/2)) //Checks if the character has reached the border of the 2 sides of the screen
    {
    send_data_screen(font6x8[x]);

    }else{ //If the Character is belong to the right side

    lcd_select(1); //If yes selects the the right side
    set_y(0); // Resets the offset
    set_x(line_select); //Selects line of writing
    send_data_screen(font6x8[x]); //Sends out the relevant section of the Array
    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;
    }

    }

    void string_out(char* message, float variable, int line, int y_offset)
    {
    int Maximum_num_char= Display_width/Font_width; //Maximum number of characters what can be placed in one row

    char test[Maximum_num_char],i=0,j;
    char a[Maximum_num_char];
    sprintf(a, "%s%f", message, variable);
    while(a[i]!='\0') {test[i]=a[i]; i++;}
    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*Font_width,test[j]);

    }

  • #90088192
    törölt tag

    Hello, ha egyre gondolunk akkor :R
    azok nem hard coded értékek hanem fizikai portok.

    Leesett miről beszelsz, maris javítom, elnézést kicsit korán volt :)

    :R

  • #90088192
    törölt tag

    Ez így olvashatatlan. Kérlek vedd ki a hardcodeolt értékeket és használj függvényeket, illetve makrókat _értelmezhető_ névvel.

    Hello, ha egyre gondolunk akkor :R
    azok nem hard coded értékek hanem fizikai portok.

  • #90088192
    törölt tag

    Hello Mindenkinek :DDD

    Lenne itt egy kis fennforgás és segítséget szeretnek kerni hozza, mert nem jutok dűlőre egymagamban.

    A karakter kiíratás amikor elérkezik a határhoz(2X64 képpontból áll a kijelző, amiket külön kell kapcsolgatni, és 8 bit magas a "sor") akkor nem csak térfelet vált hanem nem is tudom mit csinál, kihagyja az első karakter, meg mintha csak egy oszlopnyi szemetet zúdítana a határvonalra :O

    Ez lenne a problémás részlet(a font 6 szeles és 8 magas):

    for(x=(charcater_code-32)*6; x<((charcater_code-32)*6)+7; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(y_offset+(x-(charcater_code-32)*6)<63) //Checks if the character has reached the border of the 2 sides of the screen
    {
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x]; //Sends the data to the screen
    strobe_E();

    }else{ //If the Character is belong to the right side

    lcd_select(1); //If yes selects the the right side
    set_y(0); // Resets the offset
    set_x(line_select);
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x]; //Sends the data to the screen
    strobe_E();

    Ez lenne az egesz:

    #include "font6x8.h"
    #include "screen.h"
    #include "membrane.h"

    void InitalizePorts_display(void)
    {
    S_DATA_OUT=0;
    S_DATA_IN=0;
    DISPLAY_Dir=0;
    DISPLAY_CS1=1;
    DISPLAY_CS2=1;
    DISPLAY_RS=1;
    DISPLAY_RW=0;
    DISPLAY_EN=0;

    /* Command port direction settings */

    DISPLAY_CS1_Direction =0 ;
    DISPLAY_CS2_Direction =0 ;
    DISPLAY_RS_Direction =0 ;
    DISPLAY_RW_Direction =0 ;
    DISPLAY_EN_Direction =0 ;

    DelayUs(100);
    }

    void lcd_select(int s)

    {
    if(s==0)
    {
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 0; //Deselects Right side of the screen
    DelayUs(15);
    }else if(s==1)
    {
    DISPLAY_CS1 = 0; //Deselects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    DelayUs(15);
    }else{
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    DelayUs(15);
    }
    }

    void strobe_E(void) //Turns enabling line off/on
    {
    DelayUs(5);
    DISPLAY_EN = 0; //Turns Display Off
    DelayUs(5);
    DISPLAY_EN = 1; //Turns Display On
    DelayUs(5);
    }

    void set_y(int y) //Set Y coordinate 0-63 on the active side of the screen
    {
    DISPLAY_RS = 0; //Sets Instruction mode
    DelayUs(5);
    S_DATA_OUT = (0b01000000+y); //Set Y coordinate
    strobe_E();
    }

    void set_x(int x) //Select one of the 8 bit line out of the 8
    {
    if(x<=7 && x>=0) // Verify input parameter is in range
    {
    DelayUs(5);
    DISPLAY_RS = 0; //Sets Instruction mode
    DelayUs(5);
    S_DATA_OUT = 0b10111000+x; //select the desired line from the 8 X 8bit lines
    strobe_E();
    }else{
    MEMBRANE_MUTE=1;
    }
    }


    void dsp_on(void)
    {
    DISPLAY_RS = 0; //Instruction mode
    DelayUs(2);
    S_DATA_OUT = 0b00111111; //Turns display controller ON
    DelayUs(2);
    DISPLAY_EN = 1; //Turns Enable line ON
    strobe_E();
    }

    void clr_scr (int Fill_)

    {
    int x; int y;
    lcd_select(2); //Select both side of the display for quicker action
    for(y=0;y<=7;y++)
    {
    set_y(0); //Set y to 0
    set_x(y); //Selects line of writing
    for(x=0; x<64; x++)
    {
    DISPLAY_RS = 1; //Turns Data mode ON
    DelayUs(2);
    S_DATA_OUT = Fill_; //Send data to the selected line
    strobe_E();
    }
    }


    }

    void write_char(int line_select, int y_offset, int charcater_code)

    { int x;
    if(y_offset>=64 && y_offset<=122) //Check which side of the screen need to be activated
    {
    lcd_select(1); //if the offset is bigger than 63 than the right side

    set_y(y_offset-64); //Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-32)*6; x<=((charcater_code-32)*6)+6; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x];
    strobe_E();
    }
    } else if(y_offset<=63 && y_offset>=0) {

    lcd_select(0); //selects the left side of the screen

    set_y(y_offset); //Set y

    set_x(line_select); //Selects line of writing

    for(x=(charcater_code-32)*6; x<((charcater_code-32)*6)+7; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(y_offset+(x-(charcater_code-32)*6)<63) //Checks if the character has reached the border of the 2 sides of the screen
    {
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x]; //Sends the data to the screen
    strobe_E();

    }else{ //If the Character is belong to the right side

    lcd_select(1); //If yes selects the the right side
    set_y(0); // Resets the offset
    set_x(line_select);
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x]; //Sends the data to the screen
    strobe_E();
    }
    }
    }
    else
    {
    MEMBRANE_MUTE=1;
    }

    }

    void string_out(char* message, float variable, char line, char y_offset)
    {
    char test[21],i=0,j;
    char a[21];
    sprintf(a, "%s%f", message, variable);
    while(a[i]!='\0') {test[i]=a[i]; i++;}
    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*6,test[j]);

    }

  • #90088192
    törölt tag

    Mégegyszer is köszönöm a válaszokat. Hosszú és rögös út vár még rám úgy látom :D Főleg mikrovezérlők programozása miatt szeretném megtanulni (amennyire csak képes vagyok rá) a C nyelvet, de ha többre lennék képes a segítségével az sem volna nagy baj :D

    Hello,

    Ha PIC32 is érdekel, akkor az alap hülyeségeken mar túl vagyok vele :K

  • #90088192
    törölt tag

    Dehogy! Ahogy mondani szokták, csak a fel nem tett kérdés a hülye kérdés. Aki válaszol, az segítő szándékkal teszi. Legalábbis remélem.

    & buherton :R

    Köszönöm a segítséget, sikerült átrendeznem az egészet, most mar működik is.
    Persze mindig van mit finomítani, de így mar sokkal egyszerűbb :K
    Aztán majd jönnek az újabb kérdések :DDD

  • #90088192
    törölt tag

    Alapvetően azzal kell tisztában lenni, hogy az #include-okkal beszúrt fájlok az őket beinklúdoló fájlokkal együtt egy fordítási egységet (translation unit TU) képeznek. Az #include egy direktíva, a C előfordítónak szól, és egyszerűen szöveg-szinten beszúrja az inklúdolt fájlt. Tehát olyam, mintha copy-pastéval bemásolnád a fájlt. Ezért az inklúdokban nem lehet körbe hivatkozás (a.h inklúdolja b.h-t, ami inklúdolja a.h-t), és nem lehet többször inklúdolni ugyanazt a fájlt (mert ekkor keletkezik a többszörös defínició). Az utóbbi elkerülésére az ún. include guard megoldást használjuk:
    Pl. egy include file így néz ki:
    #ifndef __include_guard_h //itt a nev include fájlonként különböző és a fáj nevére utal
    #define __include_guard_h
    //ide jön az include file tartalma
    #endif

    Ezzel azt érjük el, hogy egy TU-ban ne lehessen az include fájlt többször beszúrni. Ugyanis először az __include_guard_h makró még nincs definiálva, tehát a fájl tartalma feldolgozásra kerül, miközben a makró definiálttá válik. Következő eseleges beszúráskor a makró már definiálva lesz, de a #ifndef direktíva hamosra lesz kiértékelve, vagyis a feldolgozás az #endif után folytatódik. A körbe hivatkozások ellen az include guard nem véd, arra neked kell odafigyelni.
    C forrás fájlokat tényleg nem szoktunk inklúdolni. Ha több forrás fájlból áll a projected, akkor azokat a project létrehozásakor (project fájlban) kell megadni. Ezek külön-külön fordítási egységet fognak képezni (az általuk beinklúdolt header fájlokkal együtt), amikben már újra inklúdolhatod a másik TU-ban beinklúdolt header fájlt. A külön fordítási egységekben definiált függvények és globális változók egymás közötti elérhetőségét a linkelés (linker) fogja biztosítani.
    Esetenként előfordul (pl. template-ek használatakor), hogy header fájlban függvény definícót írnak, amik a különböző TU-kba való inklúdolások után a linker számára valóban többszörös defínicók lesznek, de ezt a legtöbb linker kezeli. Ettől még kerülendő ez a gyakorlat, ha nagyon kell akkor inline-ként megadható, bár azt a fordító dönti el, hogy valóban inline módon fordítja-e.

    Köszönöm :)

    Remélem, nem akasztok ki senkit a hülyeségeimmel :R

  • #90088192
    törölt tag

    [link]

    Minden .c fájlból fordítódik egy .o fájl. A .o fájlokat fogja a linker összeszerkeszteni, aminek a vége egy bináris, amit te is használni fogsz. A .h fájlok, azért kellenek, mert abban vannak deklarálva a .c/.o szempontjából a külső függőségek, amiket a linker old fel a bináris összeállítása során.

    Példa: A foo.c-hez kell tartoznia egy foo.h-nak, amiben a foo.c kívülről is elérhető makrók, típusok, változók és függvények vannak felsorolva. A main.c-ben elég a foo.h-t includolni, hogy a main.c leforduljon. Majd a linker összerakja a két .o fájlt.

    A fordítást/linkelést az IDE tipikusan megoldja, neked csak a forrás fájlokkal kell bíbelődni.

    Ahaaaaaaaaaaaaaaaaaaaaaa :R

    Így mar értem :R

    Akkor ennek menten neki esek az újra rendezésnek :K

    De majd csak legközelebb.

    KÖSZÖNÖM :R

  • #90088192
    törölt tag

    screen.h
    void delay(unsigned int usec);    
    void lcd_select(int s);
    void strobe_E(void);
    void set_y(int y);
    void dsp_on(void);
    void clr_scr (int t);
    void write_char(int line_select, int y_offset, int c);
    void string_out(char* message, float variable, char line, char y_offset);

    A hardware.h-ban pedig függvény definíciók vannak a deklarációk helyett. Nem illik ilyet csinálni. De ha nagyon muszáj, akkor az inline kulcsszót kell elétenni.

    Kerüld a fölösleges pontosvesszőket. Nem illik ilyet csinálni.

    Ha pedig void a függvény paramétere, akkor írd ki, mert így variadikus lesz.

    A register map-re struktúrát és uniont szoktak ráhúzni és akkor nagyon frankón végigkövetehető, hogy ez melyik regiszter. A macro mágiát érdemes elkerülni.

    Az include pathért legyen a build környezet felelős és ne hardcode-ld bele a kódba.

    Köszönöm megegyszer :R

    Ezzel el leszek egy ideig.

    Akkor maradhatnak .c ben a fuggvenyek, csak a deklaracio kell .h ban.
    Ha ezt megugrottam, akkor jön majd a következő kérdés, elég a relevans .h fájlt include a main.c ben és akkor maris működik?

  • #90088192
    törölt tag

    C fájlt nem illik includolni. Erre való a header fájl, amiben leírod a függvény deklarációkkal, hogy a hozzátartozó C fájl mit is tartalmaz.

    A C-ben nincsenek szubrutinok.

    Köszönöm :)

    Akkor természetesen jönnek az újabb kérdések, ha nem baj

    Akkor a különböző részegységek funkcióit hogyan tudnám szeparálni.
    Vagyis a mostani screen.c bol csináltam screen.h, így működik, de ha újabb .h-t hívok meg amiben egy előzőleg meghívott hardware.h benne van akkor megint ugyan az a probléma.
    Tudom hülye kérdés, ilyen alap struktúra probléma, de fogalmam sincs ezekre hogyan keressek rá.
    Amit el akarok erni: reszegysegenkent kulon fuggveny konyvtar vagy mi a fitty fene.(Nem tudom minek nevezzem)
    Azt hogyan kellene strukturalni?
    :R

    Közben kutakodtam, ezt találtam.

    ez a hardware.h

    #include "stdio.h"
    #include <string.h>
    #include <math.h>
    #include <p32xxxx.h>
    #include <D:\Program Files (x86)\Microchip\xc32\v2.30\pic32mx\include\peripheral\legacy\i2c_legacy.h>


    #define SYS_FREQ 80000000L
    #define FCY SYS_FREQ
    #define F_CPU SYS_FREQ
    #define DLY_COUNT (F_CPU/4000000)
    #define _delay_us( dly ) {unsigned int x=0,y=dly; while(y--){x=DLY_COUNT;while(x--);}}

    // DEVCFG3
    // USERID = No Setting
    #pragma config FSRSSEL = PRIORITY_1 // SRS Select (SRS Priority 1)
    #pragma config FCANIO = OFF // CAN I/O Pin Select (Alternate CAN I/O)
    #pragma config FUSBIDIO = OFF // USB USID Selection (Controlled by Port Function)
    #pragma config FVBUSONIO = OFF // USB VBUS ON Selection (Controlled by Port Function)

    // DEVCFG2
    #pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider)
    #pragma config FPLLMUL = MUL_20 // PLL Multiplier (20x Multiplier)
    #pragma config UPLLIDIV = DIV_2 // USB PLL Input Divider (2x Divider)
    #pragma config UPLLEN = ON // USB PLL Enable (Enabled)
    #pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)

    // DEVCFG1
    #pragma config FNOSC = FRCPLL // Oscillator Selection Bits (Fast RC Osc with PLL)
    #pragma config FSOSCEN = ON // Secondary Oscillator Enable (Enabled)
    #pragma config IESO = ON // Internal/External Switch Over (Enabled)
    #pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)
    #pragma config OSCIOFNC = OFF // CLKO Output Signal Active on the OSCO Pin (Disabled)
    #pragma config FPBDIV = DIV_2 // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/2)
    #pragma config FCKSM = CSDCMD // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
    #pragma config WDTPS = PS1048576 // Watchdog Timer Postscaler (1:1048576)
    #pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))

    // DEVCFG0
    #pragma config DEBUG = OFF // Background Debugger Enable (Debugger is disabled)
    #pragma config ICESEL = ICS_PGx2 // ICE/ICD Comm Channel Select (ICE EMUC2/EMUD2 pins shared with PGC2/PGD2)
    #pragma config PWP = OFF // Program Flash Write Protect (Disable)
    #pragma config BWP = OFF // Boot Flash Write Protect bit (Protection Disabled)
    #pragma config CP = OFF // Code Protect (Protection Disabled)

    //I/O Digital analog selection
    #define Analog_digital AD1PCFG

    //Screen Hardware Setup
    #define DISPLAY_Dir TRISE
    #define S_DATA_OUT LATE
    #define S_DATA_IN PORTE
    #define DISPLAY_CS1 LATGbits.LATG6
    #define DISPLAY_CS2 LATDbits.LATD8
    #define DISPLAY_RS LATGbits.LATG9
    #define DISPLAY_RW LATDbits.LATD7
    #define DISPLAY_EN LATDbits.LATD11
    #define DISPLAY_CS1_Direction TRISGbits.TRISG6
    #define DISPLAY_CS2_Direction TRISDbits.TRISD8
    #define DISPLAY_RS_Direction TRISGbits.TRISG9
    #define DISPLAY_RW_Direction TRISDbits.TRISD7
    #define DISPLAY_EN_Direction TRISDbits.TRISD11

    //Membrane
    #define JTAGEN DDPCONbits.JTAGEN
    #define MEMBRANE_MUTE LATBbits.LATB13
    #define MEMBRANE_MAINS LATBbits.LATB14
    #define MEMBRANE_ALARM LATBbits.LATB15
    #define MEMBRANE_MUTE_Direction TRISBbits.TRISB13
    #define MEMBRANE_MAINS_Direction TRISBbits.TRISB14
    #define MEMBRANE_ALARM_Direction TRISBbits.TRISB15


    //Analog inputs

    #define REF2_5 PORTBbits.RB0
    #define MUX PORTBbits.RB1
    #define BAT1_CURRENT PORTBbits.RB2
    #define BAT2_CURRENT PORTBbits.RB3
    #define CHARGER_CURRENT PORTBbits.RB4
    #define CHARGER_VOLTAGE PORTBbits.RB5
    #define LOAD_VOLTAGE PORTBbits.RB8
    #define BRIDGE_VOLTAGE PORTBbits.RB9
    #define VREQ PORTBbits.RB10
    #define IREQ PORTBbits.RB11

    #define REF2_5_DIRECTION TRISBbits.TRISB0
    #define MUX_DIRECTION TRISBbits.TRISB1
    #define BAT1_CURRENT_DIRECTION TRISBbits.TRISB2
    #define BAT2_CURRENT_DIRECTION TRISBbits.TRISB3
    #define CHARGER_CURRENT_DIRECTION TRISBbits.TRISB4
    #define CHARGER_VOLTAGE_DIRECTION TRISBbits.TRISB5
    #define LOAD_VOLTAGE_DIRECTION TRISBbits.TRISB8
    #define BRIDGE_VOLTAGE_DIRECTION TRISBbits.TRISB9
    #define VREQ_DIRECTION TRISBbits.TRISB10
    #define IREQ_DIRECTION TRISBbits.TRISB11

    void InitalizePorts_membrane()
    {
    JTAGEN=0;
    MEMBRANE_MUTE=1;
    MEMBRANE_MAINS=1;
    MEMBRANE_ALARM=1;
    MEMBRANE_MUTE_Direction =0 ;
    MEMBRANE_MAINS_Direction =0 ;
    MEMBRANE_ALARM_Direction =0 ;

    };

    void InitalizePorts_display()
    {
    S_DATA_OUT=0;
    S_DATA_IN=0;
    DISPLAY_Dir=0;
    DISPLAY_CS1=1;
    DISPLAY_CS2=1;
    DISPLAY_RS=1;
    DISPLAY_RW=0;
    DISPLAY_EN=1;

    /* Command port direction settings */
    DISPLAY_CS1_Direction =0 ;
    DISPLAY_CS2_Direction =0 ;
    DISPLAY_RS_Direction =0 ;
    DISPLAY_RW_Direction =0 ;
    DISPLAY_EN_Direction =0 ;




    };

    void InitalizePorts_ADC()
    {
    Analog_digital= 0x10C0;
    AD1CON2 = 0x0000;
    AD1CON3 = 0x0000; // Configure ADC conversion clock
    AD1CSSL = 0x0000; // No inputs are scanned. Note: Contents of AD1CSSL are ignored when CSCNA = 0
    IFS1CLR = 2; //Clear ADC conversion interrupt
    IEC1SET = 2; //Enable ADC conversion interrupt
    AD1CON1 = 0x00E0; // SSRC bit = 111 internal counter ends sampling and starts converting
    AD1CHS = 0b1111110011110000; // Connect RB2/AN2 as CH0 input in this example RB2/AN2 is the input
    AD1CSSL = 0;
    AD1CON3 = 0x0F00; // Sample time = 15Tad
    AD1CON2 = 0x0004; // Interrupt after every 2 samples

    //Analog PORT directions

    REF2_5_DIRECTION =1;
    MUX_DIRECTION =1;
    BAT1_CURRENT_DIRECTION =1;
    BAT2_CURRENT_DIRECTION =1;
    CHARGER_CURRENT_DIRECTION =1;
    CHARGER_VOLTAGE_DIRECTION =1;
    LOAD_VOLTAGE_DIRECTION =1;
    BRIDGE_VOLTAGE_DIRECTION =1;
    VREQ_DIRECTION =1;
    IREQ_DIRECTION =1;

    };
    void I2C1_Init()
    {
    //***** I2C1 Hardware Init *****/
    //-----Set pin drive modes-----
    //I2C - drive outputs so we can manually clear lines
    LATDbits.LATD9 = 1; //Start with bus in idle mode - both lines high
    LATDbits.LATD10 = 1;
    ODCDbits.ODCD9 = 1; //Open drain mode
    ODCDbits.ODCD10 = 1;
    TRISDbits.TRISD9 = 0; //SCL1 output
    TRISDbits.TRISD10 = 0; //SDA1 output

    /***** I2C1 Module start *****/
    I2C1CON = 0x1000; //Set all bits to known state
    I2C1CONbits.I2CEN = 0; //Disable until everything set up. Pins will be std IO.
    I2C1BRG = 0x00C6; //set up baud rate generator
    I2C1CONbits.DISSLW = 0; //Enable slew rate control for 400kHz operation
    //IFS1bits.MI2C1IF = 0; //Clear I2C master int flag
    I2C1CONbits.I2CEN = 1; //Enable I2C

    } ;

  • #90088192
    törölt tag

    Hello Mindenkinek :)

    Igen kezdő vagyok minden szinten, ezert nagyon alap kérdésem, lenne amit nehéz megfogalmazni, számomra, így nem is egyszerű megtalálni a szagirodalomban.

    MPLAB-ban készítettem egy működő kódot ami egy kijelzőt vezérel, eddig jó, van két .h fajlom az egyik a hardware deklaráció, a másik maga a font.
    Maga a source file screen.c neven futott és tartalmazott egy void main bejegyzést, amit alá írtam az lefutott.

    Amit csinálni szeretnek, létrehozni egy main.c nevű fájlt, és abba meghívni a screen.c ben összedobott szubrutinokat. Ezt így megpróbáltam, és többszörös definícióra hivatkozik folyamatosan.
    Valaki el tudna mondani mit csinálok rosszul? :R

    Maga a main.c

    #include <stdlib.h>
    #include "screen.c"

    /*
    *
    */
    int main()
    {

    unsigned int x;

    InitalizePorts_display();

    //Wait for Vcc to settle
    delay(100);
    // Turn on display
    dsp_on();
    lcd_select(2);
    clr_scr(0x00);


    //*************************************************************************
    // Test
    //*************************************************************************


    for(x=0;x<2000;x++)
    {
    float a=(73.00/5);


    string_out("Spotty:", x ,1,0);
    delay(10000);

    }


    return (EXIT_SUCCESS);
    }

    es ez lenne a kijelző vezérlő

    #include "hardware.h"
    #include "font6x8.h"



    void delay(unsigned int usec)
    {
    _delay_us(usec);
    }

    void lcd_select(int s)
    {
    if(s==0)
    {
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 0; //Deselects Right side of the screen
    delay(10);
    }else if(s==1)
    {
    DISPLAY_CS1 = 0; //Deselects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    delay(10);
    }else{
    DISPLAY_CS1 = 1; //Selects Left side of the screen
    DISPLAY_CS2 = 1; //Selects Right side of the screen
    delay(10);
    }
    }

    void strobe_E(void) //Turns enabling line off/on
    {
    DISPLAY_EN = 0;
    delay(10);
    DISPLAY_EN = 1;
    delay(10);
    }

    void set_y(int y) //Set Y coordinate 0-63 on the active side of the screen
    {
    //Y address
    DISPLAY_RS = 0;
    S_DATA_OUT = (0b01000000+y);
    strobe_E();
    }


    void dsp_on(void)
    {
    DISPLAY_RS = 0; //Instruction mode
    S_DATA_OUT = 0b00111111; //Turns display on
    //DISPLAY_RS = 1; //Data Mode
    delay(10);
    strobe_E();
    }

    void clr_scr (int t)
    {
    int x; int y;
    //line_0();
    DISPLAY_RS = 0;
    S_DATA_OUT = 0b11111111;
    for(y=0b10111111;y>=0b10111000;y--)
    {
    set_y(0);
    DISPLAY_RS = 0;
    S_DATA_OUT = y;
    strobe_E();
    for(x=0; x<64; x++)
    {
    dsp_on();
    DISPLAY_EN = 1;
    DISPLAY_RS = 1;
    S_DATA_OUT = t;
    strobe_E();
    };
    };


    }

    void write_char(int line_select, int y_offset, int c)

    { int x; int t;
    if(y_offset>63 && y_offset<122) //Check which side of the screen need to be activated
    {lcd_select(1); //if the offset is bigger than 63 than the right side

    t=(y_offset-64); //correction of the offset for the right side
    set_y(t);

    DISPLAY_RS = 0;
    S_DATA_OUT = 0b10111000+line_select; //select line
    strobe_E();

    for(x=(c-32)*6; x<((c-32)*6)+6; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x];
    strobe_E();
    }
    }else if(y_offset<64 && y_offset>=0)
    {

    lcd_select(0); //selects the left side of the screen

    t=(y_offset);
    set_y(t);

    DISPLAY_RS = 0;
    delay(10);
    S_DATA_OUT = 0b10111000+line_select;
    strobe_E();

    for(x=(c-32)*6; x<((c-32)*6)+6; x++) //Decodes the character code and make sure the data is sent by 8 bits
    {if(t+(x-(c-32)*6)==63) //checks if the character has reached the border of the 2 sides of the screen
    {lcd_select(1); //If yes selects the the right side
    delay(10);
    DISPLAY_RS = 0;
    S_DATA_OUT = 0b10111000+line_select; // Select the relevant line
    strobe_E();
    set_y(0); // Resets the offset
    delay(2);
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x]; //send out the data what belongs to the right side of the screen
    strobe_E();
    }else{ //If the Character is belong to the left side
    DISPLAY_RS = 1;
    S_DATA_OUT = font6x8[x]; //Sends the data to the screen
    strobe_E();
    }
    }
    }
    else
    {
    lcd_select(2);
    clr_scr(0xff);
    }

    }

    void string_out(char* message, float variable, char line, char y_offset)
    {
    char test[21],i=0,j;
    char a[21];
    sprintf(a, "%s%f", message, variable);
    while(a[i]!='\0') {test[i]=a[i]; i++;}
    for(j=0;j<=i-1;j++) write_char(line,y_offset+j*6,test[j]);

    }

Új hozzászólás Aktív témák