Fórum témák

» Több friss téma
Fórum » PIC - Miértek, hogyanok haladóknak
Lapozás: OK   1110 / 1320
(#) adamhollos hozzászólása Feb 5, 2013 /
 
Sziasztok!

Az alábbi kis programot írtam pic18f25k80-ra. Az volna a lényeg, hogy egy motort tartsak állandó fordulatszámon, akkor is, ha változik a terhelés. A bejövő jel egy HALL szenzortól jövő négyszög jel. T: a HALL szenzor jelének elérni kívánt periódus ideje T1 és T2 a mért periódus idő.

Tudom, hogy a periódus idők számolása nem OK, de ezen kívül más gondom is van. Az input capture-ök nem ott vannak a hol lenniük kéne. Lásd a fotót a felső a szenzor jele az alsó pedig akkor vált ha esemény van (lásd a kódot, az osztás az oszcilloszkópon 0,5 ms, az input capture a felfutó élre érzékeny). Nem telhet el ennyi idő a felfutó él és az esemény közt, hisz a timer tulcsordulását is leellenőriztem és ott az eltérés csak 0,01 ms volt a számolt értékhez képest

Az adatlapban egyáltalán nem találom, hogy mi lehet a gond, tudnátok segíteni?

Valaki tudna benne segíteni, hogy hogyan számoljam ki helyesen a periódusidőt?


íme a program kód (C18):
  1. #include <p18f25k80.h>
  2. #pragma config XINST = OFF, FOSC=INTIO2, IESO= ON, PWRTEN=ON, WDTEN=OFF, MCLRE=OFF
  3.  
  4. void con(void);
  5. void con_interupts(void);
  6. void con_PWM(void);
  7. void con_inCap(void);
  8. void lo_isr(void);
  9. void hi_isr(void);
  10.  
  11. #define t_h_inCap       CCPR3H
  12. #define t_l_inCap       CCPR3L
  13.  
  14.  
  15. #define plus            LATBbits.LATB5
  16. #define minus           LATBbits.LATB3
  17.  
  18. #define power           PORTCbits.RC2
  19. #define direction       PORTCbits.RC3
  20.  
  21. #define duty_cycle      CCPR1L
  22.  
  23. #define test            LATAbits.LATA1
  24.  
  25.  
  26. volatile long double T=5;                       //[ms]
  27.  
  28. volatile long double T1=0;
  29. volatile long double T2=0;
  30. volatile int n=0;
  31. volatile int f=1;
  32.  
  33. volatile double in=0;
  34.  
  35.  
  36. void main (void)
  37. {
  38.         OSCCONbits.IRCF0=1;                                     //
  39.         OSCCONbits.IRCF1=1;                                     //belső órajel 16MHz
  40.         OSCCONbits.IRCF2=1;                                     //
  41.         con();
  42.         T2CONbits.TMR2ON=1;
  43.         T1CONbits.TMR1ON=1;                            
  44.         plus=1;
  45.         minus=0;  
  46.         duty_cycle=200;
  47.         while (1)
  48.         {
  49.  
  50.                 if(n==1)
  51.                 {
  52.                
  53.                         if(T1>T&&duty_cycle<255)
  54.                         {
  55.                        
  56.                                 duty_cycle+=1;
  57.                        
  58.                         }
  59.                        
  60.                         if(T1<T&&duty_cycle>0)
  61.                         {
  62.                        
  63.                                 duty_cycle-=1;
  64.                        
  65.                         }
  66.                        
  67.                         //n=0;
  68.                
  69.                 }
  70.  
  71.                 if(n==2)
  72.                 {
  73.  
  74.                         if(T2>T&&duty_cycle<255)
  75.                         {
  76.                        
  77.                                 duty_cycle+=1;
  78.                        
  79.                         }
  80.                        
  81.                         if(T2<T&&duty_cycle>0)
  82.                         {
  83.                        
  84.                                 duty_cycle-=1;
  85.                        
  86.                         }
  87.                        
  88.                         //n=0;
  89.  
  90.                 }
  91.  
  92.         }
  93. }
  94.  
  95. void con(void)
  96. {      
  97.         ANCON0=0;                                                       //
  98.         ANCON1=0;                                                       //Minden digitális
  99.        
  100.         LATA=0;
  101.         LATB=0;
  102.         LATC=0;
  103.         TRISA=0;
  104.         TRISB=0x00;                                                     //RB5, RB4 és RB3 legyen kimenet
  105.         TRISC=0x0C;                                                     //RC3 és RC2 legyen bemenet
  106.  
  107.         con_PWM();
  108.         con_inCap();
  109.         con_interupts();
  110.  
  111. }
  112.  
  113. void con_PWM(void)
  114. {
  115.  
  116.         PSTR1CON=0x11;                                          //Output steering update occurs on the next PWM period & P1A pin has the PWM waveform with polarity control from CCP1M<1:0>
  117.         CCPTMRSbits.C1TSEL=0;                           //ECCP1 is based off of TMR1/TMR2
  118.         PR2=0xFF;                                                       //PWM periodus
  119.         CCP1CON=0x3C;                                           //singel output, PWM mode; P1A and P1C active-high; P1B and P1D active-high
  120.         CCPR1L=0;
  121.         T2CON=0x00;            
  122.  
  123. }
  124.  
  125. void con_inCap(void)
  126. {
  127.        
  128.         TRISCbits.TRISC6=1;
  129.  
  130.         CCP3CON=0x05;                                           //Capture mode: every rising edge
  131.         CCPTMRSbits.C3TSEL=0;                           //forrása a Timer1
  132.        
  133.         T1CON=0x40;                                                     //Timer1 clock source is instruction clock (FOSC), Enables register read/write of Timer1 in two 8-bit operations
  134.         T1GCONbits.TMR1GE=0;                            //nem Gate-ről kapja a jelet
  135.         TMR1H=0;
  136.         TMR1L=0;
  137. }
  138.  
  139. void con_interupts(void)
  140. {
  141.  
  142.         RCONbits.IPEN=1;                                        //Kétszintű interrupt mód beállítása
  143.         INTCON2=0;                                                      //
  144.         INTCON3=0;                                                      //     
  145.      
  146.         PIE1bits.TMR1IE=1;                                      //Enables the TMR1 overflow interrupt
  147.         PIE2=0;                                                         //
  148.         PIE3=0;                                                         //
  149.         PIE4bits.CCP3IE=1;                                      //CCP3 Interrupt enabled
  150.         PIE5=0;                                                         //
  151.  
  152.         IPR1bits.TMR1IP=1;                                      //TMR1 Overflow Interrupt high Priority
  153.         IPR4bits.CCP3IP=1;                                      //CCP3 interrupt low priority
  154.  
  155.         INTCON=0xC0;                                            //High pri. interrupt enabled, Low  pri. interrupt enabled
  156.  
  157. }
  158.  
  159. #pragma code high_vector_addr=0x08
  160. void high_vector(void) {
  161.   _asm GOTO hi_isr _endasm
  162. }
  163.  
  164. #pragma code low_vector_addr=0x18
  165. void low_vector(void) {
  166.   _asm GOTO lo_isr _endasm
  167. }
  168.  
  169. #pragma code
  170. #pragma interrupt hi_isr
  171. void hi_isr (void)
  172. {
  173.         if(PIR1bits.TMR1IF==1)
  174.         {
  175.                 if(f==1)
  176.                 {
  177.                         T1+=65536*0.0000625;
  178.                 }else
  179.                 {
  180.                         T2+=65536*0.0000625;
  181.                 }
  182.                 PIR1bits.TMR1IF=0;
  183.         }
  184.  
  185.         if(PIR4bits.CCP3IF==1)
  186.         {
  187.                 if(test==1){test=0;}else{test=1;}
  188.        
  189.                 if(f==1)
  190.                 {
  191.                
  192.                         in=(t_h_inCap*256+t_l_inCap+1)*0.0000625;
  193.                        
  194.                         T1+=in;
  195.                         n=1;
  196.                        
  197.                         T2=65536*0.0000625-in;
  198.                         f=2;
  199.                
  200.                 }else
  201.                 {
  202.                
  203.                         in=(t_h_inCap*256+t_l_inCap+1)*0.0000625;
  204.                        
  205.                         T2+=in;
  206.                         n=2;
  207.                        
  208.                         T1=65536*0.0000625-in;
  209.                         f=1;
  210.                
  211.                 }
  212.  
  213.                 PIR4bits.CCP3IF=0;
  214.        
  215.         }
  216. }
  217.  
  218. #pragma interruptlow lo_isr
  219. void lo_isr (void)
  220. {
  221. }
A hozzászólás módosítva: Feb 5, 2013

P1050004.JPG
    
(#) watt válasza adamhollos hozzászólására (») Feb 5, 2013 /
 
Szia!
A programot csak felületesen néztem át és néhány olyan dolgot láttam, amit nem értek.
Azt tudod-e, hogy a lebegőpontos számok használata megszakításban olyan, mint ha egy várakozási ciklust tettél volna bele? Rengeteg program lépés, mire a PIC végigrágja magát a sámításokon.
De ez csak az egyik rész. Ha már CCP modult használsz capture módban, miért nem a Timer1 CCP regiszterekbe áttöltött értékéből számolod ki a periódust, ez előző és a mostani érték különbségéből? Mi szükség a segédváltozókra? A Timer megszakításban legfeljebb a túlcsordulásokat számold, amivel a CCP megszakításban kalkulálsz, ha két impulzus között a timer1 túlcsordulna. De motor esetében erről szerintem nem lesz szó, csak amikor áll a motor.
(#) bbalazs_ válasza adamhollos hozzászólására (») Feb 5, 2013 /
 
Mar bocsass meg, de idokritikus alkalmazast irni c-ben.... brrrr.
Legalabb assembly betetet alkalmazz, ha a feladat megkivanja.
Az ember szine feher. A PIC nyelve asm.
(#) watt válasza bbalazs_ hozzászólására (») Feb 5, 2013 /
 
Szia! Igazad van, de ebben az esetben a CCP modul leveszi(levenné) a terhet az időkritikus részről, a többi elfér C-ben. Ezt szerintem meg lehet írni C-ben is gond nélkül.
(#) icserny válasza bbalazs_ hozzászólására (») Feb 5, 2013 /
 
Idézet:
„A PIC nyelve asm.”
Hm, majd próbálj meg beletölteni egy asm fájlt, mindjárt rájössz, hogy nem...
(#) bbalazs_ válasza icserny hozzászólására (») Feb 5, 2013 /
 
Ja, hogy ez c file-lal megy?
(#) vicsys válasza bbalazs_ hozzászólására (») Feb 5, 2013 /
 
Idézet:
„A PIC nyelve asm.”
A volt főiskolai tanárom azt mondta erre, hogy ezt azok szokták hangoztatni, akik nem foglalkoztak/ foglalkoznak a C nyelvvel és nem ismerik....
Szerintem az igazság valahol a kettő között van, mindegyik nyelvet jó lenne ismerni és dönteni, hogy az adott feladathoz melyik illeszkedik jobban, mindenféle tényezőket figyelembe véve.
(#) Hp41C válasza vicsys hozzászólására (») Feb 5, 2013 /
 
Mégis, ha egy kontroller programját vissza kell fordítani (ellenőrzés végett), mindig asseblyre fordítják vissza. Ha valami kétely merül fel a lefordított kóddal kapcsolatban, akkor is az assembly lista segít. Hátrányként szokták emlegetni, ha egy magas szintű nyelv nem teszi lehetővé a könyvtári függvényei assembly szintű nyomkövetését.
(#) vicsys válasza Hp41C hozzászólására (») Feb 5, 2013 /
 
Ez igaz, de egy abszolút kezdőnek nagyon hamar lehet sikerélménye egy hello word!-el, ha fogalma sincs a belső felépítésről, címzésekről, Bank-okról, stb... A mostani PIC-ek meg már elég jó paraméterekkel rendelkeznek és nem jelent gondot ezen a szinten a debug hiánya, vagy, hogy elfogyna a memória...
(#) watt hozzászólása Feb 5, 2013 /
 
Az jelen feladatot mindkét nyelven hasonló hatékonysággal meg lehet írni. Nekem mindkét nyelv a szívem csücske lett, pedig asm-al kezdtem. Most keverem a kettőt, mikor C-ben programozok, akkor is asm szerűen oldom meg a feladatokat, nem úgy, mint ha PC-n írnám C-ben.
(#) watt hozzászólása Feb 6, 2013 /
 
Sziasztok!
Lehet egyszerre használni az ADC-t és a Comparátort? (a lábakat értelemszerűen megosztva).
Még ilyet nem csináltam és az adatlapban nem igazodok el. (18F4550)
Két AD bemenet kéne Vss reffel és egy Comparátor nullátmenet detektálásra.
Köszi!
(#) icserny válasza watt hozzászólására (») Feb 6, 2013 /
 
A lábakat nehéz lesz kisakkozni a kötöttségek miatt. Talán a CM2,CM1,CM0 = 001 beállítás áll legközelebb ahhoz, amit mondtál. De ekkor csak RA1 és RA2 használható az ADC-hez, RA0 és RA3 pedig a komparátorhoz. Nem tudom, hogy működőképes-e ez a kombináció.
(#) watt válasza icserny hozzászólására (») Feb 6, 2013 /
 
Szia! Erre a kiosztásra gondoltam én is, de nem tudom, hogy a két periféria üti-e egymást. Lehet, hogy akár a komparátor bemenetén a feszt is meg lehet mérni ugyanazon lábon az AD-vel? Végül is miért ne! Na majd kipróbálom! Köszi!
(#) adamhollos válasza watt hozzászólására (») Feb 6, 2013 /
 
Köszönöm a segítséget, közben megoldottam.

Idézet:
„A PIC nyelve asm.”


Minden tiszteletem annak aki asm.-ben összedob egy bonyolultabb programot pl. egy jobbfajta motorvezérlőt, részemről a C teljesen megfelelő (am. asm-ben is tudok programozni, de nem igazán vagyok oda érte )
A hozzászólás módosítva: Feb 6, 2013
(#) helektro válasza watt hozzászólására (») Feb 6, 2013 /
 
Működik. Már nem emlékszem melyik tipuson, de én csináltam olyat, hogy komparátornak használtam egy bemenetet és mértem rajta AD-vel is.
Én a tápfeszt kötöttem rá, ami ha egy bizonyos szint alá esett (komparátor), akkor megszakítást generált.
Időnként meg megmértem ugyanazon a lábon a tápfeszt és felhasználtam a mért értéket.
(#) watt válasza helektro hozzászólására (») Feb 7, 2013 /
 
Köszönöm az infót!
(#) horcsab hozzászólása Feb 8, 2013 /
 
PIC18F26K80

Ehhez a kontrollerhez most fogtam hozzá és már az elején egy hibába
botlottam. Rengeteget olvastam és kerestem a neten, hátha találok
valami leírást, de sajna nem.

A hiba röviden.
Az RB4 lábat ha folyamtosan magasra állítom, akkor egy órajelnyi
impulzus van a kimeneten folymatosan, nincs stabilan magasban.

Elvileg mindent beállítottam ami kellhet, de nem tudom mi okozza ezt a
(számomra) hibát.

MPLAB 8.88 és C18 9.80 a fejlszető környzet.

Valakinek ötlete, hogy mi okozhatja?

  1. #include <p18f26k80.h>                                  // Register definitions
  2.  
  3. #pragma config SOSCSEL = DIG
  4. #pragma config XINST = OFF
  5. #pragma config FOSC = INTIO2
  6. #pragma config PLLCFG = ON
  7. #pragma config FCMEN = OFF
  8. #pragma config IESO = OFF
  9. #pragma config PWRTEN = OFF
  10. #pragma config BOREN = SBORDIS
  11. #pragma config BORV = 0
  12. #pragma config WDTEN = OFF
  13. #pragma config CANMX = PORTC
  14. #pragma config MCLRE = OFF  
  15.  
  16. #pragma config CPD = OFF
  17. #pragma config CP1 = OFF
  18. #pragma config CP2 = OFF
  19. #pragma config CP3 = OFF
  20. #pragma config WRT1 = OFF
  21. #pragma config WRT2 = OFF
  22. #pragma config WRT3 = OFF
  23.  
  24.  
  25. //#include <adc.h>                                              // ADC library functions
  26. //#include <timers.h>                                          // Timer library functions
  27. //#include <stdio.h>
  28. //#include <delays.h>
  29.  
  30.  
  31. //---------------------------------------------------------------------
  32. //Constant Definitions
  33. //---------------------------------------------------------------------
  34.  
  35. #define Kim_Fel PORTCbits.RC3          
  36. #define Kim_Le  PORTCbits.RC4  
  37. #define Kim_Err PORTBbits.RB4          
  38. #define Kim_aaa PORTBbits.RB5          
  39. #define Kim_STP PORTCbits.RC1
  40. #define Kim_DIR PORTCbits.RC2
  41.  
  42. #define Bem_Eng PORTBbits.RB0          
  43. #define Bem_Stp PORTBbits.RB1          
  44. #define Bem_Cor PORTAbits.RA4          
  45. #define Bem_0   PORTAbits.RA5  
  46.  
  47.  
  48. #define setKim_Fel()     (Kim_Fel = 1)
  49. #define clrKim_Fel()     (Kim_Fel = 0)
  50.  
  51. #define setKim_Le()      (Kim_Le  = 1)
  52. #define clrKim_Le()      (Kim_Le  = 0)
  53.  
  54. #define setKim_Err()     (Kim_Err  = 1)
  55. #define clrKim_Err()     (Kim_Err  = 0)
  56.  
  57. #define setKim_aaa()     (Kim_aaa  = 1)
  58. #define clrKim_aaa()     (Kim_aaa  = 0)
  59.  
  60. #define setKim_STP()     (Kim_STP  = 1)
  61. #define clrKim_STP()     (Kim_STP  = 0)
  62.  
  63. #define setKim_DIR()     (Kim_DIR  = 1)
  64. #define clrKim_DIR()     (Kim_DIR  = 0)
  65.  
  66. //---------------------------------------------------------------------
  67. // Variable declarations
  68. //---------------------------------------------------------------------
  69.  
  70.  
  71. void main(void)
  72. {
  73. OSCCONbits.IRCF = 0b111; //16MHz
  74. OSCTUNE = 0b11011111;
  75. TRISA = 0b11111111;
  76. TRISB = 0b11000011;
  77. TRISC = 0b10100001;
  78. CTMUCONH = 0;
  79. ADCON0 = 0x00;
  80. ADCON1 = 0x00;
  81. ADCON2 = 0x00;
  82. REFOCON = 0;
  83.  
  84.  
  85. while(1)
  86. {
  87. setKim_Fel();
  88. setKim_Le();
  89. setKim_Err();
  90. setKim_aaa();  
  91. setKim_STP();
  92. setKim_DIR();
  93. }
  94. }
A hozzászólás módosítva: Feb 8, 2013
(#) bbalazs_ válasza horcsab hozzászólására (») Feb 8, 2013 /
 
Csak egy altalanos jotanacs: ezeknel a PICeknel mar tul sok a regiszter es ezert egyes funkcioregiszterek nem erhetok el direktben, hanem a BANKot is allitani kell hozza. Talan ez okozhatja nalad is a hibat. Pl. az ANCON maris kivul van ezen.
Egyebkent megnezhetned, hogy csak magas szintet nem ad-e ki vagy egyaltalan nem is valt outputba, magyaran lehuzza-e a 4K7-en keresztul adott tapot...
A masik lehetoseg, hogy a PWM outputot nem allitottad jol, a fent emlitett okok miatt.
A hozzászólás módosítva: Feb 8, 2013
(#) horcsab válasza bbalazs_ hozzászólására (») Feb 9, 2013 /
 
Tudtommal, a fordító automatikusan váltja a bankot.
Az RB4-es kimenetre (és még néhányra) egy LED van kötve és a LED halvánnyabban világít a többihez képest.

Szkóppal nézve egy órajelnyi impulzusig megy magasra a kimenet, majd alacsonyba vált, pedig a program szerint folyamatosan magasban kellenne lennie.
62.5ns-ig 5V, majd kb 1.8us-ig 0V, majd megint 62.5ns-ig 5V és így tovább. Folyamatos impulzus vana kimeneten.
(#) _vl_ válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Jól gondolod, a bankváltósdival csak az assemblyben dolgozóknak kell foglalkozni.
Ha minden terhelést leszedsz a lábról (LED), akkor is ugyanezt csinálja?
Elvileg lehetne valami kalandor periféria, de alapból mindegyik periféria kimenet le van tiltva, azért egy CCP1CON = 0 nem árthat. A jelenség alapján a CCP/PWM perifériára gyanakodnék leginkább.
A hozzászólás módosítva: Feb 9, 2013
(#) horcsab válasza _vl_ hozzászólására (») Feb 9, 2013 /
 
CCP1CON = 0 berakva, ugyan az a hiba...
Ha lekötöm a LED akkor is ugyan az.

Errata átolvasása után nem találtam benne semmi infót ami ilyen jelenségre utal.

Most már hullik a hajam...

Bagatel dolog és nem haladok.
A hozzászólás módosítva: Feb 9, 2013
(#) watt válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Nézz körül az adatlapban az RB4 IO port résznél a CTPLS funkció körül! (CTPLS=> CTMU pulse generator output)
(#) potyo válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Egyrészt kapcsold át az RB4 lábat digitális üzemre, mert analóg üzemben van - ANCONx regiszterek valamelyike. Másrészt ha már 18F, akkor kimenetként használva nem a PORTx, hanem a LATx biteket kellene használni. Látszólag az utóbbi is megoldaná a problémádat, de az előbbit is csináld meg és szokd meg, hogy kell.
(#) Sasmadár válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Úgy néz ki egy órajel időre 5V, 3-ra 0V RB4. Lehet valami PWM hiba, bár CCP1CON = 0 esetén ki van kapcsolva. Próbáld meg PSTR1CON = 0. Esetleg másik IC-vel is próba.
(#) horcsab válasza potyo hozzászólására (») Feb 9, 2013 /
 
A megoldás a LATx bitek használata!

A bemenetek és kimenetek előtte már át voltak kapcsolva digitálisra.

Köszi a segítséget!
(#) potyo válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Nem, nem voltak, a kódodban nincsenek átkapcsolva! Ha át lettek volna, akkor a PORTx-el is működött volna!
A hozzászólás módosítva: Feb 9, 2013
(#) horcsab válasza potyo hozzászólására (») Feb 9, 2013 /
 
Amit ide beraktam, abban tényleg nem voltak átkapcsolva csak az utána következő probálkozásokban. Azokat nem raktam be ide. Mikor a be és kimeneteket átirtam LATx-re azonnal megjavult.
Most jeleneleg az a konfig:

OSCCONbits.IRCF = 0b111; //16MHz
OSCTUNE = 0b11011111;
TRISA = 0b11111111;
TRISB = 0b11000011;
TRISC = 0b10100001;
CTMUCONH = 0;
ADCON0 = 0x00;
ADCON1 = 0x00;
ADCON2 = 0x00;
REFOCON = 0;
INTCON = 0;
CCP1CON = 0;
(#) Sasmadár válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Érdekes, adatlap szerint:
Idézet:
„CLRF PORTB ; Initialize PORTB by
; clearing output
; data latches
CLRF LATB ; Alternate method
; to clear output
; data latches”
A hozzászólás módosítva: Feb 9, 2013
(#) horcsab válasza Sasmadár hozzászólására (») Feb 9, 2013 /
 
Na igen, ha csak nem valami bug van a kontrollerben.
(#) potyo válasza horcsab hozzászólására (») Feb 9, 2013 /
 
Ebben sincs átállítva digitális módba az RB4 láb. Mondom, ANCONx regiszterek.
Következő: »»   1110 / 1320
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