Fórum témák

» Több friss téma
Cikkek » PIC-es motorvezérlés
PIC-es motorvezérlés
Szerző: Ideiglenes, idő: Jan 19, 2011, Olvasva: 46169, Oldal olvasási idő: kb. 3 perc
Lapozás: OK   3 / 4

A PICkit demo panelja elég nagy lehetőségeket ad a vezetékek kötözgetéséhez. Én úgy döntöttem, hogy az illesztőpanel vezérlőpontjait a pic "C" PORT 0 illetve 1 lábaira kötöm, a végállás kapcsolót pedig az "B" PORT 4-es lábra és a GND-re, nem elfeljetve az 1 k ohm -os felhúzó ellenállást, ami szintén a "B" PORT 4-es lábához kapcsolódik, valamint az +5V-ra. A rendszer megtáplálásáról a PICkit2 gondoskodik.

        

A kimenetek állapotáról a demo panelen található LED-ek adnak majd némi infomációt illetve a végállás kapcsoló jelzése is ide lett másolva a 4. LED-re.

A vezérlőprogram se lett agyonbonyolítva, de azért a megoldás megérdemel némi magyarázatot. Először is fontos tudni, hogy a program C nyelven íródott és az ingyenes SDCC fordítóprogram legújabb változatához lett igazítva. Nem kell hozzá nagy nagy munka szerintem, hogy másik fordító is megeméssze a sorokat. A C ezért egy szerencsés választás. Könnyen megeshet, hogy egy másik tipusú vezérlőre íródott program néhány apró változtatással áttehető PIC-re is, vagy fordítva.

  1. /* Template source file generated by piklab */
  2. #define NO_BIT_DEFINES
  3. #include <pic16f690.h>
  4.  
  5. /* ----------------------------------------------------------------------- */
  6. /* Configuration bits: adapt to your setup and needs */
  7. typedef unsigned int word;
  8. word __at 0x2007 CONFIG = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF;
  9.  
  10. #define ELORE    ( 1 )
  11. #define HATRA    ( 2 )
  12.  
  13. void isr() __interrupt 0 {
  14.     /* << megszakitasi kod helye >> */
  15. }
  16.  
  17. void main()
  18. {
  19.     unsigned int i;                // helyi valtozok
  20.     unsigned char be;
  21.     unsigned char irany;
  22.    
  23.     ANSEL = 0;                    // analog funkciok kikapcsolva
  24.     ANSELH = 0;
  25.  
  26.     TRISA = 0xFF;                // minden port bemenet
  27.     TRISB = 0xFF;
  28.     TRISC = 0xFF;
  29.  
  30.     TRISC_bits.TRISC0 = 0;        // kimeneti bitek lesznek
  31.     TRISC_bits.TRISC1 = 0;
  32.     TRISC_bits.TRISC3 = 0;
  33.  
  34.     irany = HATRA;
  35.     i = 0;    
  36.     while( 1 )
  37.     {
  38.         be = PORTB;                        // mintavetel a bemenetrol
  39.  
  40.         if( irany == ELORE ) i++;
  41.         if( i > 10000 )
  42.         {
  43.             irany = HATRA;
  44.             i = 0;
  45.         }
  46.  
  47.         if( ( be & ( 1 << 4 ) ) == 0 )     // vegallas benyomva
  48.         {
  49.             irany = ELORE;
  50.         }
  51.  
  52.         if( irany == ELORE )     // kimenetek beallitasa
  53.         {
  54.             PORTC_bits.RC1 = 1;
  55.             PORTC_bits.RC0 = 0;
  56.         }
  57.         if( irany == HATRA )
  58.         {
  59.             PORTC_bits.RC0 = 1;
  60.             PORTC_bits.RC1 = 0;
  61.         }
  62.         PORTC_bits.RC3 = ( be & ( 1 << 4 ) ) == 0;    // vegallas jelzese
  63.     }
  64. }

