Mjerenje širine signala pomoću Tajmer0

Rasprava o PIC mikrokontrolerima, PIC projekti i drugo vezano za PIC-eve...

Moderators: stojke369, pedja089, [eDo], trax

majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Pozdrav,
radim s PIC 16F887, 8 Mhz, na easyPic5. Pokušavam izmjeriti širinu signala na RB.5 pomoću Tajmera0. Osnovni signal ima širinu 19.5ms i interval između dva signala je oko 19.6ms. Osnovna zamisao je da pomoću Inetrrupt izmjerim širinu signala i dalje ju obrađujem, ali zapeo sam na mjerenju (ne radi mi inerrupt rutina). Možete li mi pomoći (guglam već skoro dva mjeseca, a rezultat ništa)?

Code: Select all

dim signal as sbit at RB5_bit
dim counter, cnt, CNT_STARI as word
dim CNT_str, CNT_STARI_STR as string [5]

sub procedure  interrupt()        ' Interrupt rutine
  INTCON.GIE=0
    if TestBit (INTCON, RBIF = 1 )then      
        INTCON.RBIF = 0
        If  signal=1 then
            cnt=0
            TMR0=240
            INTCON.T0IE=1
        else
            CNT_STARI=cnt
        end if
    end if
    IF  (INTCON.T0IF = 1 ) THEN      ' PROVJERA JE LI DOŠLO DO OVERFLOW
        INTCON.T0IF = 0
        INC (cnt)
    end if
end sub
'----------------------------------------------------------------------------
main:                     ' Main program
  ANSEL  = 0              ' MCU settings, digital I/O and Comparators off
  ANSELH = 0
  C1ON_bit = 0
  C2ON_bit = 0
  TRISB.5=1                'Set PB5 as input
  INTCON = 0x90           '1001 0000
  WPUB.WPUB5=1             ' Weak Pull-Up on pin B0
  IOCB.IOCB5=1
  Lcd_Init() Lcd_Cmd(_LCD_CLEAR) Lcd_Cmd(_LCD_CURSOR_OFF)
  CNT=0
  CNT_STARI=0
  '---------------------------------------------
  OPTION_REG.T0CS=0
  OPTION_REG.PSA=0   ' PRESKALER SE DODJELJUJE TIMER0
  OPTION_REG.PS2=0
  OPTION_REG.PS1=0
  OPTION_REG.PS0=0
  TMR0=240
  INTCON.T0IE=1
  INTCON.T0IF=0
  while (True )           ' Unending loop
     wordtostr (CNT, CNT_str)
     lcd_out (1,1,CNT_str)
     wordtostr (CNT_STARI, CNT_STARI_str)
     lcd_out (2,1,CNT_STARI_str)
 wend
end.
User avatar
pedja089
Administrator sajta
Administrator sajta
Posts: 7871
Joined: 20-02-2007, 14:50
Location: Beočin -Srbija

Re: Mjerenje širine signala pomoću Tajmer0

Post by pedja089 »

Ne znam koji je to programski jezik, nepoznat mi je. Ocigledno neka vrsta basica.
NEbitno...
Program podeli na delove. Napravi prvo da ti radi tajmer, i proveri da li je dovoljno brz da imas zadovoljavajucu rezoluciju.
Zatim proveri da li ti uopste radi ulaz, napravi u mainu nesto za test sa tim signalom.
Zatim proveri da li ti se aktivira flag pri interuptu u mainu(nemoj omoguciti interupt, flag ce svakako biti aktiviran, ali nece doci do interupta).

