Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
LCD counter
#41
(12-16-2016, 02:54 PM)gorankg Wrote: Za svaku liniju stavljaš asm("...");

Ako tako mora - neće biti teško Smile
Reply
#42
Samo jedno pitanje, kolika je duzina "CLKCNT" promenljive?
Reply
#43
(12-16-2016, 03:00 PM)mikikg Wrote: Samo jedno pitanje, kolika je duzina "CLKCNT" promenljive?

integer (32 bit)
Reply
#44
Onda moj asm mod mora da se promeni. On je za 8bit-a
Reply
#45
Kod sada izgleda ovako :


// IRQ handler for IC2 (RD1) = DIR
// handled on every state change
void __attribute__((__no_auto_psv__, __interrupt__)) _IC2Interrupt(void)
{
IFS0bits.IC2IF = 0; // clear IF

asm ("nop");
asm ("movlw 0x01");
asm ("movwf CLKCNT");
asm ("btfsc DIR");
asm ("goto INTEND");
asm ("comf CLKCNT,f");
asm ("INTEND");
}


Opet - BUILD FAILED

Jedino prodje NOP - i za nju nema izvešataja o greški !
Za ostalo je:

C:\Users\Zeljko\AppData\Local\Temp/ccd6pLlr.s: Assembler messages:
C:\Users\Zeljko\AppData\Local\Temp/ccd6pLlr.s:5829: Error: Invalid mnemonic: 'movlw'
C:\Users\Zeljko\AppData\Local\Temp/ccd6pLlr.s:5831: Error: Invalid mnemonic: 'movwf'
C:\Users\Zeljko\AppData\Local\Temp/ccd6pLlr.s:5833: Error: Invalid mnemonic: 'btfsc'
C:\Users\Zeljko\AppData\Local\Temp/ccd6pLlr.s:5837: Error: Invalid mnemonic: 'comf'
C:\Users\Zeljko\AppData\Local\Temp/ccd6pLlr.s:5839: Error: Invalid mnemonic: 'intend'
Reply
#46
Zeljo,

koji MCU koristis? Ovaj ASM je za PIC. Nemoguce je da ne prolazi. Neko podesavanje nije dobro.
Reply
#47
MPLAB + C30 compiler + dsPIC30F4012
Reply
#48
Treba pogledati, dsPIC ima posebne instrukcije za 16 ili 32 bitne operande
Reply
#49
Izgleda da se odgovor krije u ovom dokumentu;
http://ww1.microchip.com/downloads/en/De...70157C.pdf

***
Jbg, ja sam do sada koristio samo PBP za PIC-ove i ovo mi je ipak sve novo ...

Evo :

izgleda da su drugačije instrukcije na ASM nivou za dsPIC i MID seriju PIC-ova

Pozz
Reply
#50
Odprilike tako, nema dok se duboko nezaviri u DS.
Reply
#51
Želja,

Ovaj način korišćenja  capture interrupt-a je isto kao da si korstio INT0, recimo s tom razlikom što ulaziš u prekid i na uzlaznu i na silaznu ivicu. U tom slučaju ti je mnogo bolje da nekim selektorom (tvoj DIR) vodiš impulse na INT0 pin kad brojiš NA GORE i na INT1 pin kad brojiš na dole. U prekidnim rutinama samo uvećavaš, odnosno umanjuješ brojač.
Drugi, bolji, način je da vodiš impulse na ulaz T13CKI. Tada u prekid ulaziš samo kad timer0 (ovaj put u ulozi countera) nagruva 65536 impulsa. Ako nećeš brojati više od te cifre onda je ovo ubedljivo najbrže i najlakše rešenje. U glavnoj petlji periodično čitaš TMR1H i TMR1L. Ovaj PIC18F4620 iz nekog razloga ne broji prvi impuls i ne znam o čemu se radi.
Reply
#52
Još jednu stvar mi reci.

Da li će biti razlike u optimizaciji , odnosno brzini rada za kodove koji su dobijeni upotrebom :

1. MPLAB 8.x + C30(full)
2. ako taj prethodni uvezem u MPLAB X3.50 + XC16(Full)

Znači u pitanju je isti sors od prve opcije.

Pozz
Reply
#53
Zeljo,

mislim da optimizacija nece nista pametno da uradi na tako sitnom kodu. Daj sta treba da se napise, pa cu ti napisati to u ASM. Takodje mislim da nema potrebe da koristis dsPIC. Nije on namenjen za te aplikacije. On je vise za neku digitalnu obradu signala, posto su njegove instrukcije optimizovane za iizvrasavanje diferencnih jednacina. Ne kazem da ne moze, nego mislim da nema smisla to koristiti za brojac. Uzmi bilo koji PIC18 i sa njim implementiraj.
Reply
#54
Evo ti za PIC19F4620. Može da se primeni praktično na bilo koji 8-bitni.


Code:
#include <xc.h>
#include <stdlib.h>
#include "hd44780.h"
#include "cfg.h"

#define    _XTAL_FREQ    40000000        /* Crystal frequency in MHz */    



unsigned long c;

void interrupt ISR(void)
{
   if(TMR1IF)
   {
       TMR1IF = 0;      
   }
}



