Parallella processer med PIC

Elektronikrelaterade (på komponentnivå) frågor och funderingar.
Anders Johansson
Inlägg: 7
Blev medlem: 18 september 2012, 19:56:40

Parallella processer med PIC

Inlägg av Anders Johansson »

Jag är sugen på att börja med PIC-programmering och har fått en oanvänd programmerare (PICkit 2) av en kompis.

Det var årtionden sen jag programmerade men lite C-kunskaper finns det nog kvar. Assembler har jag också kört lite.

Hur fungerar dagens PIC - kan de hantera parallella processer? Kan man tex ha en process som gör något, tex läser av en ingång, varje sekund och ha en annan process som gör något baserat på tidigare avläsningar? Jag minns att när jag tidigare programmerade enkla microprocessorer i assembler så var man tvungen att räkna hur mycket tid varje kommando tog och lägga loopar för att fylla tiden till en regelbunden avläsning. Är det historia med PIC?

Funkar den C-kompilator som finns gratis från Microchip att börja med?
Användarvisningsbild
Klas-Kenny
Inlägg: 11865
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Parallella processer med PIC

Inlägg av Klas-Kenny »

Så som du beskriver det, ja det går absolut!

Det bästa sättet att göra någonting sådant är att ha en timer med interrupt, så vid varje sekund ges interrupt och processorn går på rutinen för att läsa den där ingången, sen fortsätter den där den var.
Edit: Alternativt att man kör timer men utan interrupt, och när man har "lite tid över" så att säga så kollar man om det gått en sekund, och i så fall läser man ingången. Kan vara bra om man har en tidskritisk rutin i övrigt som inte kan bli avbruten när som helst. Men kräver klart att den rutinen alltid tar mycket mindre än en sekund för att det inte ska komma helt ur fas.


Skulle inte vilja påstå att PIC är historia, visst, 8-bitars processorer överlag ersätts ju allt mer av stora 32bitare, men man kan fortfarande göra väldigt mycket med en liten PIC.
Sen så är det dessutom i min mening betydligt lättare att börja med dessa små. När man kan dem hyggligt, ja då kan man ta steget upp till ARM eller PIC32 eller annat. Annars blir inlärningskurvan rätt hög.

Jadå, Microchips egen C-kompilator fungerar alldeles utmärkt.
Användarvisningsbild
MadModder
Co Admin
Inlägg: 31639
Blev medlem: 6 september 2003, 13:32:07
Ort: MadLand (Enköping)
Kontakt:

Re: Parallella processer med PIC

Inlägg av MadModder »

Jag tror han menar att det sätt han programmerade med i assembler där man är tvungen att räkna alla cykler alla instruktioner tog för att få ett jämnt flöde är historia iom övergång till PIC.
Det går utmärkt att programmera PIC på precis samma sätt. Man kan nog inte överge den tanken ändå. Såvida man inte använder inbyggda funktioner som kan finnas i kretsen som t.ex PWM så tar ett interrupt tid och resten står still medan detta utförs.
blueint
Inlägg: 23238
Blev medlem: 4 juli 2006, 19:26:11
Kontakt:

Re: Parallella processer med PIC

Inlägg av blueint »

Interrupt kan gott användas för att få en jämn sampling. Annars finns ju alltid timers och kooperativ multitasking dvs man kör en rutin lite grann, sedan nästa, osv innan man börjar om. På det sättet blir alla bitar utförda jämnt över tiden,
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Parallella processer med PIC

Inlägg av sodjan »

> Hur fungerar dagens PIC - kan de hantera parallella processer?

För att ha verkligt parallella processer behöver du en multi-core
processor eller flera processorer som jobbar tillsammans. Men det
är nog inte det som du menar, eller hur?

När det gäller att göra flera olika saker (dock inte samtidigt) så
finns det ingen teknisk gräns, du kan göra så mycket som den
aktuella processorn hinner med. Det kan vara hundratals "saker"
om bara var och en inte tar för mycket resurser.

Och detta har ingenting med, eller är specifikt för, PIC på något sett.

> Kan man tex ha en process som gör något...