Kad ti sve ovo radi, onda kreni sa interuptom prvo za timer overflow.
Kad ti on radi, onda idi na inteupt sa pina, nek ti uradi nesto sa prelaskom sa 1 na 0, ili sa 0 na 1. Ili i oboje...
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Pozdrav Pedja089,
radi se o mikroBasicu. Hvala na savjetima.
Provjerio sam rezoluciju TIMER0 i on može imati minimalnu rezoluciju 200us, a meni treba 100us, tako da prelazim na TIMER1 (on zadovoljava moj uvjet). S obzirom da nisam majstor kao većina vas, sada mi predstoji čitanje i podešavanje TIMER1, pa se javim s rezultatima.
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Peđa 089,
sve sam uradio kako si me savjetovao. Minimalnu rezoluciju koju sam dobio na Timer1 je 50us i to se vidi na osciloskopu. Ispod toga nisam mogao. Program sam podesio po komponentama i sve radi za sebe OK. Kada sam spojio program i uz rezoluciju 50 us, te širinu signala od 19,9ms moj LCD bi morao pokazivati 390 (cnt_stari 370), međutim on pokazuje 27 što nije nikako u redu. Povećavao sam rezoluciju i do 200 us, ali rezultat je uvijek isti. Može li mi netko pomoći kakvom sugestijom, jer ja vjerojatno imam grešku u kodu.dim LCD_RS as sbit at RD4_bit
LCD_EN as sbit at RD5_bit
LCD_D4 as sbit at RD0_bit
LCD_D5 as sbit at RD1_bit
LCD_D6 as sbit at RD2_bit
LCD_D7 as sbit at RD3_bit

LCD_RS_Direction as sbit at TRISD4_bit
LCD_EN_Direction as sbit at TRISD5_bit
LCD_D4_Direction as sbit at TRISD0_bit
LCD_D5_Direction as sbit at TRISD1_bit
LCD_D6_Direction as sbit at TRISD2_bit
LCD_D7_Direction as sbit at TRISD3_bit

dim signal as sbit at RB5_bit
dim cnt, CNT_STARI as word
dim CNT_str, CNT_STARI_STR as string [5]

sub procedure interrupt() ' Interrupt rutine
INTCON.GIE=0
INTCON.PEIE=0
if TestBit (INTCON, RBIF = 1 )then ' INERRUPT NA rb5
INTCON.RBIF = 0
If signal=1 then
cnt=0
INTCON.RBIF = 0
PIE1.TMR1IE=1
else
CNT_STARI=cnt
end if
end if
IF (PIR1.TMR1IF = 1 ) THEN ' PROVJERA JE LI DOŠLO DO OVERFLOW
PIR1.TMR1IF=0
INC (cnt)
TMR1H = 0xff
TMR1L = 0x9c
end if
INTCON.GIE=1
INTCON.PEIE=1
end sub

main:
ANSEL = 0 ' Configure AN pins as digital I/O
ANSELH = 0
Lcd_Init() Lcd_Cmd(_LCD_CLEAR) Lcd_Cmd(_LCD_CURSOR_OFF)
trisb.5=1
portb.5=0
INTCON=0xC8 ' GIE=1, PEIE=1, RBIE=1
WPUB.WPUB5=1 ' Weak Pull-Up on pin B5
IOCB.IOCB5=1 ' PIN RB5 JE ULAZ
OSCCON.IRCF2=1
OSCCON.IRCF1=1
OSCCON.IRCF0=1
T1CON=0x01 ' TMR1GE=0 T1CKPS1=0, T1CKPS0=0 TMR1CS=0 TMR1ON=1
CM2CON1.T1GSS=1 ' broje se signali s rb5
TMR1H = 0xff
TMR1L = 0x9c
PIE1.TMR1IE=1
PIR1.TMR1IF=0
CNT=0
CNT_STARI=0
while TRUE
wordtostr (CNT, CNT_str)
lcd_out (1,1, CNT_str)
wordtostr (CNT_STARI, CNT_STARI_str)
lcd_out (2,1, CNT_STARI_str)
wend
end.
User avatar
pedja089
Administrator sajta
Administrator sajta
Posts: 7871
Joined: 20-02-2007, 14:50
Location: Beočin -Srbija

Re: Mjerenje širine signala pomoću Tajmer0

Post by pedja089 »

Ne vidim nista da mi zapinje za oko...
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Mjerenje širine signala pomoću Tajmer0

Post by Black »

Ne razumijem se u pic nikako, ali mjerenje signala pomoću interupt timera mi se nikako ne sviđa.
Npr na atmelu(atmega) ulaz i izlaz iz interupt funkcije traje 100 uS, cak i kad se radi o overflow.
Prilikom ispisa na LCD ili bilo gdje taj interupt može prekinut i sve zajebat.
Ne volim to kad program može napravit sranje u pozadini bez mog dopuštenja.
Rješenje koje ja koristim: provjeravaj dali je pin promjenio stanje, ako je resetiraj timer. Kod ponovne promjene stanja uzmi vrijeme timera i tek onda ispisuj, računaj i šta je sve potrebno
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Black, hvala na savjetima, ali niako ne uspijevamto uraditi. Imaš li koji kod kao primjer?
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Mjerenje širine signala pomoću Tajmer0

