• No results found

ire35113-kraftelektronikk-og-mikrokontrollere-19122013

N/A
N/A
Protected

Academic year: 2022

Share "ire35113-kraftelektronikk-og-mikrokontrollere-19122013"

Copied!
32
0
0

Laster.... (Se fulltekst nå)

Fulltekst

(1)

Høgskolen i Østfold —avdeling for Ingeniørfag

EKSAMENSOPPGAVE

Emne: IRE35113 / Kraftelektronikk og mikrokontrollere Lærer: Even Arntsen / 997 17 806

Åge T Johansen / 482 49 109

Grupper: 11ELE-D+ 11ELEY-D

Dato: 19.12.2013

Tid:

09.00- 13.00

Antall vedleggsider:

27

Antall oppgavesider:

5

(med denne)

Sensurfrist: 22.01.2014

Vedlegg 1:Formler (3 sider)

Vedlegg 2:Driverfunksjoner (8 sider) Vedlegg 3:TIMER 1 (10 sider) Vedlegg 4:ADC (6 sider)

Hjelpemidler:

Selvskrevet formelsamling og godkjent kalkulator

KANDIDATENMÅ SELVKONTROLLEREAT OPPGAVESETITTERFULLSTENDIG

Oppgave 1

Prosjektoppgave uten navn merkes med studentens eksamensnummer og leveres sammen med resten av besvarelsen.

(2)

Høgskolen i Østfold —avdeling for Ingeniørfag 2

Oppgave 2

Figur 1 Vi har en vanlig enfase diodebru, med en drossel som sikrer glatt likestrøm.

Nettspenningen U =230 V. Lasten R = 4,14 ohm. Hvor mye strøm får vi gjennom R?

Det er for lite effektutvikling i R, i forhold til kravet, og vi kobler inn en brugren til, slik at vi får en trefaselikeretter. Nå er nettspenningen 400 V. Hvor stor effekt forbruker vi i R?

I nettet har vi en induktans pr. fase Ls = 0,18 mH. Hva blir likestrømmen i kretsen nå?

Som kjent vil en diode i en trefasekrets, ideelt lede i 120 grader. Finn et uttrykk for middelverdien av likestrømmen i en diode.

Diodene i trefasebrua er i felles modul. Samlet tap i denne er 260 W. Termisk motstand mellom Si- sjiktet og kjøleflaten på modulen er

RTH

skca =

0,077 °C/W. Kjøleflensen har en termisk motstand RTH=0,15 °C/W.

Med en omgivelsestemperatur på 30 °C, hva blir temperaturen i Si- sjiktet?

(3)

Høgskolen i Østfold —avdeling for Ingeniørfag 3

Oppgave 3

Figur 2. Likestrømsmotordrift

Figur 2 viser en fremmedmagnetisert likestrømsmotor, som styres av en step-ned chopper. Styreprinsippet er baser på Puls Bredde Modulasjon. U = 100 V

Vi vil styre spenningen over motoren mellom 0 og 75 V, innenfor hvilket intervall må vi kunne variere duty- cycelen?

Vi benytter en IGBT. Hvilke positive egenskaper har denne sammenlignet med andre halvledere som er aktuelle alternativ?

Hva er funksjonen til Cl?

Det viser seg at man får spenningstransienter over dioden D1, ved påslag av 01. Dette skyldes et uheldig valg av diodetype. Forklar årsaken til

transientene ut i fra karakteristikken til dioden.

Det er ikke likegyldig hvordan kretsen arrangeres fysisk. Forklar hva man bør

tilstrebe med hensyn til kritiske sløyfeareal, og lengde på ledere.

(4)

Høgskolen i Østfold —avdeling for Ingeniørfag 4

Oppgave 4

Studer følgende C-program for ATMega32A på STK500, med LEDstilkoblet PORTD.Programmet benytter driverfunksjonene for Timer1 som er lagt som vedlegg til oppgaven. Klokkefrekvensen er 15 360 000 Hz.

#include <avr/io.h>

#include "../TCNT1_drv_m32.h"

ISR (TIMER1_0VF_vect, ISR_BLOCK)

TCNT1 = 65535 - 15000; //

2A16- 15000

PORTD = 0xFF;

int main(void) int16_t counter;

DDRD= OxFF;

TCNT1_Set_PRESCALER(TCNT1_stop_gc); // Stop klokke TCNT1_Set_WGM(TCNT1_WGM_normal_gc); // WGM normal TCNT1_Set_COM1A(TCNT1_COM1A_00_gc); // COM1A normal TCNT1_Set_COM1B(TCNT1_COM1B_00_gc); // COM1B normal

TCNT1_Clr_TOV1(); // Reset eventuelt flagg

TCNT1_Enable_T0IE1(); // Enable TOV1 avbrudd

TCNT1 = 65535 - 15000; // 2A16 - 15000

TCNT1_Set_PRESCALER(TCNT1_prescale_1024_gc); // Start klokke sei();