Det finns inga "processer" enligt den vanliga betydelsen från
större system där man även har ett operativsystem "i botten".
Kalla det istället för uppgift eller funktion, så leder inte tanken
fel av misstag.
Anders Johansson
Inlägg: 7
Blev medlem: 18 september 2012, 19:56:40

Re: Parallella processer med PIC

Inlägg av Anders Johansson »

Tack för alla svar! Som vanligt inser jag att min förmåga att ställa tydliga frågor är begränsad... :-)

Jag tar ett exempel:
Jag har en insignal som ska "bevakas". Den har normalt 0V men kan när som helst växla till matningsspänningen. Så fort signalen går hög vill jag att kretsen ska upptäcka det och då slå på en fyrkantsvåg på låt oss säga 10 Hz på en utgång. Utsignalen ska ge fyrkantsvågen under hela tiden ingången är hög och i ytterligare 2 sekunder när ingången går låg. Om ingången återigen går hög inom två sekunder ska utsignalen fortsätta att vara aktiv till två sekunder efter att ingången åter går låg. Hängde ni med?

Exemplet innebär alltså att jag måste hålla koll på en ingång hela tiden och också "hålla takten" på utgången samtidigt. Plus att jag ska hålla koll på 2s efter att ingången gått låg.

Som jag minns det från min tidiga karriär med kretsprogrammering i skolan var det ett eländigt räknande av tidsåtgång vid varje avbrott och det skulle definitivt göra att jag tappade takten på min 10 Hz-signal i exemplet. Slipper jag det om jag kör C och en PIC ur 16F-serien?
Användarvisningsbild
Icecap
Inlägg: 26698
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Parallella processer med PIC

Inlägg av Icecap »

Sedär, nu kan man faktisk ge ett svar som duger.

Lösningen är Interrupt-On-Change (IOC), en funktion som finns på en hel del(/alla?) PIC. Och grejen är att du inte behöver bevaka något alls...

Steg 1: Ställ in portar och funktioner som ju alltid ska göras.
Steg 2: Läs porten som används som input, detta nollar IOC.
Steg 3: Använd värdet som läsas för att ställa utgången rätt.
Klart med startdelen.

Sedan skapar man en interrupt-funktion som avkänner när IOC sker. I den ISR (Interrupt Service Routine) ska följande ske:
A: Läs porten för att veta vad som ska ske SAMT för att nolla IOC.
B: Slå på eller av genereringen av fyrkantvågen.
Klart.

På detta sätt kan hårdvaran i PIC'en "övervaka" och se till att en interrupt utlösas när det sker en ändring av ingångssignalen.

Självklart kan detta utföras på många andra sätt, ett ganska vanligt sätt är att låta en timer ge interrupt med regelbundna mellanrum, t.ex. 100 gg/sek. I timerns ISR kollas då ingången och styrs utgången efter vad som behövs - och det kan såklart vara många saker som kollas och styrs, gemensamt för dom är dock att man ska avklara deras del snabbt och effektivt!
Nerre
Inlägg: 27300
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Parallella processer med PIC

Inlägg av Nerre »

Det känns lite som att det är lite brist på förståelse för hur en dator eller mikroprocessor fungerar.

Som redan skrivits så för att kunna ha "äkta" parallella processer så behövs flera processorkärnor eller flera CPU:er.

Men det som är beskrivet är snarare "trådhantering", d.v.s. att processorn växlar mellan olika små rutiner "vid behov".

Detta "vid behov" är väl nästan uteslutande styrt av interrupt (annars krävs alldeles för hög diciplin hos processerna att de ska lämna ifrån sig kontrollen med jämna mellanrum).


Så, för att summera: Du kan skriva kod som "ser ut" som om den gör flera saker parallellt, men egentligen görs inte sakerna parallellt utan de turas om (men med så låg latens att det kan ses som att de körs parallellt).

Det är ungefär som GSM, en basstation kan ha flera samtal igång samtidigt, men egentligen är det bara ett samtal åt gången men de delar på tiden (varsin tidslucka).
Användarvisningsbild
jesse
Inlägg: 9241
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Parallella processer med PIC

Inlägg av jesse »