Post by Maki »

Možda malo glupi savijet, ali da izbaciš npr. u glavnoj petlji ovaj dio sa ispisom na LCD i da jednostavno staviš jedan if gdje ćeš ispitivati je li npr. CNT>360, ako je npr. neka toggla ledicu na nekom pinu. Na taj način eliminiraš LCD i pretvorbu u string.
Ako imaš osciliskop u prekidnu rutinu si stavi dvije ili tri satus ledice, odnosno za svaki if, npr. kad program uđe u neki if iz prekidne petlje upali ledicu, a po izlasku ju ugasi, također to možeš napraviti i sa samom prekidnom petljom. Na taj način ćeš imat malo bolji uvid u samo izvođenje programa.
Nisam skužio, ali jel si si osigurao preljevanje varijable cnt? Npr. ako ulazni signal ne postoji, hoće li se ona samo uvečavati dok ne dođe do preljeva ili?
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Pokušao sam i Makijev savjet, ali i dalje nikakvog pomaka.
Kukinjos, možeš li i ti malo pogledati moj kod? Prošli puta si "jednim potezom pera" riješio problem. Već sam očajan, ovo je treći mjesec rada, a nikakav pomak.
hvala svima na pomoći i savjetima do sada.
jazz
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 207
Joined: 21-10-2010, 21:18
Location: Hrvatska

Re: Mjerenje širine signala pomoću Tajmer0

Post by jazz »

Ostavi se LCD-a i ispisa. Stavi 3 diode, crvenu, zelenu i žutu.

Neka se crvena pali (unutar interapt-a) kad signal na ulazu ode gore (1), a ugasi kad signal na ulazu ode dolje (0).

U glavnom programu usporedi rezulat mjerenja sa očekivanim. Npr, po tvome proračunu sa test ulaznim signalom, kao rezultat program bi trebao dati vrijednost 400. Ako je izračunata vrijednost manja od 350 upali žutu, a ako je izračunata vrijednost veća od 450 upali zelenu. Ako je rezulat između 350 i 450 obe LED (žuta i zelena) bi trebale biti ugašene.

Kada dođeš do toga da ti program daje kao rezultat očekivanu vrijednost, odnosno da program radi OK, onda dodaj LCD ispis, i vidi dali postoji možda kakav problem vezan us to. Prilikom LCD ispisa trebalo bi ugasiti interupt i mjerenje.

EDIT: U 3 minute sam našao ovo...
http://microcontrollerslab.com/pulse-wi ... ontroller/
I mogu se kladit da na net-u postoje bar 10 različitih primjera sa source-om koji rade kako treba.
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Pozdrav jazz,
hvala na prijedlozima, ali me nešto zanima. U svim pronađenim primjerima radi se o mjerenju vremena između uzlazne i silazne ivice signala, a u tom slučaju treba uključiti i komparator. Ali koliko sam je razumio Timer1, on bi trebao izmjeriti dužinu signala i bez komparatora. U primjeru koji si mi predložio na skici je vidljivo kako je signal doveden na dva pina paralelno (na RC1 i RC2). Je li to ispravno?
Da, poslušao sam te i uključio sam LED u interrupt rutinu, međutim uključenje i isključenje je tako brzo da se i ne primjeti. Ja nikako ne mogu dobiti željenu rezoluciju 50 us. To ja vidim kao najveći problem, jer ako program izbroji dužinu signala od 15 do 27 (trebao bi izbrojati i 390).
Program iz primjera ću pretvoriti u MB i onda vidjeti.
imam dva pitanja :
- što znači "double MPH"
- t2 = t2 + (TMR1H<<8)|(TMR1L); // Store values for 2nd capture
Pozdrav
jazz
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 207
Joined: 21-10-2010, 21:18
Location: Hrvatska

Re: Mjerenje širine signala pomoću Tajmer0

Post by jazz »

Nikada nisam radio sa PIC mikrokonrolerima, tako da nisam 100% siguran, ali kod ostalih mikrokontrolera, s kojima sam radio, rezolucija timer-a od 50 us s obzirom na 8 MHz takt procesora (i periferija) se dobije bez problema.

Da ja to sam sebi radim (na MSP430, npr), pokrenuo bi timer koji bi kontinuirano brojio od nule do $FFFF, pa opet od 0 do $FFFF, stalno, bez zaustavljanja. Kad bi signal na pin-u otišao gore, prvi interrupt bi pohranio početno stanje timera (bez zaustavljanja timera). Kad bi signal na pin-u otišao dolje, drugi interrupt bi pohranio krajnje stanje timera, i izračunao ukupno trajanje (bez zaustavljanja timera). Glavni program bi prikazivao rezultat. To na MSP430 ide bez komparatora i s jednim ulaznim pinom.

Ili bi okidao DMA, koji bi kopirao (u 2 takta) vrijednost na ulaznom pinu u RAM. Nakon što bi DMA odradio posao, program bi češljao ram dok ne nađe dvije susjedne prelazne vrijednosti $00 / $FF kao početak, i $FF / $00 kao kraj. I izračunao trajanje.

A da o svemu tome znam jako malo, onda bi detaljno pročešljao web, sa open source primjerima koji 100% rade, a slični su onome što meni treba. I onda bi taj source mijenjao u malim koracima, dok ne bi došao do onoga što meni treba.

t2 = t2 + (TMR1H<<8)|(TMR1L); // Store values for 2nd capture
To je pribrajanje trenutne vrijednosti timera vrijednosti t2 (t2 = t2 + 256 * HI + LO)
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Hvala jazz,
tako sam i ja zamislio svoj kod, ali nisam uspio. Pokušavao sam s kodovima s Neta, ali vjeruj mi, prepišem sve od riječi do slova i obrnuto, a onda veliko ništa. Tako i kod koji si mi preporučio, piše da su ulazi za signal RC 1 i RC2, a u opisu piše samo RC5. Komparator 1 u 16F887 u registru CCP1CON s četiri bita određuje da li sklop treba reagirati na porast ili pad napona na pinu. Logički je da ne treba uključivati i drugi komparator i raditi onakvu shemu kao on (jedan signal na dva pina paralelno), ali budem i to preradio, pa ako radi super. Ali već skoro tri mjeseca tražim, kopiram, prerađujem i uvijek neka greška, a autori se ne žele javiti (video na Youtube ima kod i sve radi kod njega, ali moj kod je blokiran). Pomalo ludim, kod mi starno treba i bez njega nikako ne mogu dalje , a više neznam kako.
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Mjerenje širine signala pomoću Tajmer0

Post by Black »

Ja ti jedino ovo mogu predložit pa ti kod prebaci za pic

Code: Select all

if((PIND & (1<<PD3)) == 0)     //ako je pin LOW
   {
     pick_up_stanje=0;
     pick_up_stanje_staro=0;     
   }
   else                                   //ako je pin HIGH
   {
    pick_up_stanje=1;       
   }

    if(pick_up_stanje != pick_up_stanje_staro)            //kada pin pređe sa LOW na HIGH program će ući u ovu petlju
       {
        pick_up_stanje_staro=pick_up_stanje;                //resetiraj varijable da ne ulazi u ovu petlju do ponovne promjene LOW/HIGH
        period=TCNT1;                                       //uzmi vrijeme timera u varijablu
        TCNT1=0;                                             //resetiraj timer
        racunaj=1;                                          //otvori programu put da može uć u petlju gdje će računati 
      
       }
       
  if(racunaj==1)                                             //petlja za računanje,ispis na LCD, ili šta je već potrebno
   {
    racunaj=0;                                                //kad jednom uđe u petlju ne dozvoli ulaz do ponovne promjene LOW/HIGH
    RPM=(10000000/(period*16))*6;
    Serial.print("RPM = ");
    Serial.println(RPM);
}


Dakle ne koristiš interupte, i možeš koristit pin koji hoćeš, pisao sam tu neke komentare da probaš malo pohvatt kako program radi.

Dakle imaš 3 petlje koje program stalno provjerava (arduinu je za to potrebno oko 1-2 uS)
program je tako napisan da samo kad pin prođe sa LOW na HIGH ,uzet će vrijeme i posle toga ide u petlju za računanje. I zbog toga ima vremena i greške neće bit iako ne koristi interupt.

Ja taj sistem koristim na motoru za paljenje iskre, gdje program mora raučanat i pomak faze i sve to prinatat na PC.
https://www.youtube.com/watch?time_cont ... dUDf4KX7X4