while(1) { cli();

counter = TCNT1 - (65535 - 15000);

if (counter > 7500) { PORTD &= 0xFE;

sei();

Programmet får &.1LEDtil å blinke.

Hvilken LED blinker?

Med hvilken frekvens blinker denne?

Hva er duty-cycle (buls-bredde-forholdet) for blinkingen.

Programmet er avbruddsbasert.

Hvilket avbrudd benyttes?

Hva er betingelsen for at avbruddsrutinen skal starte for denne avbruddstypen?

Hvorfor er kallene til cli() og sei() gjort i løkken i hovedprogrammet?

Anta at du ikke har tilgang til driverfunksjonene som er vist i programmet. Skriv dette programmet på nytt ved å benytte kontrollregistrene til ATMega32A direkte.

(5)

Høgskolen i Østfold —avdeling for Ingeniørfag 5

Oppgave 5

Du skal nå lage et enkelt system for å generere 3 PWM-signaler - R, G og B som skal benyttes til å styre ut 3 sett av lysdioder med hhv rødt, grønt og blått lys. Hensikten er å kunne framstille alle mulige fargesjatteringer i lyset fra lysdiodene. På grunn av tiden som er til rådighet på prøven, skal ikke alle forhold rundt dette løses her. (Du kan gå ut fra at lysdiodene er koblet direkte til PORTDpå en slik måte at de lyser når en 1 på aktuell bitposisjon blir sent til porten.)

Tilkobling for signaler:

R: PORTDbit 5 G: PORTDbit 6 B: PORTD bit 7

Frekvensen skal være den samme for alle pulsene:

f p

= 150 Hz

Område for kontroll av pulsbredden 0 % - 99 %.

I oppgaven skal Timerl benyttes i normalmodus, altså ikke i PWM-modus. Det betyr at

programeksempelet i forrige oppgave også kan benyttes som utgangspunkt for denne oppgaven.

Anta at puls-bredde-forholdet styres av tre globale variable pwm_r, pwm_g og pwm_b.

I denne deloppgaven kan du sette disse variablene fast til henholdsvis 25 %, 50 % og 75 %.

Skriv nå et program som styrer ut de tre diodesignalene (R, G, B) etter spesifikasjonene som er gitt her.

(Det er fritt om du vil benytte funksjonsbiblioteket for Timerl eller om du vil benytte kontrollregistrene direkte.)

Anta at signalene som skal sette variablene som er omtalt i forrige deloppgave stammer fra tre analoge signaler som styres fra 3 potensiometre. Alle analoge signaler varierer mellom 0 V og 2.56 V som tilsvarer hhv 0 % og 100 % puls-bredde-forhold.

Du skal i denne deloppgaven kun betrakte det analoge signalet som styrer R (det røde lyset) —på kanal ADC2.

Skriv en utvidelse av programmet som leser inn analoge verdier fra potensiometeret og styrer lysdiodene ut fra disse verdiene. Alle tre dioder styres likt.

Det er ikke nødvendig å skrive alle programlinjene på nytt i besvarelsen. Gjør rede for hva og hvor du må sette inn av nytt og hva du må slette/beholde fra forrige deloppgave.

(Det er fritt om du vil benytte funksjonsbiblioteket for ADC (vedlagt) eller om du vil benytte kontrollregistrene direkte.)

(6)

Formelark side

Vedlegg 1

Formelark. Kraftelektronikk

Dette er ment som en hjelp til de som har "jernteppe". Således er ikke forutsetning for bruk av formelen tatt med.

Ud = fo T u(t)dt

Middelverdi

URMS=

fT u

2(t)

dt

Effektivverdi

T

JO

Ud=

0,9U 5 Middelverdi, diodebru, &ifase

Ud=0,9U,cos(a)

Middelverdi, tyristorbru, &ifase

2wLsId 2Xkld

Kommuteringsspenningsfall, &Ifase

It n-

Is = Id

Vekselstrøm, &Ifase

= °)91d

Grunnharmonisk, &ifase

Ud=

1,35U 5 Middelverdi, diodebru, trefase

Ud=1,35Uscos(a)

Middelverdi, tyristorbru, trefase

3wLs/d

3Xkld

Kommuteringsspenningsfall, trefase

2xkid

cosii = 1

Kommuteringsvinkel. (Merk Xk

= (i)Ls)

= 0,8164 Effektivverdi. Trefase vekselstrøm

41. = 0,78Id

Grunnharmonisk. Trefase vekselstrøm

U2 = U1D

Step-ned chopper

AU2

=2

(1 D)

Rippel, step-ned

U2 8LC

U2

= 1—D AU2 DTs

U2 RC

Step-up

Rippel, step-up

(7)

Formelark side

N1 D "

N2 1—D

Fly-back

U2 = D

N 2

Forward

Asynkronmaskin:

cos = K1 f

(dS COr

S =

ws

f2= s ft

Ui

K2øagf /2 KsQiag f2

Tem 1(61Øtgf2 Im = Kgøag

2

sinus

nia = r, trekant

m ftrekant

fsinus

Likestrømsmaskin:

E = wK1ø ø = K2I,n Ten, = 1(31a(2)

di, U = Raia + La= + E

dt

PBM, amplitudemodulasjonsindeks

PBM, frekvensmodulasjonsindeks

(8)

Formelark side

P = V-5111coscp Generell trefase

Q = -‘111Isincp Generell trefase

PF = ,, P Effektfaktor

DPF = coscp1 Forskyvningseffektfaktor

1 1 1

is = .N/ . 0,781d(sin(wt) ——sin(5wt) + —7 sin(7wt) —Tisin(11wt) 5

+ -5.sin(13wt) 1 .. —+)

Fourerrekke til vekselstrøm i trefase likeretter

1r2-. 0,78/ 1 1 1

i s =

Al d (sin(o)t) —1 sin(11wt) +— 13 sin(13w0 — 3 sin(23(a) 1

+ sin(25wt).. —+)

Fourierrekke til vekselstrøm i tolvpuls likeretter

(9)

Vedlegg 2

C:\Users\aa*\Desktop\ADCdrv m32.h 1

/****************************************************************************

ADC_driver.h

#ifndefADC_DRIVER_H

#defineADC_DRIVER_H

/****************************************************************************

IncludeFiles

#include<avr/io.h> //Changeaccordingto device

#include<avr/interrupt.h>

/****************************************************************************

Macrodefinitions

****************************************************************************/

#defineADC_enable() do { ADCSRA 1= (1 « ADEN);} while (0)

#defineADC_disable() do { ADCSRA&= —UINT8_C(1« ADEN);} while (0)

#defineADC_reset() do { ADCSRA= 0; ADMUX= 0; SFIOR&= —UINT8_C(ADC_TS_gm);} while (0)

#defineADC_setADLAR()

#defineADC_clrADLAR()

#defineADC_setADIE()

#defineADC_clrADIE()

#defineADC_clrADIF()

do { ADMUX 1= (1 « ADLAR);} while (0)

do { ADMUX&= —UINT8_C(1« ADLAR);} while (0) do { ADCSRA 1= (1 « ADIE);} while (0)

do { ADCSRA&= —UINT8_C(1« ADIE);} while (0) do { ADCSRA 1= (1 « ADIF);} while (0)

/****************************************************************************

Functiondefinitions

//void ADC_setup(uint8_tchan,uint8_tvref,uint8_tpre, uint8_tie);

void ADC_setAuto(uint8_ttrigsrc);

int16_tADC_read1O(void);

uint8_tADC_read8(void);

void ADC_startSingle(void);

//void ADC_disable();

uint8_tADC_inProgress(void);

uint8_tADC_if(void);

void ADC_setChannel(uint8_tchan);

void ADC_setVref(uint8_tvref);

void ADC_setPrescaler(uint8_tpre);

/****************************************************************************

Data registers:

ADCH ADCL

****************************************************************************/

/****************************************************************************

Control& Statusregisters:

ADMUX : Bit 7 6 5 4 3 2 1 O

REFS1REFSOADLARMUX4 MUX3 MUX2 MUX1 MUXO REFS1REFSO:VoltageReferenceSelection ADLAR: ADC LeftAdjustResult

MUX4:0: AnalogChanneland Gain SelectionBits ADCSRA:Bit 7654321

ADEN ADSC ADATEADIF ADIE ADPS2ADPS1ADPSO ADEN:ADC Enable

ADSC:ADC StartConversion ADATE:ADC Auto TriggerEnable ADIF:ADC InterruptFlag ADIE:ADC InterruptEnable ADPS2:0:ADC PrescalerSelectBits

SFIOR: Bit 7 6 5 4 3 2 1 0

ADTS2ADTS1ADTSO - * * *

(10)

C:\Users\aa'\Desktop\ADC dry m32.h 2 ADTS2:0: ADC Auto Trigger Source

****************************************************************************/

/****************************************************************************

Interrupt vetors:

ADC_vect - ADC complete

****************************************************************************/

/****************************************************************************

Bit and byte definitions

#define ADC_Ref_AREF_gc ((e « REFS1) + (0 « REFS0))

#define ADC_Ref_AVCC_gc ((ø « REF51) + (1 « REFS0))

#define ADC_Ref_Reserved_gc ((1 « REF51) +(E, « REFS0))

#define ADC_Ref_Internal_gc ((1 « REF51) + (1 « REFSØ))

#define ADC_Ref_gm ((1 « REFS1) + (1 « REFSØ))

#define ADC_prescale_2_gc ((0 « ADPS2) + (0 « ADPS1) + (1 « ADPSØ))

#define ADC_prescale_4_gc ((0 « ADPS2) + (1 « ADPS1) + (0 « ADPS0))

#define ADC_prescale_8_gc ((ø « ADP52) + (1 « ADPS1) + (1 « ADPSØ))

#define ADC_prescale_16_gc ((1 « ADP52) + (0 « ADP51) + (0 « ADPS0))

#define ADC_prescale_32_gc ((1 « ADPS2) + (ø « ADP51) + (1 « ADP50))

#define ADC_prescale_64_gc ((1 « ADPS2) + (1 « ADP51) + (0 « ADP50))

#define ADC_prescale_128_gc ((1 « ADPS2) + (1 « ADPS1) + (1 « ADP50))

#define ADC_prescale_gm ((1 « ADPS2) + (1 « ADPS1) + (1 « ADPS0))

#define ADC_TS_FreeRunning_gc ((ø « ADTS2) + (ø « ADTS1) +(ø « ADT50))

#define ADC_TS_ExtInte_gc ((0 « ADTS2) + (ø « ADTS1) +(1 « ADTSØ))

#define ADC_TS_AnalogComp_gc ((ø « ADTS2) + (1 « ADT51) +(ø « ADTS0))

#define ADC_TS_T0Compare_gc ((ø « ADTS2) + (1 « ADT51) +(1 « ADTSØ))

#define ADC_TS_TOOvf_gc ((1 « ADTS2) + (0 « ADTS1) +(ø « ADTSØ))

#define ADC_TS_T1Compare_gc ((1 « ADTS2) + (0 « ADTS1) +(1 « ADTSØ))

#define ADC_TS_TlOvf_gc ((1 « ADT52) + (1 « ADTS1) +(ø « ADTS0))

#define ADC_TS_TlCapt_gc ((1 « ADTS2) + (1 « ADTS1) +(1 « ADTSØ))

#define ADC_TS_gm ((1 « ADTS2) + (1 « ADTS1) +(1 « ADTS0))

#define ADC_CH_Sø_gc((0 « MUX4)+(0 « MUX3)+(0 « MUX2)+(0 « MUX1)+(e « MUX0))

#define ADC_CH_S1_gc((0 « MUX4)+(0 « MUX3)+(0 « MUX2)+(0 « MUX1)+(1 « MUX0))

#define ADC_CH_S2_gc((0 « MUX4)+(0 « MUX3)+(0 « MUX2)+(1 « MUX1)+(0 « MUX0))

#define ADC_CH_S3_gc((0 « MUX4)+(0 « MUX3)+(0 « MUX2)+(1 « MUX1)+(1 « MUXØ))

#define ADC_CH_S4_gc((0 « MUX4)+(0 « MUX3)+(1 « MUX2)+(0 « MUX1)+(0 « MUX0))

#define ADC_CH_55_gc((0 « MUX4)+(0 « MUX3)+(1 « MUX2)+(0 « MUX1)+(1 « MUX0))

#define ADC_CH_S6_gc((0 « MUX4)+(e « MUX3)+(1 « MUX2)+(1 « MUX1)+(0 « MUXØ))

#define ADC_CH_S7_gc((0 « MUX4)+(e « MUX3)+(1 « MUX2)+(1 « MUX1)+(1 « MUX0))

#define ADC_CH_PeN0_10_gc((0 « MUX4)+(1 « MUX3)+(0 « MUX2)+(0 « MUX1)+(0 « MUX0))

#define ADC_CH_P1N0_10_gc((ø « MUX4)+(1 « MUX3)+(0 « MUX2)+(0 « MUX1)+(1 « MUX0))

#define ADC_CH_PON0_200_gc ((0 « MUX4)+(1 « MUX3)+(0 « MUX2)+(1 « MUX1)+(e « MUX0))

#define ADC_CH_P1Ne_200_gc ((0 « MUX4)+(1 « MUX3)+(0 « MUX2)+(1 « MUX1)+(1 « MUX0))

#define ADC_CH_P2N2_10_gc((ø « MUX4)+(1 « MUX3)+(1 « MUX2)+(0 « MUX1)+(0 « MUX0))

#define ADC_CH_P3N2_10_gc((0 « MUX4)+(1 « MUX3)+(1 « MUX2)+(0 « MUX1)+(1 « MUX0))

#define ADC_CH_P2N2_200_gc ((ø « MUX4)+(1 « MUX3)+(1 « MUX2)+(1 « MUX1)+(0 « MUXØ))

#define ADC_CH_P3N3_200_gc ((0 « MUX4)+(1 « MUX3)+(1 « MUX2)+(1 « MUX1)+(1 « MUXØ))

#define ADC_CH_PON1_gc((1 « MUX4)+(0 « MUX3)+(e « MUX2)+(0 « MUX1)+(0 « MUX0))

#define ADC_CH_P1N1_gc((1 « MUX4)+(0 « MUX3)+(0 « MUX2)+(0 « MUX1)+(1 « MUXØ))

#define ADC_CH_P2N1_gc((1 « MUX4)+(0 « MUX3)+(0 « MUX2)+(1 « MUX1)+(0 « MUX0))

#define ADC_CH_P3N1_gc((1 « MUX4)+(0 « MUX3)+(0 « MUX2)+(1 « MUX1)+(1 « MUX0))

#define ADC_CH_P4N1_gc((1 « MUX4)+(0 « MUX3)+(1 « MUX2)+(0 « MUX1)+(0 « MUX0))

#define ADC_CH_P5N1_gc((1 « MUX4)+(0 « MUX3)+(1 « MUX2)+(0 « MUX1)+(1 « MUXØ))

#define ADC_CH_P6N1_gc((1 « MUX4)+(0 « MUX3)+(1 « MUX2)+(1 « MUX1)+(e « MUX0))

#define ADC_CH_P7N1_gc((1 « MUX4)+(0 « MUX3)+(1 « MUX2)+(1 « MUX1)+(1 « MUX0))

#define ADC_CH_P0N2_gc((1 « MUX4)+(1 « MUX3)+(0 « MUX2)+(0 « MUX1)+(0 « MUXØ))

#define ADC_CH_P1N2_gc((1 « MUX4)+(1 « MUX3)+(0 « MUX2)+(0 « MUX1)+(1 « MUXØ))

#define ADC_CH_P2N2_gc((1 « MUX4)+(1 « MUX3)+(0 « MUX2)+(1 « MUX1)+(e « MUXØ))

#define ADC_CH_P3N2_gc((1 « MUX4)+(1 « MUX3)+(0 « MUX2)+(1 « MUX1)+(1 « MUXØ))

#define ADC_CH_P4N2_gc((1 « MUX4)+(1 « MUX3)+(1 « MUX2)+(0 « MUX1)+(0 « MUXØ))

#define ADC_CH_P5N2_gc((1 « MUX4)+(1 « MUX3)+(1 « MUX2)+(0 « MUX1)+(1 « MUX0))

#define ADC_CH_Vbg_gc((1 « MUX4)+(1 « MUX3)+(1 « MUX2)+(1 « MUX1)+(0 « MUX0))

#define ADC_CH_GND_gc((1 « MUX4)+(1 « MUX3)+(1 « MUX2)+(1 « MUX1)+(1 « MUX0))

#define ADC_CH_gm((1 « MUX4)+(1 « MUX3)+(1 « MUX2)+(1 « MUX1)+(1 « MUX0))

#endif

(11)

C:\Users\aa'\Desktop\ADCdrv_m32.c 1 /****************************************************************************

ADC_driver.c

#include<avr/io.h>

#include<stdint.h>

#include"hiofdefs.h"

#include"ADC_drv_m32.h"

voidADC_setAuto(uint8_ttrigsrc) {

uint8_tmADCSRA;

SFIOR = (SFIOR& —UINT8_C(7« ADTS0))1 (trigsrc« ADTS8);

mADCSRA = ADCSRA;

mADCSRA1= UINT8_C(1« ADATE);// Set autotrig

mADCSRA1= UINT8_C(1« ADIF); // ClearInterruptflag ADCSRA = mADCSRA;

}

int16_tADC_read1o(void)

ø

{ uint16_thi, lo;

lo = ADCL & OxFF;

hi = ADCH & oxFF;

if((ADMUX& (1 « ADLAR))== o) // ADLAR== e {

return(hi « 8) + lo;

}

else // ADLAR== 1 {

return(hi « 2) + (lo » 6);

} }

uint8_tADC_read8(void) {

uint8_thi, lo;

lo = ADCL & oxFF;

hi = ADCH & oxFF;

if((ADMUX& (1 « ADLAR))== (3)// ADLAR== ø {

return(hi « 6) + (lo » 2);

else {

return(ADCH);

}

}

void ADC_startSingle(void) {

ADCSRA 1= (1 « ADSC);

}

uint8_tADC_inProgress(void) {

return(ADCSRA& (1 « ADSC))!= false;

}

uint8_tADC_if(void) {

return(ADCSRA& (1 « ADIF))!= false;

}

voidADC_setChannel(uint8_tchan) {

ADMUX = (ADMUX& —ADC_CH_gm)1 (chan);

}

(12)

C:\Users\aa'\Desktop\ADC_drv_m32.c

void ADC_setVref(uint8_tvref) {

ADMUX = (ADMUX& —ADC_Ref_gm)1 (vref);

}

voidADC_setprescaler(uint8_tpre) {

ADCSRA = (ADCSRA&= —ADC_prescale_gm)1 pre;

}

(13)

C:\Users\aa'\Desktop\TCNT1drv m32.h 1

#include<avr/io.h>

#ifndefINCFILE1_H_

#defineINCFILE1_H_

#defineTCNT1_stop_gcOxøø

#defineTCNT1_prescale_l_gcexel

#defineTCNT1_prescale_8_gcex02

#defineTCNT1_prescale_64_gc0x83

#defineTCNT1_prescale_256_gc0x04

#defineTCNT1_prescale_1024_gc0>:05

#defineTCNT1_T1neg_gcex06

#defineTCNT1_Tlpos_gc0x07

#defineTCNT1_prescale_gm0h<87

#defineTCNT1_prescale_bpexøø

#defineTCNT1_COM1A_00_gc((0 « COM1A1) (ø « COM1AØ))

#defineTCNT1_COM1A_0l_gc((0 « COM1A1) (1 « COM1A0))

#defineTCNT1_COM1A_10_gc((1 « COM1A1) (0 « COM1AO))

#defineTCNT1_COM1A_11_gc((1 « COM1A1) (1 « COM1AØ))

#defineTCNT1_COM1A_gm((1 « COM1A1) (1 « COM1A0))

#defineTCNT1_COM113_00_gc((E)« COM1B1) (Ø « COM1BO))

#defineTCNT1_COM1B_01_gc((0 « COM1B1) (1 « COM1B0))

#defineTCNT1_COM1B_le_gc((1 « COM1131) (ø « COM1B0))

#defineTCNT1_COM1B_11_gc((1 « COM1B1) (1 « COM1Bø))

#defineTCNT1_COM1B_gm((1 « COM1B1) (1 « COM1BO))

#defineTCNT1_no_PWM_OC1A_gcTCNT1_COM1A_00_gc

#defineTCNT1_normal_PWM_OC1A_gcTCNT1_COM1A_l0_gc

#defineTCNT1_inverted_PWM_OC1ATCNT1_COM1A_11_gc

#defineTCNT1_no_PWM_OC1B_gcTCNT1_C0M1B_00_gc

#defineTCNT1_normal_PWM_OC1B_gcTCNT1_COM1B_10_gc

#defineTCNT1_inverted_PWM_OC1BTCNT1_COM18_11_gc

#defineTCNT1_WGM_normal_gc((ø « WGM13)I(ø « WGM12)I(ø « WGM11)I(ø « W WGM10))

#defineTCNT1_WGM_Phase_Correct_8_bit_gc((ø « WGM13)

I

(0 « WGM12)I(ø « WGM11)I(1 « W WGM10))

#defineTCNT1_WGM_Phase_Correct_9_bit_gc((ø « WGM13)

I

(0 « WGM12)I(1 « WGM11)I(0 « W WGM10))

#defineTCNT1_WGM_Phase_Correct_10_bit_gc((0 « WGM13)I(ø « WGM12)I(1 « WGM11)I(1 « W WGM1ø))

#defineTCNT1_WGM_CTC_OCR1A_gc((0 « WGM13)

I

(1 « WGM12)I(0 « WGM11)I(0 « W WGM10))

#defineTCNT1_WGM_Fast_PWM_8_bit_gc((ø « WGM13)

I

(1 « WGM12)I(ø « WGM11)I(1 « W WGM10))

#defineTCNT1_WGM_Fast_PWM_9_bit_gc((ø « WGM13)

I

(1 « WGM12)I(1 « WGM11)I(0 « W WGM10))

#defineTCNT1_WGM_Fast_PWM_l0_bit_gc((0 « WGM13)

I

(1 « WGM12)I(1 « WGM11)I(1 « W WGM10))

#defineTCNT1_WGM_Phase_and_Frequency_Correct_ICR1_gc((1« WGM13)

I

(0 « WGM12)I(ø « WGM11)I(0 « W WGM1Ø))

#defineTCNT1_WGM_Phase_and_Frequency_Correct_OCR1A_gc((1« WGM13)I(ø « WGM12)(ø « WGM11)I(1 « W WGM1ø))

#defineTCNT1_WGM_Phase_Correct_ICR1_gc((1 « WGM13)I(ø « WGM12)I(1 « WGM11)(0 « W WGM1O))

#defineTCNT1_WGM_Phase_Correct_OCR1A_gc((1 « WGM13)

I

(0 « WGM12)I(1 « WGM11)I(1 « W WGM1O))

#defineTCNT1_WGM_CTC_ICR1_gc((1 « WGM13)

I

(1 « WGM12)I(ø « WGM11)I(ø « W WGM1O))

#defineTCNT1_WGM_reserved_gc((1 « WGM13)

I

(1 « WGM12)I(ø « WGM11)I(1 « W WGM1ø))

#defineTCNT1_WGM_PWM_ICR1_gc((1 « WGM13)

I

(1 « WGM12)I(1 « WGM11)I(ø « W WGM1Ø))

#defineTCNT1_WGM_Fast_PWM_OCR1A_gc((1 « WGM13)

I

(1 « WGM12)I(1 « WGM11)I(1 « W WGM10))

#defineTCNT1_WGM_gm((1 « WGM13)

I

(1 « WGM12)I(1 « WGM11)I(1 « W WGM1ø))

#defineTCNT1_WGM_TCCR1A_gm((0 « WGM13)I(ø « WGM12)(1 « WGM11)I(1 « W WGM1ø))

(14)

C:\Users\aa'\Desktop\TCNT1drv m32.h 2

#defineTCNT1_WGM_TCCR1B_gm ((1 « WGM13) 1 (1 « WGM12) 1 (0 « WGM11) I (0 « kl WGM10))

#defineTCNT1_Is_ICF1()((TIFR& (1 « ICF1))!= 0)

#defineTCNT1_Is_OCF1A()((TIFR& (1 « OCF1A))!= 0)

#defineTCNT1_Is_OCF1B()((TIFR& (1 « OCF1B))!= 0)

#defineTCNT1_Is_TOV1()((TIFR& (1 « TOV1))!= 0)

#defineTCNT1_Wait_ICF1()do { while((TIFR& (1 « ICF1))== 0) ; } while (0)

#defineTCNTl_Wait_OCF1A()do { while((TIFR& (1 « OCF1A))== 0) ; } while (0)

#defineTCNT1_Wait_OCF1B()do { while((TIFR& (1 « OCF1B))== 0) ; } while (0)

#defineTCNT1_Wait_TOV1()do { while ((TIFR& (1 « TOV1))== 0) ; } while (0)

#defineTCNT1_Enable_Output_OC1A()(DDRD= DDRD 1 (1 « DDRD5))

#defineTCNT1_Enable_Output_OC1B()(DDRD= DDRD 1 (1 « DDRD4))

#defineTCNT1_Clr_TOV1() do { TIFR = (1 « TOV1);} while (0) void TCNT1_Set_WGM(uint8_twgm);

/*

SETTINGPRESCALERBITS Registers:TCCR1B

wgm: 3 bit word from table16.6 in doc8155.pdf

*/

void TCNT1_Set_PRESCALER(uint8_tpresc);

/*

SETTINGCOMPAREOUTPUTMODE BITSA Registers:TCCR1A

com1A:2 bit word from tables16.2 - 16.4 in doc8155.pdf

*/

void TCNT1_Set_COM1A(uint8_tcom1A);

/*

SETTINGCOMPAREOUTPUTMODE BITS B Registers:TCCR1A

com1B:2 bit word fromtables16.2 - 16.4 in doc8155.pdf

*/

void TCNT1_Set_COM1B(uint8_tcom1B);

void TCNT1_Enable_TICIE1(void);

void TCNT1_Disable_TICIE1(void);

void TCNT1_Enable_OCIE1A(void);

void TCNT1_Disable_OCIE1A(void);

void TCNT1_Enab1e_OCIE1B(void);

void TCNT1_Di5ab1e_OCIE1B(void);

void TCNT1_Enable_TOIE1(void);

void TCNT1_Disable_TOIE1(void);

#endif/* INCFILE1_H_*/

(15)

C:\Users\aa'\Desktop\TCNT1_drv_m32.c 1

#include"TCNT1_drv_m32.h"

void TCNT1_PWM_Phase_and_Freq_correct_Set_rate(uint8_tratio) {

OCR1B= (ratio* ICR1)/ 108;

}

void TCNT1_PWM_Phase_and_Freq_correct_Init(uints_tpresc,uint16_ttop ) {

uint8_tb2, bl, bø;

bø = (presc» 0) & 1;

bl = (presc» 1) & 1;

b2 = (presc» 2) & 1;

TCCR1A= (ø « WGM11 ) 1 (ø « WGM18 ) // PWM - Phaseand Fre.correct:ICR1 -> TOP 1 (ø « FOC1A) 1 (Ø « FOC1B)

1 (0 « COM1A1)1 (0 « COM1A0) // No output

1 (1 « COM1B1)1 (0 « COM1130);// NormalPWM-output TCCR1B= (0 « ICNC1) // IC noisecanceler

1 (8 « ICES1) // InputCaptureEdgeSelect

1 (1 « WGM13 ) 1 (ø « WGM12 ) // PWM - Phaseand Fre.correct:ICR1 -> TOP 1 (b2 « CS12 ) 1 (b1 « CS11 ) 1 (b0 « CS1O ); // PRESCALER8 x

TCNT1 = 0; // initialvalueof T/C1

ICR1 = top; // initialvalueof TOP (9600givesFpwm=188Hz) OCR1B = top/2; // initialvalueof Comparereg.B (50%) DDRD = DDRD 1 (1 « DDRD4);

}

/*

SETTINGWGM BITS

Registers:TCCR1A,TCCR1B

wgm: 4 bit word from table16.5 in doc8155.pdf- use predefinedconstants

*/

void TCNT1_Set_WGM(uint8_twgm) {

TCCR1A= (TCCR1A& --TCNTl_WGM_TCCR1A_gm)1 (wgm& TCNT1_WGM_TCCR1A_gm);

TCCR1B= (TCCR1B& --TCNT1_WGM_TCCR1B_gm)1 (wgm& TCNT1_WGM_TCCR1B_gm);

} /*

SETTINGPRESCALERBITS Registers:TCCR1B

wgm: 3 bit word from table16.6 in doc8155.pdf

*/

void TCNT1_Set_PRESCALER(uint8_tpresc)

{

TCCR1B= (TCCR1B& —TCNT1_prescale_gm)1 (presc);

}

/*

SETTINGCOMPAREOUTPUTMODE BITSA Registers:TCCR1A

com1A:2 bit word from tables16.2 - 16.4 in doc8155.pdf

*/

void TCNT1_Set_COM1A(uint8_tcom1A) {

TCCR1A= (TCCR1A& -,TCNT1_COM1A_gm)1 com1A;

}

/*

SETTINGCOMPAREOUTPUTMODE BITS B Registers:TCCR1A

com1B:2 bit word fromtables16.2 - 16.4 in doc8155.pdf

*/

void TCNT1_Set_COM1B(uint8_tcom1B) {

TCCR1A= (TCCR1A& —TCNT1_COM1B_gm)1 com1B;

}

void TCNT1_Enab1e_TICIE1(void)

(16)

C:\Users\aa'\Desktop\TCNT1_drv_m32.c {

TIMSK= TIMSK I (1 « TICIE1);

}

2

void TCNT1_D1sab1e_TICIE1(void) {

TIMSK= TIMSK& —(1 « TICIE1);

}

void TCNTl_Enab1e_OCIE1A(void) {

TIMSK= TIMSK I (1 « OCIE1A);

}

void TCNT1_Disab1e_OCIE1A(void) {

TIMSK= TIMSK& —(1 « OCIE1A);

}

void TCNT1_Enab1e_OCIE1B(void) {

TIMSK= TIMSK I (1 « OCIE1B);

}

void TCNT1_Disab1e_OCIE1B(void) {

TIMSK= TIMSK& —(1 « OCIE1B);

}

void TCNT1_Enab1e_TOIE1(void) {

TIMSK= TIMSK I (1 « TOIE1);

}

void TCNTl_Disab1e_TOIE1(void) {

TIMSK= TIMSK& —(1 « TOIE1);

}

ø

(17)

Vedlegg 3

HØGSKOLEN I ØSTFOLD AVDELING FOR INGENIØRFAG / ELEKTRO / DIGITAL ELEKTRONIKK

3.1 Oversikt

Dette er en beskrivelse av funksjonsregistre og virkemåte for de mest anvendte funksjonene i timere/tellere for AVR-familien av mikrokontrollere. Følgende funksjonsenheter beskrives:

Timer_O (8 bit) Timer_1 (16 bit) Timer_2 (8 bit)

TIMER 0 TIMER 1 - high TIMER 1 - low TIMER 2

Figur 3.3: De 3 timer-enhetene som finnes i de mest anvendte AVR-kontrollerne.

Innledningsvis vises de mest aktuelle funksjonsregistrene med symbolske navn på de enkelte bit. Disse navnene benyttes i ATMEL's dokumentasjon og også i headerfiler som følger WinAVR GCC-kompilator og assembleren i AVR Studio 4.

NB! Vær oppmerksom på at bitposisjonene for kontrollbit med samme navn forandrer seg mellom kontrollertypene - f. eks. mellom at90s8515 og ATMega32. Det er derfor en stor fordel å benytte de symbolske navnene framfor numeriske konstanter.

De viste registrene i dette kapittelet er fra dokumentasjonen for ATMega32. Sjekk alltid med originalt datablad (avrm3209) før du benytter registrene i et program.

3.1.1 Avbruddsrelaterte registre

Følgende to register vil være sentrale i beskrivelsen for flere av AVR-familens timerkretser og gjengis derfor her i oversiktsdelen.

TIMSK(Timer Interrupt Mask Register). Dette registeret kontrollerer hvilke

avbruddsfunksjoner som skal tillates. En ener på angitte posisjon vil åpne for vedkommende avbrudd. Om avbruddet virkelig skal utføres, avhenger også av om det globale l-flagget i statusregisteret (SREG) er satt til 1. Setting og nullstilling av l-flagg utføres vedhjelp av makroene sei()og cIi().

Bit 7 6 5 4 3 2 1 0

$39 ($59) OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0 TIMSK

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.4: Timer Interrupt Mask Register

TIFR(Timer Interrupt Flag Register). Dette registeret forteller hvilke fysiske avbrudd som har inntruffet. En ener på angitte posisjon angir dette. De enkelte bit i dette registeret settes automatisk til 1, men kan nullstilles fra programvare ved polling eller automatisk når avbruddsmekanismen benyttes.

NB! TIFRer spesielt ved at et bit nullstilles ved å skrive en 1-er til vedkommende bitposisjon.

FORFATTER: 48 DATO:

(18)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAG ELEKTRO/ DIGITAL ELEKTRONIKK

Bit 7 6 5 4 3 2 1 0

$38 ($58) OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOVO TIFR

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.5: Timer Interrupt Flag Register

De enkelte bit i disse registre skal omtales etter hvert som de benyttes i eksempler. En skisse av disse TIMASK og TIFR vil også gjentas i tilknytning til hver teller i det neste avsnittene.

3.2 Timer 0

I dette dokumentet beskrives kun de mest grunnleggende egenskapene til Tim _0. I praksis ar Timer_O og Timer_2 mange av de samme funksjonene.

• 3.2. Generelt

Timer_O e en 8-bits timer/teller som kan telle fra 0 til OxFF. Neste kl kepuls etter at toppverdien FF er nådd, fører til

overflow;

dvs. tellerverdien set s tilbake til 0. Timer_O

overflow

kan tri et avbrudd hvis det eller er klargjort for det

I timer-modus benytt et internt klokkesignal, mens det i t er-modus benyttes et eksternt klokkesignal på PBO kalt . Begge operasjonsmodi blir b krevet. Begge modi kan benyttes både med avbruddsstyring o med

polling.

TCNTO - telleverdi

255/

OxFF

0 Tid

OVO TOVO TOVO

Figur 3.6: Ti spunkter for TOVO-avbruddvedfull tellesekvens r Timer 0.

Figuren ovenfor v. er at avbruddshendelsen TOVO inntrer hver gang Timer_ år

ovetflow.

Figuren nede r viser et relativt detaljert blokkskjema for Timer_0. I figuren ska erstattes med

0 i

reg. ernavnene.

FORFATTER: 49 DATO:

(19)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAG ELEKTRO/ DIGITAL ELEKTRONIKK

3.3 Timer_l

3.3.1 Generelt

motsetning til Timer_O og Timer_2, er Timer_1 en 16-bits teller (timer). Derfor kan Timer_1 benyttes i anvendelser der lengre tellesekvenser er nødvendig ønskelig. Tellesekvensen strekker seg fra

Ox0000

til

OxFFFF

og så direkte tilbake til

Ox0000 (overflow).

Timer_1

realiseres ved hjelp av to sammenkoblede 8-bits tellerregistre

(TCNT1H

og

TCNT1L).

For øvrig tilbyr Timer_1 også funksjonene

"output compare"

og

"input capture"

i tillegg til en PWM utgang (puls-bredde-modulert utgang).

TCNT1 - telleverdi FFFF

0000

Tid

viv ylv

TOV1 TOV1 TOV1

Figur 3.15: Tidspunkterfor TOV1-avbrudd vedfull tellesekvensfor Timer 1.

Timer_1 kan også settes opp til å telle både oppover og nedover, selv om dette ikke vises i programeksemplene.

Blokkskjemaet for Timer_1 vises nedenfor, der

n

skal erstattes med 1.

FORFATTER: 57 DATO:

(20)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAGI ELEKTRO DIGITA1ELEKTRONIKK

Count Clear

Chrectort Control Log,c C

TOVn Cleck Saiect

E.

DiNiziar Tn

TOP BOTTOM

TirtNeriCourqur TCNTn

=

(Frcrn Proscaw

OCnA (Irt Rez

Vålvef fr

ratfl OCnA

OCnB

Arakcs CDmparatr

CPn OCnB

(Int.Rez ) V4v6fDrni Gir.43rafion

OCRnB

CRn

TOCRnA

CFn (IrtRa;.) Ej;i1 Datoctof

NOSli Canze4r

TCCRnB OCRnA

TOP VaIulas

Figur 3.16: Blokkskjemafor Timer 1. (avrm3209)

Som det framgår av figuren er Timer_1 en mer komplisert konstruksjon enn Timer_O. Vi kjenner likevel igjen binærtelleren TCNT1 (16 bit). Vi identifiserer også:

2 x

output compare

registre: OCR1A, OCR1B 1 x

input capture

register: ICR1

1 x ekstern telleinngang: T1 1 x ekstern

capture

inngang: ICP1

2 x eksterne utganger fra

output compare

enhetene: OC1A, OC1B 2 x kontrollregistre TCCR1A, TCCR1B

Merk at alle dataregistrene er dobbeltregistre (2 x 8 bit) og må programmeres byte for byte med assemblyinstruksjoner. C-kompilatoren lar oss imidlertid jobbe direkte mot 16 bits registre, uten å måtte dele de opp. Dette sparer oss for en del brydderi.

Kontrollregistrene er 8-bits registre på vanlig vis.

3.3.2 Funksjonsregistre

TCNT1(Timer Register 1). Dette er et sammensatt register på til sammen 16 bit. Registeret innholder aktuell telleverdi for Timer_1. Fysisk sett er TCNT1 bygget opp av to 8 bits registre

—TCNT1H (high byte) og TCNT1L (low byte). Disse må programmeres og avleses i en bestemt sekvens for at riktig verdier skal garanteres.

FORFATTER: 58 DATO:

(21)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAG ELEKTRO DIGITAL ELEKTRONIKK

Ved programmering (skriving):

Skriv først til TCNT1H Deretter til TCNT1L Ved lesing:

Les først fra TCNT1L Deretter fra TCNT1H

Disse prosedyrene fører til at alle 16 bit skrives og leses samtidig fra de fysiske registrene.

Et C-program refererer som regel til alle 16 bit samtidig ved å angi TCNT1.Kompilatoren ordner med den riktige lese- eller skrivesekvensen av 8-bitsregistrene etter de angitte regler.

Timer_1 kan klokkes av et utvalg klokkekilder som velges i kontrollregister TCCR1B.

Bit 7 6 5 4 3 2 1 0

$2D ($4D) MSB TCNT1H

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Bit 7 6 5 4 3 2 1 0

$2C ($4C) LSB TCNT1L

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.17: Timer/Counter 1.

OCR1A

(Output Compare Register A) Dette registeret er et 16-bits dobbelregister som består av OCR1AH og OCR1AL. Programmering og lesing av disse registrene må utføres i henhold til metoden som er beskrevet for TCNT1 ovenfor.

Registerets innhold sjekkes kontinuerlig mot innholdet av TCNT1 (hardwaremessig). Bit OCF1A I flaggregisteret TIFR settes til 1 så snart match inntreffer. Et "output compare"

avbrudd vil trigges hvis bit OCIE1A i maskeregisteret TIMSK er satt til 1.

OCF1A må nullstilles fra programmet om man benytter polling. OCF1A resettes automatisk ved bruk av avbrudd.

Bit 7 6 5 4 3 2 1 0

$2B ($4B) MSB OCR1AH

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Bit 7 6 5 4 3 2 1 0

$2A ($4A) LSB OCR1AL

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.18: Output Compare RegisterA

FORFATFER: 59 DATO:

(22)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAGI ELEKTRO/ DIGITAL ELEKTRONIKK

OCR1B

(Output Compare Register B) Dette registeret er et 16-bits dobbelregister som er organisert og virker på samme måte som OCR1A. De aktuelle bit i TIFR og TIMSK registrene er henholdsvis OCF1B og OCIE1B.

Bit 7 6 5 4 3 2 1 0

$29 ($49) MSB OCR1BH

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Bit 7 6 5 4 3 2 1 0

$28 ($48) LSB OCR1BL

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.19: Output Compare Register B

ICR1

(Input Capture Register) Dette registeret er et 16-bits dobbelregister. Registeret klokkes av et ytre signal fra pinne ICP. Når registeret klokkes, kopieres innholdet fra TCNT1 direkte inn i ICR1 (alle 16 bit samtidig). Det blir altså mulig å fryse telleverdien i TCNT1 ved hjelp av et ytre signal.

Igjen er det viktig at de to 8-bitsregistrene som ICR1 består av leses av i riktig rekkefølge som forklart for TCNT1 ovenfor.

Bit 7 6 5 4 3 2 1 0

$27 ($47) MSB ICR1H

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Bit 7 6 5 4 3 2 1 0

$26 ($46) LSB ICR1L

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.20: Input Capture Register

TCCR1A (Timer/Counter Control Register A) Innholdet av dette registeret styrer store deler av

"output compare"

og PWM funksjonaliteten til Timer_1.

De enkelte kontrollbit beskrives nærmere i forbindelse med de enkelte operasjonsmodi.

Bit 7 6 5 4 3 2 1 0

$2F ($4F) COM1A1 COM1A0 COM1B1 COM1B0 FOC1A FOC1B WGM11 WGM10 TCCR1A

Read/Write R/W R/W R/W R/W W W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.21: Timer/Counter 1 Control RegisterA.

FORFATTER: 60 DATO:

(23)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAG ELEKTROI DIGITAL ELEKTRONIKK

TCCR18(Timer/Counter Control Register B) Innholdet av dette registeret styrer "input capture" funksjonen, valg av klokkesignal til Timer_1. Et kontrollbit, CTC1, er også med på bestemme noe av funksjonaliteten i "output compare" modus.

De enkelte kontrollbit beskrives nærmere i forbindelse med de enkelte operasjonsmodi.

Bit 7 6 5 4 3 2 1 0

$2E ($4E) ICNC1 ICES1 WGM13 WGM12 CS12 CS11 CS10 TCCR1B

Read/Write R/W R/W R R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.22: Timer/Counter 1 Control Register B.

TIMSK(Timer Interrupt Mask Register).

Bit 7 6 5 4 3 2 1 0

$39 ($59) OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0 TIMSK

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.23: Timer Interrupt Mask Register.

TIFR(Timer Interrupt Flag Register).

Bit 7 6 5 4 3 2 1 0

$38 ($58) OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOVO TIFR

Read/Write R/W R/W R/W R/W R/W R/W R/W R/W

Initial Value 0 0 0 0 0 0 0 0

Figur 3.24: Timer Interrupt Flag Register.

Figuren nedenfor viser inn- og utganger tilknyttet Timer_1.

FORFATTER: 61 DATO:

(24)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAGELEKTRO/DIGITAL ELEKTRONIKK

PDIP

(XCK/TO) PBO 1 40 PAO (ADCO)

2 39 Rk1 (ADC1)

(T1) PB1

(INT21AINO) PB2 3 38 PA2 (ADC2)

(OCOIAI N1) P83 4 37 PA3 (ADC3)

(n) PB4 5 36 PA4 (ADC4)

(MOSI) PB5 6 35 R5 (ADC5)

(M ISO) P86 7 34 PA6 (ADC6)

(SCK) PB7 8 33 R!1/47(ADC7)

RESET 9 32 AREF

VCC 10 31 GND

GND 11 30 AVCC

XTAL2 12 29 PC7 (TOSC2)

XTAL 1 13 28 PU (TOSC1)

(RXD) PDO 14 27 FC5 (TDI)

(TXD) PD1 15 26 PC4 (TDO)

(I NTO) P02 16 25 PC3 (TMS)

(I NT1) PD3 17 24 PC2 (TCK)

18 23 PC1 (SDA)

111••••• (0C1B) PD4

(0C1A) PD5 19 22 PCO (SCL)

(ICP1) P06 20 21 P07 (0C2)

Figur 3.25: Inn-/Utganger for Timer 1. (avrm3209)

3.3.3 Timer-modus

denne operasjonsmodus blir

Timer 1

klokket av et internt signal avledet fra systemklokken (fosc)• For hver klokkecycle inkrementeres registerverdien til

Timer 1

med 1.

Klokkefrekvensen frIrvu = fosc n, der n kan innta verdiene: 1, 8, 64, 256, 1024.

Verdien n settes i kontrollregisteret

TCCR1B

i oppstartedelen av programmet i henhold til tabell 2.

TABELL2: TCCR1B —Valg av klokkesignal CS10 Beskrivelse

0 Stopp, Timer_l er stoppet

1 fosc

0 fosc / 8

1 fosc / 64

0 fosc / 256 1 fosc / 1024

0 Ekstern pinne T1, negativ flanke 1 Ekstern pinne Tl, positive flanke

3.3.3.1 Bruk av polling

Det vises et program som tilsvarer det som ble presentert for Timer_0, men med forskjellen at det her benyttes en 16 bits timer, "Timer_1" .

CS12 CS11

0 0

0 0

0 1

0 1

1 0

1 0

1 1

1 1

FORFATTER: 62 DATO:

(25)

HØGSKOLEN I ØSTFOLD AVDELING FOR INGENIØRFAG ELEKTRO / DIGITAL ELEKTRONIKK

#include <avr/io.h>

unsigned char led;

int main( void )

DDRB = OxFF; //

use all pins on

PORTB

for output

TCNT1 = Ox0000; //

start value of T/C1

TCCR1A = 0; // T/C1

in timer mode

TCCR1B = (1 << CS10); //

prescale ck/1 led — 0;

for (;;) (

while

((TIFR & (1 << TOV1)) == 0) () //

wait for overflow

PORTB = -

led; // write to

LEDs

on

PORTB

led++;

TCNT1 = 0; //

start value of T/C1 (unnecessary)

TIFR = (1 << TOV1); //

clear TOV1

I eksempelet er

TCCR1A

programmert med verdien 0 som får

Timer 1

til å arbeide i timer modus. TCCR1B får verdien 1 (CS10) som angir at timer-klokken skal være fosc. Startverdien til telleren settes til 0 (TCNT1).

Etter hver klokkepuls inkrementeres altså verdien til telleren med 1 helt til verdien

OxFFFF

nås. Neste klokkepuls fører til

overflow

i telleren og verdien settes tilbake til

Ox0000.

En

while-løkke

overvåker tilstanden til

Timer 1

ved å lese av flaggregisteret

TIFR.

Det er spesielt bit

TOV1

som vi er interessert i. TOV1 angir om timeren har hatt overflow. Når

TOV1

inntar verdien 1, betyr det at telleren er nullstilt, og

while-løkken

avbrytes. Innholdet av variabelen

led

(bit-invertert) sendes til PORTB.

Variabelen

led

inkrementeres før flagget

TOV1

nullstilles ved å skrive en 1 til bitposisjonen for dette flagget. Denne nullstillingen må utføres for et program som benytter polling i motsetning til avbrudd. I et avbruddsbasert program vil TOV1 automatisk (hardware-messig) bli nullstilt når avbruddsfunksjonen startes.

Det er ganske overflødig i dette eksempelet å nullstille TCNT1 for hver gang vi har hatt

overflow.

Imidlertid vil det være aktuelt hvis vi ønsket å telle f. eks. 40 000 klokkepulser. I dette tilfellet ville setningen

TCNT1 = 0;

bli erstattet med

TCNT1 = Ox10000 - 40000; //

Merk bruk av hex- og desimaltall

3.3.3.2 Bruk av avbrudd

Denne operasjonsmodus benyttes oftere enn polling. Statusbit

TOV1

trenger ikke overvåkes fra programmet. Mikrokontrollerhardwaren sørger selv for å starte riktig avbruddsfunksjon når

overflow

inntreffer.

TOV1

blir også nullstilt automatisk, som nevnt ovenfor.

FORFATTER: 63 DATO:

(26)

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAG ELEKTRO/ DIGITAL ELEKTRONIKK

Når avbruddsfunksjonen avsluttes, fortsetter hovedprogrammet som om ingenting skulle ha skjedd. I følgende eksempel går hovedprogrammet i en endeløs løkke og gjør ingenting.

#include <avr/io.h>

#include <avr/interrupt.h>

unsigned char led;

ISR(TIMER1._OVF

vect,

ISR BLOCK)

[

PORTB = -

led;

//

write value of led on

PORTB

led++;

//

Increment output value

TCNT1 = Ox0000;

//

reload timer with initial value

int main( void )

DDRB = OxFF; //

use all pins on

PORTB

for output

TIMSK = (1 << TOIE1); //

enables the T/C1 overflow interrupt TCNT1 = Ox0000; // start value of T/C1

TCCR1A = 0; // T/C1

in timer mode

TCCR1B = (1 << CS12)

1 (1 << CS10); // prescale

ck/1024

led = 0;

sei(); // set global interrupt enable for (;;){

Avbruddsfunksjonen starter med nøkkelordet

ISR.

Det aktuelle avbruddet identifiseres med en symbolsk konstant definert i headerfilene. Så snar

overflow

inntreffer, startes

avbruddsfunksjonen. Det nødvendige avbruddet må åpnes i initialiseringsdelen av hovedprogrammet:

Bit

TOIE1

settes i

TIMSK,

og det globale avbruddsflagget (I) må settes i statusregisteret

(SREG)

vha av hjelpefunksjonen

sei0,

som fører til at assemblyinstruksjonen "SEI" blir utført.

3. . Teller-modus

denne mo forandres innholdet i telleren TCNT1 av et eksternt klokkesig å pinne T1.

Dette signalet ka mme fra en ekstern generator, eller kan stamme sensorer eller lignende som aktiveres fysiske hendelser i omgivelsene; f. ek biler passerer på en vei eller at en gjenstand passerer ° et samlebånd. På samm ate som i timermodus, vil et avbrudd kunne trigges ved

ovetflo .

Et programeksempel for denne operasjon us vil være svært lik tilsvarende for

Timer 0.

Vær oppmerksom på at T1 ligger p° TB hvis p1 e (PB1) må defineres som inngang.

Tellermodus velges ved å rammere TCCR1B.[2-0] = 7 lokking på positiv flanke av T1 og 6 for klokking på arende negative flanke. Se tabell 2.

FORFATTER: 64 DATO:

(27)

Vedlegg 4

HØGSKOLENI ØSTFOLD AVDELING FORINGENIØRFAG ELEKTRO DIGITAL ELEKTRONIKK

4.1.2 ADC-omformeren i AVR

Internt bruker ADC-en i AVR metoden med "suksessiv approksimasjon". Dette prinsippet innebærer at det tar like mange klokkepulser som antall bits oppløsning for ADC-en å utføre konverteringen. I praksis går det med et par pulser ekstra for synkronisering og

startbetingelser. For AVR vil dette si 13 klokkepulser.

Figuren nedenfor viser hvilke pinner på ATMega32 som benyttes i forbindelse med ADC-en.

(XCKITO) PBO (TI) PBI (I NT2/AINO) PB2 (OCO/AIN I ) PB3 (n) PB4 (MOSI ) PBS (M ISO) PB6 (SCK) PB7

PDIP

1 2 3 4 5 6 7 8

40 39 38 37 36 35 34 33

Ff‘O (ADCO) PA1 (ADC 1) PA2 (ADC2) PA3(ADC3) PA4 (ADC4) PAS (ADC5) PA6 (ADC6) PA7 (ADC7)

Analog referansespenning

• •

111—

RESET 9 32 AREF

VCC 10 31 GND

GND 11 30 AVCC

••.—

XTAL2 12 29 PC7 (TOSC2) Analog driftspenning

XTAL 1 13 28 FC6 (TOSC1)

(RXD) PDO 14 27 PC5 (TD I)

(TXD ) P01 15 26 PC4 (TDO )

(INTO) PD2 16 25 PC3 (TMS)

(INT 1) PD3 17 24 PC2 (TCK)

(0C1B) PD4 18 23 PC1 (SDA)

(0C1A) PD5 19 22 PCO (SCL)

(ICPI ) P06 20 21 P07 (0C2)

Figur 4.3: Aktuelle innganger for AD-omformer.

En intern multiplekser er koblet inn foran ADC-en. Inngangene på multiplekseren er koblet til pinnene PA7-0 som også er koblet til PORTA. Hvis man ønsker, kan derfor opp til 8 analoge spenningskilder kobles direkte til mikrokontrolleren. Pinnene på Port A som ikke brukes til analog innganger, kan fremdeles benyttes til digital 10 på vanlig måte.

2

3

10 8

PA7 PA6 PA5 PA4 PA3 PA2 PA1 PAO

ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADCO

ADRAUX ADCSR

Figur 4.4: Blokkskjemafor AD-omformer.

Resultatet kan leses av fra dobbeltregisteret ADC (ADCH/ADCL)som har de minst signifikante 8 bit i ADCL og de 2 mest signifikante bit i ADCH. Disse registrene må leses i sedvanlig rekkefølge med ADCL først for å sikre at innholdet begge registre hører til samme

FORFATTER: 89 DATO:

Referanser

RELATERTE DOKUMENTER

SPISlave (PinName mosi, PinNarne miso, PinName sclk, PinName ssel) Create a SPI slave connected to the specified pins. void format (int bits,

Vis med et kretsskjema hvordan du vil koble en RGB-led til Arduino Uno via skiftregisteret 595 dersom den skal kunne styres ved hjelp av SPI. Ta med kontrollsignaler

06S QnS contents of shift register shifted through: previous contents of the shift register is transferred to the storage register and the parallel output stages. [1] H =

1A. Når dette stoppes brenselscella.. Forklar hvordan et ledespenningsfall på 1 V over hver av diodene vil påvirke D under bulkladning.. Svar: Regner effekttap i komponentene over

Location Village / WardType of facilityDispensary Health Centre Hospital Number of births in the year 2000 Number of Caesarean Sections in the year 2000.. Ownership

Vi har prøvd i den utstrekning det har vært mulig å kombinere dette med snn-n kontroll, men det er ikke alltid like- til.. Skal det ytes full service

Efterspørslen efter denne artikel var meget liten og dette i forbindelse med den høje saltpris bevirket, at der ikke blev tilberedt saa meget til eksport, som

FARKOSTENS LENGDE BRED BR .TONN ÅR MOTOR EIER (DEN KORRESPONDERENDE REDER) NiDNER ART OG NAVN M.. NAVN