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.
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?
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.
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.
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 HzOmrå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.)
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
MiddelverdiURMS=
fT u
2(t)dt
Effektivverdi— T
JOUd=
0,9U 5 Middelverdi, diodebru, &ifaseUd=0,9U,cos(a)
Middelverdi, tyristorbru, &ifase2wLsId 2Xkld
Kommuteringsspenningsfall, &Ifase
It n-
Is = Id
Vekselstrøm, &Ifase= °)91d
Grunnharmonisk, &ifaseUd=
1,35U 5 Middelverdi, diodebru, trefaseUd=1,35Uscos(a)
Middelverdi, tyristorbru, trefase3wLs/d
3Xkld
Kommuteringsspenningsfall, trefase
2xkid
cosii = 1
Kommuteringsvinkel. (Merk Xk= (i)Ls)
= 0,8164 Effektivverdi. Trefase vekselstrøm
41. = 0,78Id
Grunnharmonisk. Trefase vekselstrømU2 = U1D
Step-ned chopperAU2
=2
(1 D)
Rippel, step-nedU2 8LC
U2
= 1—D AU2 DTsU2 RC
Step-up
Rippel, step-up
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 f2Tem 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
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
•
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 - * * *
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
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);
}
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;
}
•
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ø))
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_*/
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)
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);
}
ø
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:
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_Ooverflow
kan tri et avbrudd hvis det eller er klargjort for detI 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:
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
tilOxFFFF
og så direkte tilbake tilOx0000 (overflow).
Timer_1realiseres ved hjelp av to sammenkoblede 8-bits tellerregistre
(TCNT1H
ogTCNT1L).
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:
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 xinput capture
register: ICR11 x ekstern telleinngang: T1 1 x ekstern
capture
inngang: ICP12 x eksterne utganger fra
output compare
enhetene: OC1A, OC1B 2 x kontrollregistre TCCR1A, TCCR1BMerk 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:
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:
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:
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:
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 tilTimer 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:
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
PORTBfor 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
LEDson
PORTBled++;
TCNT1 = 0; //
start value of T/C1 (unnecessary)
TIFR = (1 << TOV1); //
clear TOV1
I eksempelet er
TCCR1A
programmert med verdien 0 som fårTimer 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 tiloverflow
i telleren og verdien settes tilbake tilOx0000.
En
while-løkke
overvåker tilstanden tilTimer 1
ved å lese av flaggregisteretTIFR.
Det er spesielt bitTOV1
som vi er interessert i. TOV1 angir om timeren har hatt overflow. NårTOV1
inntar verdien 1, betyr det at telleren er nullstilt, ogwhile-løkken
avbrytes. Innholdet av variabelenled
(bit-invertert) sendes til PORTB.Variabelen
led
inkrementeres før flaggetTOV1
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 setningenTCNT1 = 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åroverflow
inntreffer.TOV1
blir også nullstilt automatisk, som nevnt ovenfor.FORFATTER: 63 DATO:
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
PORTBled++;
//Increment output value
TCNT1 = Ox0000;
//reload timer with initial value
int main( void )
DDRB = OxFF; //
use all pins on
PORTBfor 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/1024led = 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å snaroverflow
inntreffer, startesavbruddsfunksjonen. Det nødvendige avbruddet må åpnes i initialiseringsdelen av hovedprogrammet:
Bit
TOIE1
settes iTIMSK,
og det globale avbruddsflagget (I) må settes i statusregisteret(SREG)
vha av hjelpefunksjonensei0,
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:
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: