Vill göra en varvräknare av PIC...

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Användarvisningsbild
dadde
Inlägg: 177
Blev medlem: 25 oktober 2007, 11:02:27
Ort: Töreboda
Kontakt:

Vill göra en varvräknare av PIC...

Inlägg av dadde »

Som vanligt har jag många ideer men den här gången har jag tagit mig lite vatten över huvudet;
Jag kan nämligen nästan ingenting om PIC:ar
Dock är jag lite kunnig innom språket C++ vilket jag antar är likt C?
Jag kan iaf lite av grunderna :D

Jag hade iaf tänkt mig göra en varvärknade med en PIC16F628, en hallgivare och typ 10 lysdioder.

En magnet kommer placeras på grejen jag ska mäta varvtalet och hallgivaren kommer då sitta och ge en puls/varv.

Varvtalen som jag vill mäta är ca 1500-2500 varv/minut vilket inte borde vara några problem.

En antalet varv överträffar 1500 rpm så skall den första lysdioden tändas och sedan en lysdiod/1000varv upp till 2500.

Problemet är att jag inte har en aning om hur man skall skriva programmet;
måste man definera in/utgångarna på något sätt?
Hur får jag en räknare att trigga när hallgivaren ger en puls?
Hur får jag PIC:en räkningen att resetta sig efter en viss tid för att sedan ränka ut hur många varv det blir / minut?
Hur får jag PIC:en att tända lysdioder på utgångarna?

Finns det någon smidig guide för nybörjare?
Har letat som en galing men har inte hittat något vettigt :/
Användarvisningsbild
RasmusB
Inlägg: 1006
Blev medlem: 24 augusti 2006, 23:32:13
Ort: Södertälje

Inlägg av RasmusB »

Finns massor om du googlar runt lite.

Däremot skulle jag rekommendera att du börjar programmera i assembler i början, det blir lättare att förstå vad som händer då.
Vill också rekommendera en djupdykning i databladet till processorn, där finns det allra mesta du behöver veta :)

Lycka till!
EEPROMdanne
Inlägg: 1155
Blev medlem: 30 oktober 2007, 09:39:59
Ort: Söderköping

Inlägg av EEPROMdanne »

EDIT: Hittade en länk...Var det något sånt här du menade?
http://www.jetronic.se/Led_varvraknare.htm
Senast redigerad av EEPROMdanne 27 oktober 2009, 19:51:27, redigerad totalt 1 gång.
Användarvisningsbild
Icecap
Inlägg: 26801
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Att lösa problemet är inte så svårt men först steg först: GLÖM C++!!!

Jag kör själv C++, ANSI C, assembler osv. och till detta är det assembler som gäller.

På en PIC finns det en CCP-enhet, den kan fånga "händelser" (pulser) i tid vid att en räknare kör på med inställd frekvens och Capture-enheten sparar "tiden" i ett register när det kommer en (valfri) flank på en ingång.

Då vet du tiden mellan 2 pulser:
Tid_mellan_pulser = Tiden_Nu - Tiden_Då;
Sedan kopierar man ner såhär:
Tiden_Då = Tiden_Nu;
då kommer den att vara klar till nästa puls.

Sedan kan du köra en helt vanlig:
if(Tid_mellan_pulser < X1) Tänd_LED1;
else Släck LED1;
if(Tid_mellan_pulser < X2) Tänd_LED2;
else Släck LED2;
osv. osv.

X1 och X2 (och X...) är konstanter du räknar ut baserat på räknefrekvensen osv. Timern ger interrupt vid overflow, den kan du använda till att utöka räknarens antal bits vid behov.
xobx
Inlägg: 196
Blev medlem: 14 juni 2007, 13:46:43
Ort: Där borta

Inlägg av xobx »

Snor tråden lite,
kan CCP-enhet användas på vilken IO pin som helst eller finns det en speciell för just detta?
eriikh
Inlägg: 258
Blev medlem: 5 maj 2006, 10:52:15

Inlägg av eriikh »

Det är (oftast) en speciell, titta i databladet.
Användarvisningsbild
bengt-re
EF Sponsor
Inlägg: 4829
Blev medlem: 4 april 2005, 16:18:59
Skype: bengt-re
Ort: Söder om söder
Kontakt:

Inlägg av bengt-re »

Det är en eller två pinnar på 16F serien iaf, kanske har blivit mer spritt på nyare PICár, men på gamla goa 16F876A så är det RC1 och RC2 som är kopplade till CCP, men som sagt - läs databladet på den pic du tänkte använda.
Användarvisningsbild
dadde
Inlägg: 177
Blev medlem: 25 oktober 2007, 11:02:27
Ort: Töreboda
Kontakt:

Inlägg av dadde »

Tack för hjälpen grabbar!
Har pluggat på databladet och börjat förstå hur jag skall gå tillväga...
Har börjat lite lätt att skapa ett program,
Får se var jag hamnar :D
Användarvisningsbild
SeniorLemuren
Inlägg: 8767
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re:

Inlägg av SeniorLemuren »

Icecap skrev:Att lösa problemet är inte så svårt men först steg först: GLÖM C++!!!

Jag kör själv C++, ANSI C, assembler osv. och till detta är det assembler som gäller.

På en PIC finns det en CCP-enhet, den kan fånga "händelser" (pulser) i tid vid att en räknare kör på med inställd frekvens och Capture-enheten sparar "tiden" i ett register när det kommer en (valfri) flank på en ingång.

Då vet du tiden mellan 2 pulser:
Tid_mellan_pulser = Tiden_Nu - Tiden_Då;
Sedan kopierar man ner såhär:
Tiden_Då = Tiden_Nu;
då kommer den att vara klar till nästa puls.

Sedan kan du köra en helt vanlig:
if(Tid_mellan_pulser < X1) Tänd_LED1;
else Släck LED1;
if(Tid_mellan_pulser < X2) Tänd_LED2;
else Släck LED2;
osv. osv.

X1 och X2 (och X...) är konstanter du räknar ut baserat på räknefrekvensen osv. Timern ger interrupt vid overflow, den kan du använda till att utöka räknarens antal bits vid behov.
Grävde fram denna gamla tråd, Eftersom jag nu står i begrepp att bygga ett par varvräknare till mina motorer så ställer jag frågan om det verkligen måste programmeras i assembler.

Jag har inte något emot assembler, men resultatet skall presenteras på en display som även är tänkt att visa temperatur och oljetryck. Rutinen för att visa tecken på displayen har jag redan skrivit i C så det vore klart mindre arbete om man kunde använda C. Jag tänkte använda en PIC 16F887 20 Mhz för ändamålet.
Användarvisningsbild
Icecap
Inlägg: 26801
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Vill göra en varvräknare av PIC...

Inlägg av Icecap »

Såklart måste man inte det - men kommer man med C++ i PC-miljö i bakfickan kommer det att vara nära nog den enda möjlighet att lösa detta utan att gå vilse i skillnaden mellan PC-med-extremt-med-resurser och mikroprocessor.

Rent faktisk har jag löst det du behöver till så vida att jag har färdiga "mäta tid"-rutiner osv.

Kod: Markera allt

#define RPM_CONSTANT  xxx // Här ska man räkna lite, värdet beror på Timer1 frekvens. Se kommentar vid T1CON.

struct
  {
  union
    {
    unsigned char Byte[2];
    unsigned int  Word;
    } Start;
  unsigned int Previous, Difference;
  unsigned int RPM;
  } Pulse;

void interrupt(void)
  {
  if(PIR1.CCP1IF)
    {
    if(CCP1CON.CCP1M0) // If capturing rising edges
      {
      Pulse.Start.Byte[0] = CCPR1L; // Transfer the value, low byte
      Pulse.Start.Byte[1] = CCPR1H; // Transfer the value, high byte
      }
    PIR1.CCP1IF = false; // Acknowledge interrupt
    Pulse.Difference = Pulse.Start.Word - Pulse.Previous; // Calculate the difference
    Pulse.Previous = Pulse.Start.Word; // Save for next time
    }
  }

Initiera CCP:
void Initialize_CCP(void)
  {
  TRISA        =  0xEF; // All input but PORTA.4
  TRISB        =  0x08; // All output but PORTB.3
  CMCON        =  0x07; // No comparator inputs
  CCP1CON      =  0x05; // Set CCP1 to capture all rising edges and use Timer 1 as timebase
  PIE1         =  0x04; // Allow CCP1 interrupts
  PIR1         =  0x00; // Erase any latent interrupts
  INTCON       =  0xC0; // Allow interrupts
  T1CON        =  0x31; // Måste ändras för rätt frekvens men då måste man veta maximal och minimal RPM först
  }