När man ska generera en utsignal med en viss frekvens så är det väldigt lämpligt att använda en inbyggd timer i processorn. t.ex. en 8 bitars timer kan räkna från 0 till 255 och börjar om igen på noll. Timern kan programmeras till olika frekvenser (beroende av processorns klockfrekvens) och att den skapar ett TIMER-OWERFLOW-INTERRUPT varje gång den börjar om på 0. Det går också att programmera timern att slå om vid ett godtyckligt värde, t.ex. när den räknat till 175.

Om du har en processorklocka på 8,0 MHz , programmerar timern att öka med ett var 64:e klockpuls, så kommer den att ha räkna upp 125000 ggr/sek. Låter man timern räkna till 125 kommer det att gå exakt 1ms mellan omslagen. Dessa kan fångas upp i en interrupt med stor exakthet (ofta med omkring 1-4 klockcykler noggrannhet, dvs. ca 125 till 500 nanosekunder variation, beroende på hur man utför programmet i övrigt).

Inuti detta interrupt kan man lämpligtvis låta räkna upp en räknare från 0 till 49 - när den slår om till 50 nollställs den och man "togglar" den utgång man vill ska ge 10 Hz, med villkoret att en viss flagga är ställd. (En "flagga" är här en vanlig global variabel som kan anta två tillstånd, 0 eller icke-0. ) Nu kommer utgången att ändra värde exakt var 50:e ms.

I samma interrupt kan du - beroende på vissa villkor - låta räkna upp en timer som går till 2000 - dvs. 2 sekunder. Denna nollar din 10Hz_on_off flagga när den nått 2000.
På så vis kan du använda samma timer (och samma interrupt) till att både generera en (eller flera) utsignaler med olika frekvenser och att skapa klockor som håller koll på tider mm.

Flaggan sätter du till etta någon annastans i programmet när din insignal är rätt. 2000ms-räknaren nollställs när insignalen upphör.

Nu när du har tidbasen färdig i ditt interrupt är det enkelt att göra en klocka: Du använder 4 variabler: millisek, sek, minut och timme.
I interruptrutinen räknar du upp millisek. När den når 1000 nollas den och du räknar upp sek med ett. Vid 60 nollas den och du räknar upp minut. Vid 60 nollas den och du räknar upp timme. Vid 24 nollas den och du räknar eventuellt upp en variabel som heter 'dag' om du vill hålla reda på datum.

I det här programmet händer så få saker att du i princip inte behöver göra någonting utanför denna 1ms - interrupt. Men ju mer du ska göra desto bättre är det att dela upp det hela i olika funktioner som utförs vid vissa tidsintervall. Enklast är då att låta interruptrutinen sätta en flagga med jämna intervaller, t.ex. 100 ggr/sek. I huvudprogrammet kollar man hela tiden dessa flaggor, och när en viss flagga är etta så utförs motsvarande funktion. Detta blir inte lika exakt i tiden som om det gjordes direkt i interruptrutinen - det beror på vad för uppgifter som utförs när interruptet sker.

(Jag kan inte ge några kodexempel, då jag inte jobbar med PIC-processorer)
Senast redigerad av jesse 8 september 2013, 11:26:46, redigerad totalt 3 gånger.
Anders Johansson
Inlägg: 7
Blev medlem: 18 september 2012, 19:56:40

Re: Parallella processer med PIC

Inlägg av Anders Johansson »

Jag är nog ganska med på att en processor bara gör en sak i taget, däremot funderar jag på hur man hanterar parallella uppgifter, i detta fall då man programmerar PIC mha C.

Det jag fastnade var just hur bökigt det blir att få en utgång att producera en perfekt (nåja) fyrkantvåg med rätt frekvens trots att jag måste hantera andra saker "parallellt". Jag vill ju inte senarelägga utgångens skifte från 0 till 1 ett par klockcykler bara för att kontrollen av ingången upptäckte en förändring och ägnar ett par cykler åt att tex sätta ett register till ett visst värde.
Användarvisningsbild
jesse
Inlägg: 9241
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Parallella processer med PIC

Inlägg av jesse »

Ett par klockcykler i det här sammanhanget är i princip försumbart!

