Fórum témák

» Több friss téma
Fórum » PIC kezdőknek
 
Témaindító: Placi84, idő: Okt 3, 2005
Témakörök:
- A PIC ÖSSZES Vdd és Vss (AVdd és AVss) (tápfeszültség) lábát be kell kötni!
- A táplábak mellé a lehető legközelebb 100nF-os KERÁMIA kondenzátorokat kell elhelyezni.
- Az MCLR lábat, 10kohm-mal fel kell húzni a Vdd tápfeszültségre.
- Külső kvarc használatakor 4MHz-ig XT, a fölött pedig HS konfigurációt kell beállítani.
- Stabilizált tápegységet kell használni, a kapcsoló üzemű "telefon töltő" adapterek okozhatnak hibákat.
- Programozáshoz, használj lehetőleg PICKIT2 vagy 3 programozót. Kerülendő a JDM (soros porti) programozó.
- A PIC adatlapja (PDF), tartalmazza a lábak kiosztását és a PIC minden paraméterét. Az adatlap ingyen letölthető!
- Egyes PIC típusoknál az RA4 nyitott nyelőelektródás (Csak lefelé húz L szintre, H szintet nem ad ki!)
- Ha a PGM lábat digitális ki-/bemenetnek használod, az alacsony feszültségű programozási lehetőséget le kell tiltani.
Lapozás: OK   1160 / 1203
(#) Laja1 válasza foxi63 hozzászólására (») Máj 15, 2021 /
 
És akkor a frekvencia már nem is számít?
(#) Bakman válasza Laja1 hozzászólására (») Máj 15, 2021 / 1
 
De, számít. Mikrokontrollernél (is) az órajel frekvenciája az alfája és omegája mindennek.

Számoló: RC Circuit Calculator.
Bővebben: RC Oscillator Circuit.

Jobban járnál, ha ezt a kontrollert leváltanád egy modernebb típusra, aminek van belső órajele. A külső RC oszcillátor nagyon érzékeny, könnyen elmászik a frekvencia. Ha nagyon pontos időzítések kellenek, akkor valamilyen pontos külső órajel vagy kvarc kell.
(#) Laja1 válasza Bakman hozzászólására (») Máj 15, 2021 /
 
Még azt nem értem, ha van ez a parancs __delay_ms, és a programozasnal megadjuk a frekvenciát, akkor abból miért nem számol pontos milliszekundumot. Persze, ha a frekvencia elmaszik, akkor az idő is elmaszik, ez rendben van. De, ha pontos a frekvencia (kvarc), akkor pl. már kisebb frekvencia is jó lehet.
(#) Bakman válasza Laja1 hozzászólására (») Máj 15, 2021 /
 
Azért nem pontos, mert a kontroller ilyen utasítást nem (sem) ismer. Ezt az egy utasítást le kell fordítani a kontroller nyelvére, amit a fordító meg is tesz helyetted. Ez a fordítás vagy jól sikerül, vagy nem de általában az utóbbi. Ennyire időkritikus alkalmazásnál a programot már ASM-ben illik írni, ott nincs tévesztés. Cserébe masszívan több idő egy fejlesztés.

A Timer-es megoldásnál szabályos időközönként ad egy jelzést az időzítő. Innentől kezdve a pontosság az órajel pontosságától és attól függ, hogyan kezeled ezt a jelzést. Általánosságban elmondható, hogy az esetek nagy többségében ez a módszer meg is felel. Van, ahol a delay függvény hazsnálata is bőven jó és marad az időkritikus alkalmazás.
(#) foxi63 válasza Laja1 hozzászólására (») Máj 15, 2021 /
 
Szia!
Gyakorlatilag nem számít a frekvencia.
Bármilyen frekvenciád van, a timer2-vel 0,01 -0,001 sec időnként ami pontos, megszakítást lehet generálni. Ekkor csak egy számlálót kell léptetned, ami ha eléri a 100-at vagy 1000-ret akkor telt el 1 másodperc.
hogy milyen módon oldod meg a 3 sec illetve az 5 sec időzítést már rajtad áll. A pontos frekvencia itt nem is játszik szerepet, hiszen szekundumos időkről beszélünk.
(#) foxi63 válasza Laja1 hozzászólására (») Máj 15, 2021 /
 
Tegyél mellé valamilyen kvarcot és ha megvan a frekvencia akkor segítek a programozásban.
(#) Josi777 válasza K_Imre hozzászólására (») Máj 16, 2021 /
 
Az nem úgy van, hogy a Portot olvassuk és ha kimenet, akkor a Latch-et írjuk?
(#) Zsora válasza Josi777 hozzászólására (») Máj 16, 2021 /
 
Nem egészen.
Írásnál mindegy hogy a POTRx vagy LATx regisztert használjuk, a beírt érték mindig a latch-be kerül. Olvasás-módosítás-írás típusú utasításoknál kell erre figyelni, ha valamelyik kimeneti láb logikai állapotát kívülről valami megváltoztathatja. Ekkor a PORTx használata esetén hibás érték íródhat vissza a LATx regiszterbe. Ezért ajánlott a LATx-regisztert használni kimeneti láb állapotának változtatására. (Már ha van ilyen regiszter az adott mikrovezérlőn.)
(#) Laja1 válasza foxi63 hozzászólására (») Máj 16, 2021 /
 
A segítséget megköszönném, mert a Timer kezelése gondot okoz. Próbáltam már, de nem sikerült. Váltottam egy olyan kontrollerre, amiben van belső órajel: PIC16F627A.
Ez volna a program __delay paranccsal. Ami a Proteus 8 szimulációval jól is működik, de csak 20 Mhz-nél. Ha sokkal alacsonyabb, akkor a másodpercek lassabban telnek. A valóságban pedig minden összevisszaság van. Ki van kommentelve a Timer-es próbálkozásom.
A program (még PIC16F718-ra):
  1. #include <xc.h>
  2. #define _XTAL_FREQ 20000000 //define crystal frequency to 20MHz
  3.  
  4. // CONFIG
  5. #pragma config FOSC = RC     // Oscillator Selection bits (RC oscillator)
  6. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  7. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  8. #pragma config BOREN = OFF       // Brown-out Reset Enable bit (BOR disabled)
  9. #pragma config CP = OFF      // Flash Program Memory Code Protection bit (Code protection off)
  10.  
  11.  
  12. #define gomb RA0
  13. int k=0;
  14. int z=3;
  15. int t;
  16. int n=1;
  17.  
  18.  
  19.  
  20.  
  21. void main() {
  22.     ADCON1 = 0x0F;  //digitális bemenet és nem analóg
  23.     TRISB = 0x00; //Port-B as Output
  24.     TRISA = 0x01; //RA as input
  25.     //T1CON = 0x30;  //Timer beállítás. ki kell számolni 1 sec alatti m?veletek számát: XTAL_FREQ/4/Prescaler= 1 sec alatti m?veletszám
  26.  
  27.     // megszakítások beállítása
  28.     /* PIE1bits.TMR1IE=1;              // Timer1 megszak. engedélyezés
  29.      PIR1bits.TMR1IF=0;              // Timer1 megszakításjelz? törlése
  30.      INTCONbits.PEIE=1;              // periféria megszak. engedélyezés
  31.      INTCONbits.GIE=1;            */   // globális megszak. engedélyezés  
  32.        
  33.        // TMR1H=0x0B;  Feltöltés 16 bit-es timernél a fels? és als? 8 bitet külön adjuk meg. Vagy hexadec vagy rendes számmal.
  34.         //TMR1L=0xDB;  Innen fog indulni egyesével felfelé a számláló és FFFF-nél túlcsordul, akkor indul 0-ról vagy újabb feltöltésnél onnantól
  35.     //TMR1=3035;
  36.            
  37.      
  38.         /*T1CONbits.TMR1ON=0;   //Timer nem indul  
  39.         PIR1bits.TMR1IF=0;  //Nincs túlcsordulva*/
  40.        
  41.        
  42.     while (1)
  43.     {
  44.            
  45.       if (gomb==1)
  46.       {
  47.          
  48.           __delay_ms(300);
  49.      
  50.                  if (gomb==1)
  51.               {__delay_ms(2000);
  52.                  if (gomb==1)
  53.                  { PORTBbits.RB6=1;
  54.                  __delay_ms(1000);
  55.                  PORTBbits.RB6=0;
  56.                  
  57.                   __delay_ms(1000);
  58.                   PORTBbits.RB6=1;
  59.                  // T1CONbits.TMR1ON=1;
  60.                   z=0;
  61.                    while (n)
  62.           {__delay_ms(1000);
  63.           // if (PIR1bits.TMR1IF==1)  //ha túlcsordult
  64.            // { PIR1bits.TMR1IF=0;
  65.                 z=z+1;
  66.            if (gomb==1) {n=0;}
  67.                    }
  68.                
  69.                  
  70.                  // T1CONbits.TMR1ON=0;
  71.                   PORTBbits.RB6=0;
  72.            
  73.          
  74.                  
  75.                  
  76.                  }
  77.                 // n=1;
  78.                  
  79.                  }  
  80.      
  81.                  else
  82.                  {
  83.           PORTBbits.RB3=1;
  84.          // T1CONbits.TMR1ON=1;
  85.           k=0;
  86.          
  87.           while (k<z+2)
  88.           {
  89.               __delay_ms(1000);
  90.            //if (PIR1bits.TMR1IF==1)  //ha túlcsordult
  91.            // { PIR1bits.TMR1IF=0;
  92.        
  93.             k=k+1;
  94.          if (k==1)
  95.          {
  96.           PORTBbits.RB5=1;  
  97.          }
  98.            if (gomb==1)
  99.            {PORTBbits.RB5=0;}
  100.          if (k==z+1)
  101.          {
  102.           PORTBbits.RB5=0;  
  103.          }
  104.          if (k==z+2)
  105.          {
  106.           PORTBbits.RB3=0;  }
  107.          }
  108.          
  109.           //T1CONbits.TMR1ON=0;
  110.          
  111.                  }
  112.          
  113.          
  114.      
  115.       }
  116.       else
  117.       {PORTBbits.RB3=0;
  118.       PORTBbits.RB5=0;
  119.       PORTBbits.RB6=0;}
  120.     }
  121. }


Működés:
A nyomógombra egy relé meghúz, majd 1 sec múlva egy másik is behúz. 3 sec múlva a második elenged és ezután 1 sec múlva az első is elenged.
Ha hosszan nyomjuk a gombot, akkor egy LED felvillan és onnantól számolja a másodperceket, ha ismét megnyomjuk a gombot, akkor leáll. Ezt az időt azért számolja, mert innentől kezdve a második relé már nem 3 sec-ig fog behúzva lenni, hanem eddig a megváltoztatott ideig.
Köszönöm!!
(#) foxi63 válasza Laja1 hozzászólására (») Máj 16, 2021 /
 
Szia én más megközelítéssel gondoltam, nem próbáltam ki a programot, assemblyben programozok, de ezen el tudsz indulni.
  1. #include <xc.h>  
  2. #define _XTAL_FREQ 20000000 ; //define crystal frequency to 20MHz
  3. #define rele1 PORTBbits.RB0
  4. #define rele2 PORTBbits.RB1
  5. #define led   PORTBbits.RB2
  6. #define  gomb  PORTAbits.RA0
  7. /**/
  8. unsigned char t2cnt,flag,keycnt,r1cnt=50,r2cnt=30,time;
  9.  
  10. void  __interrupt() megszak (void)
  11. {
  12.     if(PIR1bits.TMR2IF)
  13.     {
  14.         t2cnt++;
  15.         if(t2cnt==50){t2cnt=0;flag |=1;}// lejárt 0,1 sec frissülhet a főprogi
  16.       PIR1bits.TMR2IF=0;  
  17.     }
  18. };
  19.  
  20.  
  21. void main (void)
  22. {
  23.   PORTB = 0;
  24.   TRISB &= 0xf8;  
  25.   // timer2 beállítása
  26.   PR2=249;                  //timer2 250órajel után ujrakezdi a számolást
  27.   T2CON= 0b01001101 ;       //4 előosztó  modul on 10 utóosztó
  28.   INTCON |= 0xc0;           // golbal és periféria irq on
  29.   PIE1bits.TMR2IE=1;        // tmr2 irq enable
  30.   while(1)
  31.   {
  32.       if(flag)              // 0.1 sec lejárt főprogram frissítése
  33.       {
  34.         flag=0;
  35.         if (gomb && !keycnt)   //ha első megnyomás
  36.         {
  37.             rele1=1; keycnt++;
  38.             r1cnt=time;
  39.             r2cnt=10;           //1sec késleltetés
  40.         }
  41.         if(gomb)     //ha még mindig nyomva
  42.         {
  43.             keycnt++;
  44.             if(keycnt>5){led=1;r1cnt++ ; r2cnt++;}
  45.                     //0.5 secnél led on késleltetés frissítés felfüggesztve
  46.                
  47.         }
  48.         if(!gomb )
  49.         {
  50.             if(keycnt>5) //sokáig nyomva volt
  51.             {
  52.                 time=keycnt; led=0;
  53.                
  54.             }
  55.             keycnt=0;
  56.         }
  57.        //időzítők frissítése  
  58.        if(r1cnt){r1cnt--;if(r1cnt==0)rele1=0;};
  59.        if(r2cnt)
  60.        {
  61.            r2cnt--;
  62.            if(r2cnt==0 && r1cnt>10)
  63.            {
  64.                rele2 =1;r2cnt=r1cnt-10;
  65.            }
  66.            else rele2=0;
  67.                
  68.        }
  69.        
  70.            
  71.        
  72.       }
  73.   }
  74.  
  75. };
(#) foxi63 válasza Laja1 hozzászólására (») Máj 16, 2021 /
 
annyit elrontottam, hogy amíg nyonva van a gomb addig növeli az időt és nem az újbóli megnyomásra, de ez lényegtelen ,hiszen "úgyis ott kell lennie"a páciensnek.
(#) Zsora válasza szucsistvan123 hozzászólására (») Máj 16, 2021 /
 
Kíváncsiságból belekukkantottam a dsPIC33/PIC24 FRM idevonatkozó részébe is (Serial Peripheral Interface (SPI) with Audio Codec Support), de tényleg nagyon alul-dokumentált az SPI működése. Azt látom, hogy a buffer 2x16-bites (SPIxBUFH, SPIxBUFL), viszont a FIFO csak 16-bites, és a mélysége az adathossztól függ (4, 8, vagy 16). Vagyis 32-bites adatnál 2 cella tartalmaz egy adatot, míg 8-bitesnél egy cella 2 adatot. Én arra tippelek hogy a shift regiszter is 16-bites és az adat két részletbe kerül bele. Vagyis 32-bites vagy 24-bites adat esetén először a felső szól kell beírni, mert az átvitel big-endian (Motorola) módon történik.
Sajnos tesztelés nélkül én is csak találgatni tudok.
(Úgy látom hogy ez a doksinak a legelső (A) verziója. Talán majd a következő verziókban pótolják a hiányosságokat.)
A hozzászólás módosítva: Máj 16, 2021
(#) Laja1 válasza foxi63 hozzászólására (») Máj 16, 2021 /
 
Köszönöm szépen. Mivel C-ben sem vagyok profi, hát még ebben... De atragom magam és megpróbálom átültetni C-be. Visszatért a lelkesedésem.
(#) foxi63 válasza Laja1 hozzászólására (») Máj 16, 2021 /
 
Szia! Ez c nyelven van.És hiba nélkül lefordul XC fordítóval.
(#) Laja1 válasza foxi63 hozzászólására (») Máj 16, 2021 /
 
Gyanús is volt, hogy ez C, de Te assemblyt írtál (amit egyáltalán nem ismerek). Félreértettem. Akkor viszont meg kell(ene) értenem . Küzdök vele! Még egyszer köszönöm!
(#) Josi777 válasza Zsora hozzászólására (») Máj 17, 2021 /
 
Ez azért érdekes, amit írsz, mert a Port-ot közvetlenül nem is lehet írni, kizárólag a Latch-en keresztül. Legalábbis az adatlapon szereplő áramköri megvalósítás alapján. Ezért aztán bizonyos esetekben a Port írás hibás működéshez vezet, amit sikerült is kipróbálnom. Valamint a Chipcad-nél a szakember nyomatékosította, hogy írni kizárólag csak a Latch-ez szabad, Portot semmi esetre sem. De ezek szerint rosszul tudják
(#) Zsora válasza Josi777 hozzászólására (») Máj 17, 2021 /
 
Lehet. Vagy csak rosszul értelmezted a szavait.
Eleve bizonyos PIC típusokban nincs is LATx regiszter, tehát ott csak a PORTx regisztert tudod írni/olvasni. Ahol van, ott a következő szabály él: Írásnál - akár a PORTx, akár a LATx a cél - mindig a LATx-be kerül az adat. Olvasáskor viszont külön olvasható a PORTx és a LATx is. A működés egyértelműen kiolvasható a portok leírásában szereplő vázlatrajzból. (Van külön RD LAT és RD PORT jel, de a WR közös.)
A hozzászólás módosítva: Máj 17, 2021
(#) benjami válasza Josi777 hozzászólására (») Máj 17, 2021 /
 
Az esetlegesen hibás működés oka röviden:
Egy kimeneti láb állapotának megváltoztatásakor a rajta levő terheléstől függően (főleg ha ez a terhelés kapacitív jellegű) idő szükséges ahhoz, hogy a láb állapota ténylegesen megváltozzon.
Ha ilyenkor az átváltási időn belül a PORT 8 bitjét beolvasod nem az utoljára kiírt, hanem még az azt megelőző állapotot olvasod vissza. Ezután a hibásan visszaolvasott értéken megváltoztatsz egy bitet, amit újra kiírsz a PORT-ra. Ekkor hibásan visszaolvasott láb véglegesen a hibás állapotában marad.
Na mármost: mivel a bsf és a bcf utasítás is ezt a tevékenységsorozatot fogja végrehajtani, a PORT bitjeinek egymást követő állítgatása során képes lesz ugyanezt a hibát elkövetni. Ha létezik LAT regiszter, ezért javasolt azt írni, mert a LAT esetén nem jelentkezik a beleírt adat késleltetett megjelenése visszaolvasáskor.
(#) icserny válasza Josi777 hozzászólására (») Máj 18, 2021 /
 
Írásnál a PORTx címet vagy a LATx címet használva ugyanazt az adatkimeneti regisztert írjuk (tehát mindegy, hogy melyik címet használjuk).

Olvasásnál a LATx címet használva az adatkimeneti regiszter állapotát olvassuk vissza, a PORTx címet használva pedig a portkivezetések állapotát olvassuk - ez utóbbi értékét a rákapcsolt külső áramkör vagy áramköri elemek befolyásolják. Itt, a LATx és PORTx címzésnél nyilvánvalóan két különböző dologról van szó, de könnyen el tudjuk dönteni, hogy melyik adatra vagyunk kíváncsiak.

A bonyodalom a read-modify-write típusú utasításoknál kezdődik, amelyeket csak úgy tudja végrehajtani a mikrovezérlő, hogy először beolvassa a regiszter tartalmát, azután elvégzi a kívánt módosításokat (pl. bit beállítás, vagy bit törlés), végül visszaírja az adatot a regiszterbe. Itt fontos, hogy a LATx regiszter címet használjuk, mert ha az adatkimeneti regiszter tartalmát és a PORTx bemenetek állapotát kombináljuk egy meggondolatlan PORTx címzés használatával, akkor kellemetlen meglepetések érhetnek.

Bővebben lásd itt (a 3. és 5. ábra, illetve a a kapcsolódó szöveg).
(#) Hp41C válasza icserny hozzászólására (») Máj 18, 2021 /
 
Még egy lehetőség van, de az már mély víz...
Egy port lábat analóg módba állítunk, de a TRIS regiszterrel engedélyezzük a digitális meghajtóját. Ekkor a lábon a LAT regiszterbe utoljára beírt adatnak megfelelő szint áll be, az jut el - többek között - az A/D bemenetválasztójára, azt a szintet méri az A/D, ha a megfelelő csatornán kezdeményezünk átalakítást. Ha a PORT regisztert olvassuk vissza, az adott lábnál 0 értéket olvasunk. Ha a LAT regiszterből olvasunk, akkor is számos típuson 0 értéket kapunk mindig. Ebben az esetben a LAT regiszterrel végzett RWM művelet is hibás eredményt ad.
A megoldás a LAT regiszterről egy kópiát tarunk a GPR memóriában, minden műveletet a kópián végzünk és az eredményt csak másoljuk (movwf, movff).
(#) Zsora válasza szucsistvan123 hozzászólására (») Máj 18, 2021 /
 
Sikerült alaposabban elolvastam a dsPIC33/PIC24 Family Reference Manual idevonatkozó Serial Peripheral Interface (SPI) with Audio Codec Support részét.
Nekem úgy tűnik hogy ebbe a mikrovezérlőbe több PIC32-höz fejlesztett perifériát építettek, erre utalnak a 32-bites regiszterek, amik a PIC24 számára két részben érhetők el. (pl.: SPIxBUFL és SPIxBUFH)

A 21. oldalon azt írják, hogy ha az adathossz 16 bitnél nagyobb, akkor először mindig az SPIxBUFL regisztert írjuk (vagy olvassuk), majd csak azután az SPIxBUFH-t.
A 15. oldalon leírtak szerint 24-bites adatnál az SPIxBUFH regiszter DATA<23:16> bitjei használatosak. (normál módban)
(#) Josi777 válasza icserny hozzászólására (») Máj 18, 2021 /
 
Akkor leírom röviden a történetet:
Írtam egy asm programot 18F1330-as procira, majd később néhány újabb funkcióval kellett bővíteni. A módosítás után nem működött, egyszerűen a kimenetek nem funkcionáltak. Mindvégig a PORT-ot írtam. Mivel nagy szükség volt a programra, ezért, mivel régi jó kapcsolatban vagyok a magyarországi disztribúcióval, a CHIPCAD-el, ezért tőlük kértem segítséget, azaz besétáltam hozzájuk a laptopommal, a Pickit3-asommal és a panellal, hogy segítsenek, mert az új kód sehogyan sem működik. Baromi rendes volt a srác, mivel sajnos régi laptopról van szó, elég lassan ment fel rá a legújabb Mplab, de végigvárta. Majd betöltötte a programomat és az áttanulmányozása után csak ennyit mondott nyomatékosan: Portot soha sem írunk, csak a Latch-et, amit ott helyben meg is tett, azaz kicserélte a kimeneteknél a két utasítást és csodák csodájára, azonnal megjavult (amúgy rácsodálkozott az ajánlottnál sokkal hosszabb szalagkábelre is, amit használok az on board programozáskor, de az nem okozott problémát). Tehát innen az ismeret és a tapasztalat, ami szerint egyáltalán nem mindegy, hogy Portot vagy Latchet írunk. Én személy szerint azóta is minden esetben kizárólag Latchet írok.
(Azt hiszem, nem kell hozzátenni, hogy ahol van, mert az ugye triviális!)
(#) pipi válasza Josi777 hozzászólására (») Máj 18, 2021 / 2
 
Sokkal egyszerűbb örökre megtanulni hogy MINDIG a LATCH-ot írjuk, mint a kivételeket megtanulni mikor lehet a PORT-ot büntelenül és mikor KELL a LATCH-ot
Amúgy ez a read-modify-write is meg tud szivatni (engem már megtett) ha két egymás utáni utasítással van bitmódosítás a ugyanazon a porton, akkor az első bitmódosítás elveszik... Ez ugye az átlapolt utasításvégrehajtás miatt van, az első utasítás "teljes" végrehajtása előtt már olvassa a második bitművelet a portot, amin még az elsőt megelőző állapot van... szóval ilyenkor kell egy NOP a két (ugyanazon) porton történő bitművelet közé
(#) Zsora válasza pipi hozzászólására (») Máj 19, 2021 /
 
Az írás és olvasás ugyanabban az utasításciklusban történik, valamint két egymást követő utasítás végrehajtása nincs átfedésben. Az előző utasítás végrehajtása, ill. a következő beolvasása és dekódolása történik egyszerre. Az egymást követő két bitmódosító utasítás - ami ugyanazt a PORT regisztert használja - a következőt okozza:
A hozzászólás módosítva: Máj 19, 2021

IO.png
    
(#) pipi válasza Zsora hozzászólására (») Máj 19, 2021 / 1
 
Pont ezt mondtam, ami a képen le van írva, két egymást követő bitpiszkálás esetén az első elveszik - 4 es pontban oda van írva... a második utasitás hamarabb olvassa port állapotát, mint ahogy az első utasítás beállítja, minek hívjuk, legyen overlap
section 4.3oldal
Oké "szó szerint" nem a 2 utasítás végrehajtása van átfedésben... hanem a 2 utasítás az eléjétől a végéig nézve középen átfedésben van ))
A hozzászólás módosítva: Máj 19, 2021
(#) Zsora válasza pipi hozzászólására (») Máj 19, 2021 /
 
Lehet hogy jóra gondoltál, csak nem jót írtál. Ennek a dolognak nem az utasítás-végrehajtási sorrendhez van köze, hanem ahhoz hogy egy láb nagy kapacitív terhelése miatt a kimeneti feszültség viszonylag lassan fut fel (vagy le), ezért az olvasással addig várni kell, amíg a feszültség el nem éri a logikai szintnek megfelelő értéket.
(#) Laja1 hozzászólása Máj 20, 2021 /
 
Sziasztok!
Az alábbi programot írtam meg, szépen lefordult. PIC16F627A használok. A programot beégettem, és próbapanelon annyit csináltam, hogy adtam neki 4,71 V-t (3 db ceruzaelemről), bekötöttem a VSS-t. VSS és VDD közé tettem még kondit is. +-ra kötöttem egy ellenálláson át az MCLR-t. A nyomógombot a + és az RA0 közé kötöttem és ezt a bemenetet lehúztam a földre egy ellenállással. Csak ennyit kötöttem be és mértem a kimenetek feszültségét, de semmi.
Az égetés előtt az égető ( UPP628) programjában bejelöltem az IntOsc I/O-t; a conf. Words-nél semmit sem pipáltam ki (azaz OFF minden): WDTE, PWRTE, BOREN, LVP, CPO, CP. Kivéve a MCLRE, ezt kipipáltam (ez ON).
Van ötletetek, hogy miért nem csinál semmit? Talán a belső óra miatt még valamelyik lábára kellene +5V? Vagy valamit a fentiekből még ki kellene pipálni?
Itt a program:
  1. #include <xc.h>
  2.     #define _XTAL_FREQ 4000000 ; //define crystal frequency to 20MHz
  3.     #pragma config FOSC = 100     // Oscillator Selection bits (RC oscillator)
  4. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  5. #pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
  6. #pragma config BOREN = OFF       // Brown-out Reset Enable bit (BOR disabled)
  7. #pragma config CP = OFF      // Flash Program Memory Code Protection bit (Code protection off)
  8. #pragma config MCLRE = ON
  9. #pragma config LVP = OFF  
  10.  
  11.     #define rele1 PORTBbits.RB0
  12.     #define rele2 PORTBbits.RB1
  13.     #define led   PORTBbits.RB2
  14.     #define  gomb  PORTAbits.RA0
  15.     #define  max 100
  16.  
  17.     /**/
  18.     unsigned char t2cnt,flag,keycnt,r1cnt=50,r2cnt=30,time=50, s, ki;
  19.      
  20.     void  __interrupt() megszak (void)
  21.     {
  22.         if(PIR1bits.TMR2IF)
  23.         {
  24.             t2cnt++;
  25.             if(t2cnt==10){t2cnt=0;flag |=1;}// lejárt 0,1 sec frissülhet a f?progi
  26.           PIR1bits.TMR2IF=0;
  27.         }
  28.     };
  29.    
  30.      
  31.     void main (void)
  32.     {
  33.         PCONbits.OSCF=1;
  34.       PORTB = 0;
  35.       TRISB &= 0xf8;
  36.       // timer2 beállítása
  37.       PR2=249;                  //timer2 250órajel után ujrakezdi a számolást
  38.       T2CON= 0b01001101 ;       //4 el?osztó  modul on 10 utóosztó
  39.       INTCON |= 0xc0;           // golbal és periféria irq on
  40.       PIE1bits.TMR2IE=1;        // tmr2 irq enable
  41.       while(1)
  42.       {
  43.          
  44.           if(flag)              // 0.1 sec lejárt f?program frissítése
  45.           {
  46.             flag=0;
  47.             if (gomb && !keycnt)   //ha els? megnyomás
  48.             {
  49.                
  50.                 r1cnt=time;
  51.                 r2cnt=10;           //1sec késleltetés
  52.                
  53.             }
  54.             if (!gomb && keycnt) {rele1=1;}
  55.             if(gomb)     //ha még mindig nyomva
  56.             {
  57.                 keycnt++;
  58.                 if(keycnt>5){led=1; rele1=0; r1cnt++ ; r2cnt++;}
  59.                         //0.5 secnél led on késleltetés frissítés felfüggesztve
  60.                    
  61.               if (keycnt > max)
  62.               {keycnt=max;
  63.               led=0; }
  64.                  
  65.             }
  66.              
  67.                
  68.             if(!gomb )
  69.             {
  70.                
  71.                 if(keycnt>5) //sokáig nyomva volt
  72.                 {
  73.                    
  74.                     r1cnt=keycnt+20;
  75.                     time=r1cnt;
  76.                     led=0;
  77.                  
  78.                 }
  79.                
  80.                 keycnt=0;
  81.             }
  82.            
  83.          
  84.            
  85.            if(r1cnt){ r1cnt--;if(r1cnt==0)rele1=0;};
  86.            
  87.            if(r2cnt)
  88.            {  
  89.                r2cnt--;
  90.                if(r2cnt==0 && r1cnt>9)
  91.                {
  92.                    rele2 =1;
  93.                  
  94.                    r2cnt=r1cnt-10;
  95.                }
  96.            
  97.                if(r2cnt==0){
  98.                rele2=0; }
  99.                    
  100.            }
  101.          
  102.          
  103.          
  104.            
  105.          
  106.                
  107.             }  
  108.          
  109.          
  110.       }
  111.      
  112.     };

Előre is köszönöm a segítséged!
(#) pipi válasza Laja1 hozzászólására (») Máj 20, 2021 /
 
Nem rágtam át magam rajta...
Ami változót használsz irq-ban annak illik volatile-nek is lenni, de biztos nem ennyi nyűgje van...
Tegyél még rá ledeket amit a program különböző helyein kapcsolgatsz, így látd merre kóvályog
(#) Laja1 válasza pipi hozzászólására (») Máj 20, 2021 /
 
Proteus szimuláció szerint jól működik. Mit jelent az irq és a volatile?
(#) pipi válasza Laja1 hozzászólására (») Máj 20, 2021 /
 
irq: interrupt rutinban...
Bővebben: Link
Utasítja a fordítót, hogy azt a változót ne optimalizálja. AZ értelme hogy pl egymás utáni módosítása/felhasználása ugyanannak a változónak ha processzoron belül pl. regiszterben megtörténik, de közben van egy interrupt, ami megmódosítja a memóriában a változót, akkor az nem jut érvényre...
Következő: »»   1160 / 1203
Bejelentkezés

Belépés

Hirdetés
Lapoda.hu     XDT.hu     HEStore.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