void main(void)
{
unsigned char i;
char lcd[10];

   RCON = 0b00011111;

   for(i=0;i<10;i++){__delay_ms(100);}

    CMCON = 0x07;                

    LATA = 0;
    TRISA = 0xFF;        
    LATB = 0;     
    TRISB = 0xFF;
    LATC = 0;
    TRISC = 0xFF;            
    LATD = 0;
    TRISD = 0xFF;
    ADCON1 = 0x0F;
    LATE = 0x00;
    TRISE = 0x00;

    OpenLCD();
    ClearLCD();

   TMR1L = 0;
   TMR1H = 0;
   T1CON = 0b10000111;
   TMR1IF = 0;
   TMR1IE = 1;
   
    PEIE = 1;
    GIEL = 1;
   GIEH = 1;

    while(1)
    {
       for(i=0;i<10;i++){__delay_ms(100);}

       c = (unsigned long)((TMR1H << 8) + TMR1L);

       ltoa(lcd, c, 10);
       GotoLCD(0,0);
       PutsLCD(lcd);
    
   }
}
Ovo ti broji samo u jednom smeru do vrednosti promenljive od dva bajta (65535).
Reply
#55
HVALA drugar Smile
Reply
#56
Želja,

Ova varijanta sa korišćenjem tajmera kao brojača ti radi skroz posao. Na T13CKI pin, (kod PIC18F4620 ti je to RC0) dovodiš impulse a u softveru podesiš da ti je aktivan tajmer1 ako brojiš nagore a tajmer3 kad brojiš na dole. U glavnoj petlji samo prikažeš razliku ova dva brojača. Ako brojiš više impulsa od 2 na 16 onda mora softver da obračunava taj overflow kod 16-bitnih brojača.
Reply
#57
Šta su razlike, mane i prednosti kada brojimo spoljne impulse upotrebom :

1. Hardverskog CAPTURE modula
2. Eksternim klokom nekog tajmera

Jasno je da odlično funkcionišu oba rešenja, ali sigurno da postoje i neke razlike ..

***

Ako sam ja dobro shvatio, upotrebom CAPTURE modula sve se odvija na hardverskom nivou
i moguće je čitati zadnju upisanu vrednost za vreme uzorkovanja nove vrednosti.

Pozz
Reply
#58
Zeljo,

Goran je u pravu. Ako ti treba samo brojac dogadjaja, onda ke najbolje koristiti neki TMR koji ce raditi u modu brojaca externih dogadjaja. Ako ti treba i trenutak dogadjaja, onda koristis capture modul.
Reply
#59
1. Capture kada meriš frekvenciju. Pogledaj šta kaže datasheet za PIC 18F4620 a tako je i kod drugih, bar koliko ja znam:

"In Capture mode, the CCPRxH:CCPRxL register pair captures the 16-bit value of the TMR1 or TMR3 registers when an event occurs on the corresponding CCPx pin. When a capture is made, the interrupt request flag bit, CCPxIF, is set;"

Dakle, uključiš tajmer pa čekaš prekid i CCPxIF. Dva event-a na istu ivicu daju ti periodu signala. Pošto znaš koliko je trajanje kloka kod tajmera1 ili tajmera3 lako dobijaš tu periodu množenjem sadržaja CCPRxH:CCPRxL sa osnovnom periodom tajmera.
To koristiš kad meriš frekvenciju.

Ako koristiš Capture za counter u prekid ulaziš na prednju i na zadnju ivicu signala pa tu uvećavaš/umanjuješ counter za 1! Dobio si isto što i kada bi koristio INT pinove. A INT je i bolje rešenje jer je high priority kod ovog MCU a možeš da koristiš INT0 za UP a INT1 za DOWN ako signal odvedeš na te pinove kad brojiš.

2. Kada konfigurišeš tamer1 ili tajmer3 da radi kao counter on baš radi ono što tebi treba, broji događaje. Prekid generiše samo kada imaš overflow i u tom slučaju na prethodno uzetu vrednost iz para TMRxH:TMRxL dodaješ 65536. To je jedina softverska intervencija. Od vrednosti 0 do 65535 sve se odvija u hardveru i tvoj MCU visi u nekom drugom poslu.

Evo iz datasheet-a za PIC18F4620 modovi rada Tajmera

"Timer1 can operate in one of these modes:
• Timer
• Synchronous Counter
• Asynchronous Counter "
Kako ovaj PIC ima dva takva tajmera jedan možeš da koristiš da broji na gore a drugi na dole, pri čemu je jedan isključen dok radi drugi a sve u zavisnosti od DIR.
Reply
#60
Trrebalo bi da mogu da se spoje "redno" TMR1 i TMR3 (ili ima tacno predvidjen par) koji tada onda rade kao 32bitni HW brojac. Nije moranje ali zgodno da se proba i nauci kako se uvezuju a i moze da ostane tako jer bezveze da se ne iskoriste kad ih vec ima (i ima jos nekoliko brojaca pored toga). Mozda ovo vazi za dsPIC, probajte … Tu su zgodni oni konfiguratori sto dolaze uz MplabX, u njima imaju sve te kombinacije ...
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)