Jobban szeretem a kódban kiírni, hogy mikor melyik portra történik az írás, vagy éppen melyikről olvas be értéket a program, ezért szerepel a program elején a NO_BIT_DEFINES definíció. Ezt a fordítóprogram a fejlécállomány feldolgozása során veszi figyelembe. Ha ez a sor nem szerepelne, akkor például a PORTC_bits.RC3 helyett egyszerűen lehetne RC3-at írni. Viszont akkor már nem lehet a PORTC_bits.RC3-at használni. Nagyon szép megoldás, ha a kimenet/bemenet funkcióját a program elején egy define sorral összerendeljük. Így ha valamiért  az adott funkciót át kell tenni egy másik lábra, nem kell az egész forrást végigböngészni. Ebben a példában ez most elmaradt.

A konfigurációs szóból látható, hogy belső RC oszcillátorról fog menni az órajel, kísérletezéshez a legjobb választás. Pontos időzítésekhez azonban nem ajánlott, mert erősen elmászik a frekvenciája a hőmérséklet függvényében, de nagyon sok alkalmazásnál nem is számít annyira a pontos frekvencia.

Helyi változók alkalmazása időnként kockázatos, de ebben az egyszerű feladatban én megengedtem ezt a kockázatot, mivel megszakítást sem és egyéb más eljárást sem használ a program.

Miután a kimenetek/bemenetek sorsa eldől, kezdődik a fő ciklus. Ezen belül az irany nevű változó hordozza a fő információt, e mentén történik a végrehajtás. Az egyes sorokat megjegyzéssel elláttam, ezért azokat nem magyarázom, egy kivétellel. A kimenetek beállításánál arra kell odafigyelni, amint azt korábban írtam, hogy először a megfelelő irányt kikapcsoljuk, majd az ellenkező irányt bekapcsoljuk. Itt a 0 ( nulla ) jelenti a bekapcsolást, az 1 ( egy ) pedig a kikapcsolást. Ha nem így tennénk, akkor a hidat könnyen zárlatba vihetjük. Ennél a kisteljesítményű hajtásnál nem lényeges, de nagyobbaknál arra is oda kell figyelni, hogy a ki és bekapcsolások között hagyjunk időt a félvezetőknek nyugalomba térni. Attól még ugyanis, hogy a vezérlést elvesszük, a kapcsolóelem még nem fog azonnal kikapcsolni, ezért a túl gyors váltás szintén zárlatba viheti a hidat. Tervezéskor erre oda kell figyelni.

Érdemes a fenti sémát általánosan is követni, ha nem akarjuk az életünket túlságosan megkeseríteni. Általában ilyen ciklusos programok szoktak készülni a vezérlőkre, tehát némi előkészület után egy nagy hurokban kering a vezérlés. A hurok elején történik egy mintavételezés és a továbbiakban már csak ezzel dolgozik a program, a hurok végén pedig megtörténik a kimeneti lábak állapotának beállítása. Az ilyen módon megírt programnál nehezen fordul elő, hogy a kimenetek össze-vissza ugrálnak. A bemeneti mintavételnek az a jelentősége, hogy egy adott pillanatban meglévő állapotot lehet vizsgálni. Ha nem így tennénk, előfordulhat, hogy egy if utasításon belül ugyanarra a bemenetre hivatkozva egyik pillanatban még magas értéket ad, másikban meg alacsonyat. Ki lehet próbálni egy elvileg soha nem teljesülő, gyakorlaban mégis működő feltételt:

  1. if( PORTB_bits.RB0 == !PORTB_bits.RB0 ) PORTC_bits.RC2 = 1

Tehát az RB0 bemenet egyenlő önmaga ellentettjével feltétel időnként teljesülhet, de ha a vett mintára írunk fel hasonló feltételt, az már nem. ( Kivéve ha... )


A cikk még nem ért véget, lapozz!
Következő: »»   3 / 4
Értékeléshez bejelentkezés szükséges!
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