elomax

[ Techniek ] [ Shop ] [ Site map
TCNT ] Capture (IC) ] Compare (OC) ] OC Voorbeeld 1 ] OC Voorbeeld 2 ] OC Voorbeeld 3 ] [ IC Voorbeeld 1 ]

Terug
Omhoog

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.


Vorige ]

© 2005...2008 Elomax [Voorwaarden ]