Måste du vara mer exakt än så måste du nog generera din frekvens direkt från en timer utan inblandning av processorn alls.
Det går att göra eftersom PIC-timers är ganska flexibla och kan programmeras till att toggla en utgång automatiskt.
Användarvisningsbild
Icecap
Inlägg: 26698
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Parallella processer med PIC

Inlägg av Icecap »

Anders: så länge frekvensen som ska genereras (i detta fall) är hög nog är det sånt man överlåter till CPP-enheten. Den är gjort just för att skapa PWM med lämplig frekvens och man ställer in rätt parameter och sedan kan den sköta sig själv utan ytterligare inblandning.

Så totalt sett är övervakningen begränsat till att starta allt i rätt läge och sedan enbart låta PIC'en reagera på ändringar - och dessa ändringar blir avklarat snabbt och effektivt, förutsatt att du inte är alldeles för klantig när du skriver programmet.

Reaktionstiden på en förändring beror ju såklart på vilken klocka PIC'en kör med men är det tal om 10Hz frekvens ut lär det bokstavligen vara försumbar.

Det känns mest som att du inte har använd interrupt-funktionen tidigare men bara kört top-to-bottom assembler programmering tidigare, inget fel i det men de moderna kretsar och deras möjligheter kombinerat med en vettig kompiler för t.ex. C gör det mesta en del enklare.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Parallella processer med PIC

Inlägg av sodjan »

> ...i detta fall då man programmerar PIC mha C.

Det har ingenting med C att göra. Man gör i princip på samma
sätt helt oavsett vilket "språk" man sedan väljer att använda.

> Jag vill ju inte senarelägga utgångens skifte från 0 till 1 ett par klockcykler...

Varför inte? Vad får det för praktiska konsekvenser i just det fall.
Notera att vi talar om avvikelser på några tiotals ppm.

> ...en perfekt (nåja) fyrkantvåg...

Och vad *exakt* betyder "nåja" här? Det är ju av helt
avgörande betydelse för att förstå dina krav. Hur mycket
får din fyrkantssignal avvika från det nominella? Notera att
10 Hz är en ganska låg frekvens, en PIC med intern osc på
32 MHz utför (om jag räknar rätt i hastigheten) 400.000 inst. cykler
under en halvperiod av signalen. Du måste förklara vilka konsekvenser
det får om det ibland blir t.ex 400.005 eller 400.010 cykler.

En annan sak är om det viktiga är att det är 10 Hz stabilt i snitt
över en tid eller om varje cykel i sig måste vara stabil.

> Så fort signalen går hög vill jag att kretsen ska upptäcka det...

Det är samma problem här, vad betyder "så fort...". Du behöver ha en
uppfattning om vilken fördröjning som är acceptabel. Kan du t.ex vänta
lika länge som en halv period av 10 Hz signalen? Jag menar, det blir
ju i alla fall ingen ändring på signalen tidigare än så!

Om vi antar att det är OK, så behöver du enbart en "bas-klocka" i systemet
som tickar på med 50 ms. Varje "tick" så gör du följande:

- Kollar insignalen.

- Om pinnen är "hög" så sätter du en flagga "signal-on" och en "timeout" räknare till 40 (40 * 50 ms = 2 sek).

- Om pinnen är "låg" och "signal-on" är "hög" minskar du timeout räknaren med 1.
- Om timeouträknaren blir 0 sätter du "signal-on" flaggan "off".

- Om "signal-on" flaggan är "hög" så togglar du utgången.

Det är allt.

> Anders: så länge frekvensen som ska genereras (i detta fall) är hög nog
> är det sånt man överlåter till CPP-enheten.

Jag är inte helt säker på att 10 Hz går att generera via CPP/PWM modulen.
Ett sätt är att gå ner i frekvens på processorn i sig. Men sannolikt är det
enklast att ta det i timer-ISR'en vid en så låg frekvens.

Som sagt, om fördröjningen kan vara lika med en halvperiod av 10 Hz signalen
så blir det hela enbart en enda timer-ISR där allt hanteras enligt ovan. Ingen
separat ISR för ingången behövs.
Skriv svar