Een duty-cycle meten met een input-capture ingang
Met de output-compare uitgangen kunnen analoge signalen worden gemaakt
via het genereren van een duty-cycle gemoduleerd
signaal. Er bestaan ook
sensoren die als uitgang een duty-cycle gemoduleerd signaal leveren,
bijvoorbeeld een temperatuursensor
van de firma SMARTEC.
Met een input-capture ingang kan een duty-cycle gemoduleerd signaal
betrouwbaar en nauwkeurig gemeten worden.
De SMARTEC temperatuursensor is verkrijgbaar in een metalen huisje
zoals ook voor transistoren wordt gebruikt, dus eenvoudig in te bouwen. De
sensor moet gevoed worden met 5 Volt, en geeft als uitgangs signaal een
blokgolf op TTL niveau. De duty-cycle van dit signaal (de verhouding
tussen de periodetijd en de tijd dat het signaal een '1' is), is een maat
voor de temperatuur. Vanwege de nauwkeurigheid, en omdat de sensor een
signaal op TTL niveau afgeeft, is deze sensor in een micro-controller
schakeling eenvoudig toepasbaar.
De temperatuursensor geeft een signaal af, waarvan de duty-cycle
gemeten moet worden. Dit betekent dus, dat er in feite twee tijden gemeten
moeten worden:
- een periodetijd, en
- de tijd gedurende welke het signaal een '1' is in één periode.
Voor het meten van tijden zijn de input-capture ingangen van de
micro-controller het meest geschikt. De sensor kan dus het beste worden
aangesloten op een input-capture ingang, bijvoorbeeld op bit2 van poort A.
De 5 Volt voeding voor de sensor is beschikbaar op de connector.
Het meten van de temperatuur komt nu neer op het meten van de
duty-cycle op een input-capture ingang.
De meting wordt gestart als het ingangssignaal van een '1' naar een '0'
gaat (een neergaande flank.) Dit is het begin van een periode van het
signaal. De tijd waarop dit gebeurt wordt onthouden. Als daarna het
signaal van een '0' naar een '1' gaat (een opgaande flank) is dit het
begin van de tijd dat het signaal een '1' is. De tijd waarop dit gebeurt
wordt ook onthouden. Als daarna het signaal weer van een '1' naar een '0'
gaat, is de periode afgelopen en kan worden uitgerekend hoe lang de
periode geduurt heeft, en hoe lang het signaal een '1' was. Dit moment is
tevens de start van een nieuwe meting.
Na de meting zijn zowel de periodetijd als de '1' tijd van het signaal
bekend, en wel in eenheden van 0.5µs. Dit moet nog worden omgerekend naar
de temperatuur die hierbij hoort.
Volgens het data-sheet van de SMARTEC sensor is de duty-cycle
afhankelijk van de temperatuur volgens de formule:
d.c. = 0.31924 + 0.00472 x Temperatuur (graden Celcius)
Hieruit volgt, dat de temperatuur is: 211.9 x ( d.c. - 0.31924)
De cijfers achter de komma moeten weggerekend worden. Dit kan door de
formule aan beide zijden met 216 (65536) te vermenigvuldigen. Er onstaat
dan:
Temperatuur x 65536 = 211.9 x ( 216 x d.c. - 20922)
Ofwel:
309 x Temperatuur = 216 x d.c. - 20922
Het getal d.c. x 216 kan eenvoudig berekend worden door de '1' tijd
van het signaal en de periodetijd van het signaal op elkaar te delen via
de 'fdiv' instructie. Deze instructie kan twee 16-bits getallen op elkaar
delen, maar vermenigvuldigt eerst het deeltal met 216 voordat het gedeeld
wordt. Dat is precies wat in dit geval nodig is.
Van dit resultaat moet dan 20922 worden afgetrokken. Wat overblijft is
een getal, dat 309 keer het aantal graden celcius is dat we zoeken. Zo
levert bijvoorbeeld een temperatuur van 25 graden een resultaat op van
ongeveer 25 x 309 = 7725. Het is eenvoudig om met deze getallen verder te
rekenen.
De frequentie van het signaal van de sensor ligt tussen de 1 en 4 kHz.
Dat betekent dat elke milli-seconde een nieuwe meetwaarde beschikbaar is.
Dat is veel sneller dan nodig zal zijn bij temperatuurmetingen. Daarvan
kan gebruik gemaakt worden door niet over één, maar over bijvoorbeeld
256 perioden te meten. De tijden die voor ieder van de 256 perioden worden
gemeten, worden opgeteld, en later wordt de som weer door 256 gedeeld. De
metingen duren dan ongeveer ¼ seconde. Dat is snel genoeg. Omdat over een
langere tijd gemeten wordt, zullen de meetwaarden beter bepaald kunnen
worden, en vanwege het middelen minder gevoelig zijn voor storingen.
Een voorbeeld van een module die gebruikt kan worden om de temperatuur
te meten met een SMARTEC sensor is hieronder gegeven.
*************************************************
* Temperatuur meting
*************************************************
* De temperatuurmeting telt gedurende 'nogtedoen' perioden van het ingangs
* signaal de periodetijden op bij 'periodesom', en de tijden dat het signaal
* een '1' is op bij 'signaalsom'. Aan het eind van elke periode wordt
* 'nogtedoen' met 1 verlaagd. Als 'nogtedoen' op 0 komt, is de meting klaar
* en worden de sommen niet langer aangepast. De vlag 'meting_aan' wordt dan
* ook op '0' gezet. Om een meting te starten moet de vlag 'meting_aan' op
* '1' gezet worden, en 'nogtedoen' moet geinitialiseerd worden op het aantal
* perioden dat tijdens de meting gesommeerd moet worden. Ook moeten de
* sommen op 0 gezet worden.
PROGRAM space
tempstart equ $
* datagebied voor de temperatuur meting
DATA space
nogtedoen rmb 1 |aantal perioden dat nog gemeten moet worden
meting_aan rmb 1 |vlag om aan te geven dat er een meting loopt
periodesom rmb 3 |som van de periodetijden
signaalsom rmb 3 |som van de tijd dat het signaal een '1' is
periodestart rmb 2 |starttijd van een periode
starttijd1 rmb 2 |tijdstip waarop het signaal een '1' wordt
* initialisatie voor de temperatuur meting
PROGRAM space
ldx #regsbeg |start het meten met een neergaande flank
bclr tctl2+regsbeg,x,edg1a
bset tctl2+regsbeg,x,edg1b
ldab #ic1f |clear mogelijke interrupt
stab tflg1+regsbeg,x
bset tmsk1+regsbeg,x,ic1i
bra tempend
* subroutines voor de temperatuur meting
PROGRAM space
******* input capture interrupt routine *******
sensorint equ $
ldx #regsbeg |laat IX op de I/O registers wijzen
* eerst de interrupt vlag op '0' zetten
ldab #ic1f
stab tflg1+regsbeg,x
* daarna uitzoeken of het een op- of neergaande flank was
brclr tctl2+regsbeg,x,edg1a,sensorint1
* als het een opgaande flank is, dan zitten we in het midden van een meting
* onthoud de tijd waarop de flank kwam
ldd tic1+regsbeg,x
std starttijd1
* en wacht vervolgens op een neergaande flank
bclr tctl2+regsbeg,x,edg1a
bset tctl2+regsbeg,x,edg1b
bra sensorint9
* als het een neergaande flank is, dan zitten we aan het eind van een meting
* het eind van een meting is tevens het begin van een nieuwe meting
sensorint1 tst meting_aan |kijk of de meting gedaan moet worden
beq sensorint4
* als de meting gedaan moet worden:
* bereken de nieuwe som van de tijd dat het signaal een '1' is
ldd tic1+regsbeg,x
subd starttijd1 |reken uit hoe lang het signaal een '1' was
addd signaalsom+1 |en tel dat op bij de som
std signaalsom+1
bcc sensorint2
inc signaalsom
* bereken de nieuwe som van de periodetijd van het signaal
sensorint2 ldd tic1+regsbeg,x
subd periodestart |reken uit hoe lang de periode van het signaal
addd periodesom+1 |was, en tel dat op bij de som
std periodesom+1
bcc sensorint3
inc periodesom
* en verlaag het aantal perioden dat nog gemeten moet worden
sensorint3 dec nogtedoen
bne sensorint4
* als er geen perioden meer gemeten hoeven te worden, is de meting klaar
clr meting_aan
* leg de starttijd van de nieuwe periode vast
sensorint4 ldd tic1+regsbeg,x
std periodestart
* en ga op een opgaande flank wachten
bclr tctl2+regsbeg,x,edg1b
bset tctl2+regsbeg,x,edg1a
sensorint9 rti
* een meting van 256 perioden starten
startmeting equ $
tpa |bewaar (via A) het conditie-code register
psha |op de stack
sei |houd de interrupts tijdelijk tegen
ldd #0
staa nogtedoen |256 perioden sommeren
std periodesom |de periodesom op 0
staa periodesom+2
std signaalsom |de signaalsom op 0
staa signaalsom+2
ldab #1 |de meting starten
stab meting_aan
pula |haal (via A) het condition-code register
tap |terug van de stack
rts
***** routines die door het hoofdprogramma gebruikt mogen worden
PROGRAM space
* Meet de temperatuur, en laat het resultaat achter in D. Dit resultaat
* is 309 * het aantal graden in Celcius.
graad equ 309
meet_temp equ $
pshx |bewaar het IX register op de stack
bsr startmeting |start een meting van 256 perioden
meet_temp0 tst meting_aan |wacht totdat de meting klaar is
bne meet_temp0
ldx periodesom |de tijden worden door 256 gedeeld door
ldd signaalsom |alleen de twee meest significante bytes te
|gebruiken van de 3 bytes waarin de som staat
fdiv |bereken de duty-cycle
xgdx |zet het resultaat van de deling in D
subd #20922 |corrigeer daarna (zie de uitleg hierboven)
pulx |haal X terug van de stack
rts
Door de module en de bovenbeschreven uitleg van het meetprincipe
zorgvuldig te bestuderen zou U inmiddels zelfstandig in staat moeten zijn
de werking van dit voorbeeld te doorgronden.
Dit is een goed voorbeeld van een redelijk complexe module die, eenmaal
geschreven en getest, eenvoudig in elk programma kan worden toegepast.
Elke toepassing, waarbij een temperatuur via een SMARTEC sensor moet
worden gemeten, kan gebruik maken van deze module. Het hoofdprogramma
hoeft alleen de routine 'meet_temp' aan te roepen om de temperatuur te
weten te komen.
|