main-Loop:
if(Pulse.Difference)
  {
  Pulse.RPM = RPM_CONSTANT / Pulse.Difference;
  Pulse.Difference = 0; // Mark as used
  }
  // Nu innehåller Pulse.RPM värdet för RPM hela tiden.
  // Man kan lägga in en timeout så att om motorn stoppas visas 0 RPM
Detta är saxat ur ett gammalt projekt och kan behöva fräschas upp lite men grunden är den samma:
I interrupt-rutinen:
* Fånga tiden för varje puls.
* Subtrahera tiden för den förra tiden för att få fram skillnaden.
* Spara den senaste tiden som "förra tiden".

I main-loop'en:
* Om skillnaden är icke-noll är det mätt en tid.
* Räkna då vilket RPM det motsvarar vid att ta en konstant och dela med tiden för skillnaden, nolla sedan skillnaden för att markera den som klar.

Då kan man skriva ut Pulse.RPM hela tiden om man vill.

Själva RM-uträkningen kan såklart utföras i själva interrupt-rutinen om man vill, det beror helt på processorkraft och vad som behövs.
Senast redigerad av Icecap 2 augusti 2012, 10:54:58, redigerad totalt 1 gång.
sodjan
EF Sponsor
Inlägg: 43289
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Vill göra en varvräknare av PIC...

Inlägg av sodjan »

> Grävde fram denna gamla tråd,

Nu har jag inte kollat alla detaljer i tråden men jag ser att det i början
talas om en PIC16F628, vilket *idag*, "5 år senare...", är lite "dated".
Det har hänt mycket på processorsidan under den tiden. En standard
processor ur t.ex 16F1xxx serien har betydligt mer resurser än 628'an.

Vad som också har hänt är t.ex att Microchip har köpt HiTech vilket
gör urvalet av utvecklingsverktyg något annorlunda ("bredare") idag.
Användarvisningsbild
SeniorLemuren
Inlägg: 8767
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Vill göra en varvräknare av PIC...

Inlägg av SeniorLemuren »

@sodjan. Jag har PICKIT2 och den klarar tydligen inte 16F1xxx serien. Skulle det vara bättre att gå på 18F2xx? Jag har några PIC 18F2550 liggandes, den finns med i listan som supportade av PICKIT2.

Jag hade från början tänkt att använda PIC16F877 men den har ju inte högre klockfrekvens än PIC16F628 så det är väl ingen stor vinning med det.

Jag tänkte använda en display som visar RPM, oljetryck, vattentemp, laddning och det kanske blir svårt att få PIC16F877 att räcka till?

@Icecap. Ett bra exempel som jag tar till mig. Kul att få lära sig

Kod: Markera allt

struct
  {
  union...
Den möjligheten har jag inte använt tidigare.
sodjan
EF Sponsor
Inlägg: 43289
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Vill göra en varvräknare av PIC...

Inlägg av sodjan »

> Jag har PICKIT2 och den klarar tydligen inte 16F1xxx serien.

Nja, inte från den integrerade "drivern" i MPLAB, men den fristående PICkit2
"applikationen" gör nog det. Sen kan man ställa in den så att den "flashar"
automatiskt så fort den finns en ny HEX fil, så det blir i princip som att köra
som vanligt i MPLAB.

http://www.microchip.com/stellent/idcpl ... e=en027813

(Se andra halvan av sidan...)

> Jag tänkte använda en display som visar RPM, oljetryck, vattentemp, laddning
> och det kanske blir svårt att få PIC16F877 att räcka till?

Nu så beror det ju lite på vad du tänker använda för "display", men om det är en
vanlig HD44780 text display eller en enkel grafisk med eget minne (så att den inte
behöver "refreshas" hela tiden) så ska det inte vara något problem. De saker du
vill visas ändras ju inte flera 100 gånger per sekund.
Användarvisningsbild
SeniorLemuren
Inlägg: 8767
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Vill göra en varvräknare av PIC...

Inlägg av SeniorLemuren »

Tanken var en vanlig text LCD 20x4
sodjan
EF Sponsor
Inlägg: 43289
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Vill göra en varvräknare av PIC...

Inlägg av sodjan »

OK. Den kan du uppdatera säkert 50-100 ggr/sek.
Men det lär ju inte behövas för att visa det du vill visa.
Skriv svar