Sida 1 av 4

Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 19:24:59
av Magnus_K
Hej hej,

Visste inte riktigt vad jag skulle döpa tråden till. Kanske får ändra senare.

Får börja med att säga att detta verkligen är nybörjarnivå vilket antagligen kommer innebära att frågeställningen kan bli lite fel. Jag gör ett försök så får vi se om ni förstår vad jag frågar efter.

Information:
Microcontroller: PIC12F1840 (datablad)
Kompilator och IDE: Mikroelektronika MikroC for PIC

Mål:
Att på snabbaste möjligaste sätt sätta en digital utgång låg när en analog ingång når ett visst tröskelvärde

Fråga:
Jo, det låter nog simpelt för er men jag måste få lite djupare förståelse för vad som händer egentligen samt hur man kan "snabba upp" koden. Just nu gäller just detta lilla exempel men imorgon kanske det är något annat och då vill jag redan från början tänka rätt.
Som jag hade gjort idag så hade jag skrivit så här:

Kod: Markera allt

if(analog > 500) {
PORTA.RA0 = 0;
}
Det kanske inte finns så mycket man kan göra för att detta ska utföras på ett snabbare sätt?
Det jag kan tänka mig påverkar exekveringstiden är klockfrekvens och om det finns någonstans hur ofta controllern uppdaterar det analoga värdet?

Vore tacksam om ni kan tipsa om snabbare sätt att utföra ovan? Kanske genom assembly-kod? Interrupts?

EDIT: Ändrat databladslänken till senaste version

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 19:33:40
av Icecap
Detta exempel beror ju definitivt på AD-omvandlarens hastighet som är flaskhalsen.

Men i essens låter man AD-omvandlaren utföra en omvandling och sedan ska den ge en interrupt när den är klar. I den interrupt-rutin lägger du in denna if(analog > 500) PORTA.RA0 = 0;

Snabbare än så lär det inte gå. Självklart kan man nog tweaka ett par cykler vid att jämföra på ett smart sätt - men det ändrar inte fakta: AD-omvandlingen tar definitivt den längsta tiden varför den del kan tweakas med extern hårdvara för att snabba upp det hela.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 19:35:14
av Klas-Kenny
Processorn har en inbyggd komparator, den kan nog med fördel användas om man behöver snabbhet. :)

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 19:47:50
av Magnus_K
Det var snabba och mycket intressanta svar!

Hur kan man påverka AD-omvandligens hastighet annat än klockfrekvens? Tänkte på typ upplösning eller något...
Som ni förstår så har jag ganske lite förståelse om vad som verkligen händer här...

Ska läsa ikväll om komparatorn och se om jag blir lite klokare.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 20:01:38
av Icecap
AD-omvandlaren kan inte gå fortare än den kan! Höjer du klockfrekvensen ska man oftast sänka den igen i prescalern, helt enkelt för att AD-omvandlaren behöver en viss tid.

Vad man kan reglera på är setup-tiden, alltså hur lång tid den behöver för att "läsa in" värdet som ska omvandlas. Man kan (bör) ha en kondensator på den analoga ingången för att medge att setup-tiden kan sänkas lite.

Sedan tar själva omvandlingen en viss tid, denna tid framgår av databladet och där kan man se till att tider och klockfrekvenser går upp i en större helhet så att omvandlingen går snabbast möjligt utan att för den delen pressas för hårt.

Sedan tar en jämförelse med ett 16-bitars tal en viss tid på en 8-bit processor, den kan nog klämmas ner en lite bit vid att (om det nu går) att jämföra med en byte och då strunta i lägsta bitarna. Självklart kan detta bara ske om man kan placera bitarna rätt per automatik, ska man shifta dom på plats är det en ren tidförlust att börja med detta.

Så steg 1A är att läsa databladet och få för sig kristallklart vilka sekvenser som behövs för att AD-omvandlaren ska kunde utföra jobbet rätt, notera tider, räkna mot klockan osv. Ta en funktion åt gången, trilla in den så att den är "perfekt" och ta nästa steg.

På detta sätt kan du räkna ut tiden mellan varje omvandling och kontrollera om det räcker i snabbhet.

I ISR-delen startar du först om AD-omvandlaren (om den inte kan göra det automatisk), sedan kollar du värdet och till slut rensar du interrupt-flaggan.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:00:50
av Magnus_K
Vilket kanon-svar!

