Fórum témák

» Több friss téma
Fórum » PIC programozása C nyelven, C-Compiler
Lapozás: OK   104 / 153
(#) Hp41C válasza Wudoou hozzászólására (») Aug 16, 2014 /
 
Körmére kell nézni mindkét fordítónak. Nézegesd a disassembly listát. Sok képtelenséget fogsz találni bennük.
(#) watt válasza Poostmaster hozzászólására (») Aug 16, 2014 /
 
Minden fordítóhoz szokott telepedni doksi is (a C18-hoz az MPLAB-C18-Getting-Started.pdf), keresgélj az xc8 mappában.
(#) Poostmaster hozzászólása Aug 16, 2014 /
 
Próbáltam egy egyszerű két porton át lépegető ledsort programozni.
itt a forrás:
  1. /*
  2.  
  3. #include <pic16f887.h>
  4.  
  5. #define _output 0x00
  6. #define _input  0xFF
  7.  
  8. // CONFIG1
  9. #pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
  10. #pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
  11. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  12. #pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
  13. #pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
  14. #pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
  15. #pragma config BOREN = ON       // Brown Out Reset Selection bits (BOR enabled)
  16. #pragma config IESO = ON        // Internal External Switchover bit (Internal/External Switchover mode is enabled)
  17. #pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
  18. #pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
  19.  
  20. // CONFIG2
  21. #pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
  22. #pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)
  23.  
  24. /*
  25.  *
  26.  */
  27. void pihen(void){
  28.     for (int ido = 0; ido < 30000; ido++){
  29.     }
  30. }
  31. main(void) {
  32.     TRISA = _output;
  33.     TRISB = _output;
  34.     PORTB = 0;
  35.     PORTA = 0;
  36.     unsigned char _aport = 1;
  37.     for (int a = 1; a < 7; a++){
  38.         PORTA = _aport;
  39.         _aport = _aport << 1;
  40.         pihen();
  41.     };
  42.     unsigned char _bport = 1;
  43.     for (int a = 0; a < 8; a++){
  44.         PORTB = _bport;
  45.         _bport = _bport << 1;
  46.         pihen();
  47.     };
  48. }


A szimulátorban végiglépked a porton, de beégetve csak az APORT első 4 ledjét kapcsolja, és utána vissza az elejére.
Mi lehet a baj?
(#) pipi válasza Poostmaster hozzászólására (») Aug 16, 2014 /
 
Hali!
Ha jól emlékszem a dokuban a portok leírásánál van minta...
A tris az kevés, az analóg cuccokat ki kell kapcsolni
(#) Poostmaster válasza pipi hozzászólására (») Aug 17, 2014 /
 
Kifejtenéd bővebben?
Milyen dokuban, milyen analog cuccokat?
(#) Poostmaster válasza pipi hozzászólására (») Aug 17, 2014 /
 
Ja, gondolom az ANSEL regiszterekre gondolsz.
Ez eszembe sem jutott, mert ha a portra '11111111'-et küldök, mind világít.
De ez még nem magyarázza meg, miért nem fut tovább a program.
(#) potyo válasza Poostmaster hozzászólására (») Aug 17, 2014 /
 
Pl. nem reseteled a watchdogot.

Jobb azt úgy megszokni, hogy ha digitális működést akarsz, akkor kikapcsolod az analóg dolgokat. Még digitális kimenetnél is.
(#) pipi válasza Poostmaster hozzászólására (») Aug 17, 2014 /
 
Meg a komparátort is ki kell kapcsolni, ha van.
Mihez képest nem fut "tovább"?
A programnak igy nem illik végének lenni, valahol csinálj végtelen ciklust, amit ismételni kell.
_output változónak hol adsz értéket?
(#) Poostmaster válasza pipi hozzászólására (») Aug 22, 2014 /
 
Ahhoz képest nem fut tovább, hogy a B porton is kellene végiglépkednie. Ehelyett az A feléig megy, és újrakezdi.
A változó a deklarácónál kap értéket.
(#) Poostmaster válasza (Felhasználó 15355) hozzászólására (») Aug 23, 2014 /
 
No most tudtam vele foglalkozni. Átállítottam mindent. most jó.
Köszi mindenkinek.

Ám a másik kérdés még áll:
Hol tudom megnézni az implementált eljárásokat?
A delay(1000) pl nem működik.

csiga_main.c:55: warning: (1464) number of arguments passed to function "_delay" does not match function's prototype

ezt mondja.
A hozzászólás módosítva: Aug 23, 2014
(#) watt válasza Poostmaster hozzászólására (») Aug 23, 2014 / 1
 
Írtam már, hogy az XC8 könyvtárában. Nálam ide telepedett: E:\xc8\v1.32\docs\MPLAB_XC8_C_Compiler_User_Guide.pdf (és a többi doksi is itt van).
A 330. oldalon van a __delay...
A programodba ne a PIC típusának megfelelő h-t include-old, hanem az xc.h-t!
  1. #include <xc.h>

Másra nincs szükség.

Ha a doksi szerint helyesen beírt delay-okat pirossal aláhúzná, az az MPLAB X hibája, a kód jó, csak hibásan jelzi hibának.
A delay deklarációkat itt találod: :\xc8\v1.32\include\plib\delays.h és itt :\xc8\v1.32\include\pic.h
(Használd a TotalCommander kereső funkcióját szöveg keresési beállítással, tallózz bele az xc8 könvtárba és keress bármire, ami érdekel...)
(#) Poostmaster válasza watt hozzászólására (») Aug 24, 2014 /
 
Köszönöm, azt megtaláltam, csak nem akart működni.
Gyenge angolommal kibogarásztam, hogy kell neki az _XTAL_FREQ érték megadása.
Most csak azt nem tudom, hogy a belső oszcillátor mennyivel megy a 887-ben. Az adatlapján 8 MHz - 31 kHz van, akkor gondolom alapból 8 mega, ha nem állítok semmit.
(#) Poostmaster válasza (Felhasználó 15355) hozzászólására (») Aug 24, 2014 /
 
Köszi. Megvan.
(#) lóri hozzászólása Aug 25, 2014 /
 
Sziasztok!
Szeretném kérdezni, hogy van-e valami leírás kezdőknek c-ről? Lehet, hogy már kérdezték.
Olyanra gondolok, mint ez:Pl. Ennek megvan valakinek a többi része?
L.
(#) kissi válasza lóri hozzászólására (») Aug 25, 2014 /
 
Szia!

Itt árulják :Bővebben: Link !
(#) lóri válasza kissi hozzászólására (») Aug 25, 2014 /
 
Köszi, nem tudtam, hogy abból való, azt gondoltam, valami jegyzet.
(#) lóri válasza lóri hozzászólására (») Aug 25, 2014 /
 
Közben találtam Vicsys, és Lidi-Slogan féle leírásokat. Jók, már kezdtem beleélni magam, de a Slogan-osat le akartam fordítani, és feljött egy regisztrációs ablak a ccs részéről. Mplabx -be is beraktam, ott meg a _delay_ms (100)-al van baja. Most akkor mit használjak, és melyik fordítónak olvasgassam a leírását? Nálam már keveredés van. Egy 18f1330-athasználok, egy gomb, és 3 led van rajta.
(#) Hacsi hozzászólása Aug 25, 2014 /
 
Szia !

Próbáld meg a CCS-C (5.025)-t MPLAB alatt. Nekem évek óta hibátlan ez a páros.
Jó benne a help is.
(#) watt válasza lóri hozzászólására (») Aug 26, 2014 /
 
Az MPLAB X a delay-t pirossal aláhúzza, de jól fordítja! Próbáld ki szimulációval!
(#) lóri válasza watt hozzászólására (») Aug 26, 2014 /
 
Köszönöm mindenkinek, majd még vergődöm. A munkahelyen kell ezzel foglalkozni, és délutános vagyok. Mikroc 6.0.0-át és ccs 5.011-et sikerült szerezni.
(#) Poostmaster válasza lóri hozzászólására (») Aug 27, 2014 /
 
Az Mplabx-ben a __delay_ms() használatos. Az elején két aláhúzással.
(#) lóri válasza Poostmaster hozzászólására (») Aug 27, 2014 /
 
Köszönöm, azt tudom. Most már villognak a led-ek, de nem az én érdemem. Megszakításos időzítőt csináltak nekem.
(#) Poostmaster hozzászólása Szept 1, 2014 /
 
Nekem másféle gondom van az említett eljárással.

Készítettem egy kis rutint, amiben meghívásra kerül a __delay_ms(), és paraméterként átadnám neki a várakozás értékét.
Sajnos a fordító nem fogadja el.
Itt a kódrészlet:
  1. void _KepKiiras(int iEttol, int iEddig, unsigned int iVarakozik){
  2.     for (int x = iEttol; x < iEddig; x++){
  3.         PORTA = kepA[x];
  4.         PORTB = kepB[x];
  5.         PORTC = kepC[x];
  6.         PORTD = kepD[x];
  7.         __delay_ms(iVarakozik);
  8.     };
  9. };


És kapom a hibaüzenetet:
main.c:103: error: (1387) inline delay argument must be constant
(#) icserny válasza Poostmaster hozzászólására (») Szept 1, 2014 / 1
 
Ezek szerint a __delay_ms() inline függvény csak konstans értékkel hívható (a fordításkor már tudni kell az értékét).

Menet közben úgy lehet variálni, hogy írsz egy saját függvényt, amiben egy for ciklusban hívogatod az időegységnek tekintett inline függvényt (például: _delay_ms(1); vagy __delay_ms(10); ).
(#) Poostmaster válasza icserny hozzászólására (») Szept 1, 2014 /
 
Ez nekem is eszembe juthatott volna.
Csak azt hittem, én rontottam el valamit. Kösz.
Így jó is:
  1. void _KepKiiras(int iEttol, int iEddig, unsigned int iVarakozik){
  2.  
  3.     for (int x = iEttol; x < iEddig; x++){
  4.         PORTA = kepA[x];
  5.         PORTB = kepB[x];
  6.         PORTC = kepC[x];
  7.         PORTD = kepD[x];
  8.         for (unsigned int y = 0; y < iVarakozik; y++){
  9.         __delay_ms(1);
  10.         };
  11.     };
  12. };
(#) Birs Alma hozzászólása Szept 12, 2014 /
 
Sziasztok,

Valami ilyesmit hogy lehet csinálni? (XC8)
Egy változóval szeretnék a megfeleő bitre hivatkozni.
Sajnos ez így nem jó. A XXXXXbits.változó nem működik.


  1. void LCDPutChr( unsigned char d )
  2. {
  3.     unsigned char i;
  4.     for (i = 7; i >= 4; i--)        
  5.     {
  6.         if (d.7 == 1)
  7.             LCD_DATAPbits.i = 1;   // Az i változóval hivatkoznék a megfelelő bitre, de így nem jó
  8.         else
  9.             LCD_DATAPbits.i = 0;   // Az i változóval hivatkoznék a megfelelő bitre, de így nem jó
  10.         <=d ;
  11.     }
(#) potyo válasza Birs Alma hozzászólására (») Szept 12, 2014 /
 
  1. const unsigned char mask[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
  2.  
  3. void LCDPutChr( unsigned char d )
  4. {
  5.     unsigned char i;
  6.     for (i = 7; i >= 4; i--)      
  7.     {
  8.                 if (d&mask[7])  /* nem vagyok benne biztos, hogy a d.7 az jó, ez így biztos jó */
  9.                         LCD_DATAPbits |= mask[i];       /* egyesbe állítjuk az i-edik bitet */
  10.         else
  11.                         LCD_DATAPbits &= ~mask[i];      /* nullázzuk az i-edik bitet */
  12.         <=d ;   /* ez meg nem tudom, mi akar lenni */
  13.     }
  14. }
  15.  
  16. -------------------------------
  17.  
  18. void LCDPutChr( unsigned char d )
  19. {
  20.     unsigned char i;
  21.     for (i = 7; i >= 4; i--)      
  22.     {
  23.                 if (d&(1<<7))   /* nem vagyok benne biztos, hogy a d.7 az jó, ez így biztos jó */
  24.                         LCD_DATAPbits |= (1<<i);        /* egyesbe állítjuk az i-edik bitet */
  25.         else
  26.                         LCD_DATAPbits &= ~(1<<i);       /* nullázzuk az i-edik bitet */
  27.         <=d ;   /* ez meg nem tudom, mi akar lenni */
  28.     }
  29. }


Alapvetően ez a két verzió jut eszembe. Előbbi átlagban valamivel gyorsabb, utóbbi meg néhány utasítással kevesebb helyet foglal.

Az XXXXXbits az csak az SFR regiszterekre van megcsinálva, nézz szét a fordító header fájljaiban, hogy pontosan hogyan is. Azok egyszerű bitmezők, bepozícionálva a hozzájuk tartozó regiszter címére. Valószínűleg saját változókra is megoldható a létrehozásuk, de nem láttam még sosem szükségét. Ha szükségem lenne ilyenre, akkor valószínűleg létrehoznám a bitmezőt, mint típust, és castolnám más típusra, ahol arra épp szükség van.
A hozzászólás módosítva: Szept 12, 2014
(#) Hp41C válasza potyo hozzászólására (») Szept 12, 2014 /
 
Mivel csak 4 bitről van szó (d 7..4 bitjeiről), egyszerűbb egy 16 elemű táblázatot csinálni a ROM területen és abból az összekevert bitmintát egyben elővenni.
Legyen pl. az LCD bitkiosztása: D7 - Rx0, D6 - Rx1, D5 - Rx2, D4 - Rx3 (csak azért, hogy jól össze legyen keverve)


  1. const unsigned char LCD_Conv[16] = {0x00,0x08,0x04,0x0C,0x02,0x0A,0x06,0x0E,0x01,0x09,0x05,0x0D,0x03,0x0B,0x07,0x0F,};


Használata:
  1. LCD_DATA = LCD_Conv[d >> 4];
(#) AZoli hozzászólása Szept 14, 2014 /
 
Sziasztok!
Órákat szenvedtem mire megtaláltam hogy miért csak bizonyos helyere tudok írni programmemóriában.
Volt egy ilyen sorom, amiben ha WhitchMap 0 vagy 1 akkor ProgMemoryAddress helyesen 0x40000 vagy 0x44000 lesz, viszont ha WhitchMap = 2 akkor 0x48000 helyett 0x38000 .
  1. int WhitchMap = 0;
  2. unsigned long ProgMemoryAddress = 0x40000 + (0x4000 * WhitchMap);

WhitchMap -ot long-á téve viszont jó 2-vel is! Miért szivat? Egy int-et szoroznia kéne egy int -el, majd egy long- hoz hozzáadni.. mi nem megy ezen az XC16-nak?
  1. unsigned long ProgMemoryAddress = 0x40000 + (0x4000 * (long)WhitchMap);

Mert ha szerinte a 0x40000 nem long, akkor int-ként végezné az összes műveletet, de akkor ProgMemoryAddress nem lehetne 0xFFFF -nél nagyobb.
(#) AZoli válasza AZoli hozzászólására (») Szept 14, 2014 /
 
Azt hiszem értem...
WhitchMap mivel előjeles, (int) ezért a szorzást is előjelesként végzi, és a 0x8000 eredmény így már negatív szám.
Következő: »»   104 / 153
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