Ima još par stvari na koje moraš pazit ali o tome ćemo kasnije. Koliko bitni timer je na tom picu i na kojoj frekfenciji radi, može li mu se postavit djelitelj?
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Pozdrav Black,
tajmer1 je 16 bitni, djeljitelj je postavljen na 1:1, a koristim unutrašnji takt i on je postavljen na 8 MhZ. Iskreno, morao bi "letiti", a sporiji je od puža. Hvala na primjeru, moram ga skužiti i prebaciti u MBasic. Prvim pregledom skoro sve mi je OK, osim...
Imaš li interrupt rutinu gdje se mjeri vrijeme tajmera, jer uzimaš taj podatak u kodu?? Kako postavljaš parametre tajmera , na koju rezoluciju (mislim na djeljitelj i tejmerski registar)?
Hvala još jednom.
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Mjerenje širine signala pomoću Tajmer0

Post by Black »

Možeš li postavit djelitelj timera na 8? To bi bilo 1uS rezolucija i s ovim kodom ćeš moći mjerit signale širine do 65535 uS.(kasnije ako ti treba da možeš i duže signala mjerit)

U tijeku okidanja broj TIMERA se stavi u variablu 'period' i TIMER se resetira na 0. Posle toga tu varijablu 'period' koristiš da izračunaš uS (pomonožiš je sa 8 )

Nikakve interupte ne koristim, a koji tajmerski registar treba postavit to ti neznam kako ide na PIC-u.
Kod mene je uključen timer i ono broji normalno do kraja , kad dođe do overflowa 65535 vrati ga na nulu
majstor1
Pocetnik na forumu
Pocetnik na forumu
Posts: 47
Joined: 17-10-2014, 13:43

Re: Mjerenje širine signala pomoću Tajmer0

Post by majstor1 »

Pozdrav Black
U PIC sve to postavljaš malo drukčije, Sve sam postavio kako bi do prekoračenja tajmera dolazilo svakih 100us. Jedan od mojih signala je širok 19,7 ms ili 19700us, što bi trebalo dovesti da tajmer ima 197 prekoračenja, a svako prekoračenje registriram varijablom koja se uvećava za jedan. Ali nisam uspio. Za sada odustajem. Nemam više živaca da nastavim, možda za koji dan. Hvala svima na pomoći.
jazz
Pravo uznapredovao :)
Pravo uznapredovao :)
Posts: 207
Joined: 21-10-2010, 21:18
Location: Hrvatska

Re: Mjerenje širine signala pomoću Tajmer0

Post by jazz »

majstor1 wrote:Pozdrav Black
U PIC sve to postavljaš malo drukčije, Sve sam postavio kako bi do prekoračenja tajmera dolazilo svakih 100us. Jedan od mojih signala je širok 19,7 ms ili 19700us, što bi trebalo dovesti da tajmer ima 197 prekoračenja, a svako prekoračenje registriram varijablom koja se uvećava za jedan.
Pa zar ti ne bi bilo jednostavnije smanjiniti CLK timera, sa odgovarajućim djeljiteljem, tako da rezulat direktno dobiješ u krajnjoj vrijednosti timera, a ne da radiš sa prekoračenjima i uvećavanjem za jedan? Pustiš timer na izlazni pin i izmjeriš frekvenciju, da si 100% siguran kojom brzinom broji.
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Mjerenje širine signala pomoću Tajmer0

Post by Black »

majstor1 wrote:Pozdrav Black
U PIC sve to postavljaš malo drukčije, Sve sam postavio kako bi do prekoračenja tajmera dolazilo svakih 100us. Jedan od mojih signala je širok 19,7 ms ili 19700us, što bi trebalo dovesti da tajmer ima 197 prekoračenja, a svako prekoračenje registriram varijablom koja se uvećava za jedan. Ali nisam uspio. Za sada odustajem. Nemam više živaca da nastavim, možda za koji dan. Hvala svima na pomoći.
To ti i je problem krivi pristup, svakoh 100uS još dobiješ toliko greške kod prekoračenja. Postavi timer da ide do kraja
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Mjerenje širine signala pomoću Tajmer0

Post by Black »

I nemoj odustajat, na tisuće ljudi je uspjelo to što pokušavaš zašto nebi i tebi
Post Reply