Förstår databladet mycket mer nu efter din beskrivning. Det nämner också "holding capcitor" som du sa samt rekommenderade klocktider.
Som jag förstår det så kan man få ner en Tad (ADC klockperiod) till 1µs och med en 8-bitars omvandling tar det ca 9,5 µs för omvandligen.
Precis som du säger kan man också få en interrupt-flagga när omvandligen är klar.
Icecap skrev: I ISR-delen startar du först om AD-omvandlaren (om den inte kan göra det automatisk), sedan kollar du värdet och till slut rensar du interrupt-flaggan.
Jag ska då alltså; i denna interruptfunktion lägga min if-sats och sedan rensa flaggan? Förstår jag dig rätt då? Eller ja, du skrev ju så i ditt första inlägg...

@Klas-Kenny:
Det var också ett väldigt bra tips!
Läste på lite om det nu och använda en komparator verkar gå snabbare men om den är tillämpningsbar i mitt fall vet jag inte ännu.

Tack för hjälpen till er båda!
Det här ska bli kul att försöka få till! Tyvärr brukar det sluta med en pungspark ändå då det inte är lika lätt att verkställa för en annan...

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:20:50
av sodjan
> Information:
> Microcontroller: PIC12F1840 (datablad)

Din länk går till ett gammal version (och dessutom via en Google länk).
Bättre att *alltid* plocka det direkt från källan:
http://www.microchip.com/PIC12F1840
Ditt är rev B från 2011 och det aktuella är rev E från maj 2014.

> Det nämner också "holding capcitor" som du sa...

Den som databladet nämner är den interna kondensatorn som håller
spännigen in till omvandlaren under omvandlingen. Det som Icecap
talar om är en extern extra kondensator för att stabilisera spänningen.

> och med en 8-bitars omvandling

Alla omvandlingar är alltid 10 bitar. Sedan behöver man inte använda alla bitar.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:23:11
av sodjan
Men som sagt, ska du enbart bevaka en extern spänningsnivå så kan
det vara enklare att använda komparatorn, speciellt ihop med FVR.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:33:43
av Nisse
Ska PICen göra något mer?
Annars kanske det är bättre att använda en operationsförstärkare kopplad som komparator.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:38:43
av Magnus_K
Uppdaterade länken i första inlägget. Det gick lite fort och fel när jag skulle skriva inlägget.

Då förstod jag fel angående kondensatorn. Tack för förtydligandet. Är inte färdigläst om det här ännu så förhoppningsvis går det upp ett par ljus under kvällen. Å andra sidan minns jag nu att detta nämnts som rekommendation i någon annan tråd.

Ahaaa, just det... Dessa 10 bitar (i detta fallet) omvandlas alltid och sätts in i ADRESH:ADRESL registren, sen väljer jag hur många bitar jag vill "hämta".

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:47:25
av victor_passe
du kan formatera på 2 vis, ena är "till" för att hämta de 8 överta bitara och andra för att hämta alla data.
Om du bara tar de över 8 så kan du köra if(reading>125) istället. Då räcker det att bara läsa en byte.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:52:10
av Magnus_K
@Nisse: Det var också ett kanonförslag (tror jag). Det kanske blir en "extern" lösning för att få ner tiden.

Sanningen är väl den att jag tänkte göra något som ni bara kommer sucka åt och säkert kan svaret på direkt men för mig är inte resultatet det viktiga utan hur mycket man kan lära sig på vägen. Jag har MYCKET att lära mig.

På min att-göra-lista står nu:

* Sätta upp ADC:n och skriva ihop en fungerande interrupt (aldrig gjort något av dom)
* Konfigurerar en komparator i PIC:en och även här testa med interrupt (aldrig gjort något av dom)
* Läsa på om hur man kopplar op-amp(s) som en komparator och "ta vara på signalen" (har inte hunnit tänka/läsa så mycket sen du skrev det)

och nu till dräparslaget som jag inte velat nämna för att bli idiotförklarad: Kan man få den här funktionen att gå så snabbt så en LED/halvledare inte hinner "brinna upp" vid en kortslutning/överström. Antagligen inte men då har jag lärt mig en del på vägen.

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:57:34
av Magnus_K
@victor_passe: Ja just det, så blir det ja. Jo jag hade tänkt att strunta i de två LSB's (hoppas det var det du menade?).

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 21:57:57
av Nisse
Ingen idiotförklaring nödvändig :D
Självklart kan du få förloppet tillräckligt snabbt. Det du vill bygga är alltså en microprocessorstyrd strömbegränsning/reglering?

Re: Hur gör man en snabb funktion i C?

Postat: 23 juni 2014, 22:01:08
av Magnus_K
Exakt :tumupp:
Tänkte använda ovan nämnda metoder för att mäta spänningen över ett shunt-motstånd och därifrån slå av/reglera matningen. Har inte kommit så långt än utan har en hel del framför mig som du ser.
Och ja, var lite orolig för "pust, stön och stånk" men nu är det gjort!