AVDELING FOR TEKNOLOGI PROGRAM FOR ELEKTRO- OG DATATEKNIKK Eksamensdato: 10. mai 2011 Varighet: 0900 1400 Fagnr. / navn: EDT205T MIKROPROSESSORSYSTEMER Klasse(r): 2EE Faglærer(e): Rolf Kristian Snilsberg, tlf 920 15 423 Hjelpemidler Enkel kalkulator (type C), vilkårlig lærebok i C. Oppgavesettet består av: 4 oppgaver og 27 ark inklusive vedlegg. Merknad: Øvrige opplysninger: Alle mobiltelefoner skal være avslått under hele eksamen og enten ligge i sekken/vesken eller legges på bordet til inspektørene. Den skal ikke under noen omstendighet tas med under eventuelle toalettbesøk. Kontroll av kalkulatorer kan forekomme.
Oppgave 1. (20 %) a) Hvilke minnetyper har ATmega2560 og hva brukes de til? Svar: SRAM volatilt, taper data ved strømbrudd. Lagre unna variabler + stack. Rask og direkte aksess fra cpu. 8 kbyte. Minneområdet inneholder også I/O-registre og de 32 generelle registrene. EEPROM ikke-volatilt. Parametre/tabeller/debug info som ikke skal tapes ved strømbrudd. Aksess er via I/O-registre (EECR/EEDR). Tregt å skrive/slette, 3.3ms. Lesing stopper i kodeeksekvering i 4 klokkesykler. Kan skrive til enkeltbytes. 100 000 skrivesykler. 4 kbyte. Flash Programminne. Inneholder programmet til kontrolleren. Kan også brukes til å lagre konstanter, samt evt. innsamlede data i for eksempel en datalogger. Organisert som words og på sider. 10 000 skrivesykler. Skrivetid 3.7-4.4 ms. Lese 3 klokkesykler. Atmega2560 har 256 kbyte. b) Forklar hvordan stakken fungerer og hva den brukes til. Svar: Stackpeker (SP) bestemmer hvor stakken starter i SRAM. Lagring til stakken (for eksempel PUSH r16) lagrer et generelt register på adressen til SP og dekrementer SP, mens henting fra stakk (POP) inkrementerer den og henter innholdet på adressen til et generelt register. SP initialiseres ved oppstart til siste adresse i SRAM automatisk på ATmega2560. Stacken brukes også (automatisk) for å lagre returadressen ved avbrudd og kall av subrutiner (CALL/RCALL). Brukes manuelt for hurtig mellomlagring av registre når de brukes til andre oppgaver (inkludere oftest SREG også, men må gå vi et generelt register), for eksempel i et avbrudd hvis man ikke vet om registre som er i bruk utenfor avbruddet/subrutinen. Må hentes ut i motstatt rekkefølge av de legges inn, dvs. last-in-first -out (LIFO) kø. c) Hva styrer PC (program counter). Hva slags instruksjoner modifiserer PC. Svar: PC bestemmer hvor i programminnet neste instruksjon skal hentes. Inkrementeres automatisk og avhengig av lengden på instruksjonene. Branch-instruksjone, for eksempel rjmp, sbic og brne endrer PC. PC blir lagret på stacken ved avbrudd og subrutinekall, for å blir gjenopprettet ved retur (RET/RETI);. Oppgave 2. (20 %) a) Skriv assemblyinstruksjon for å laste SREG inn i r5 (i/o-direct adressering). Svar: in r5, SREG // 1011 0AAd dddd AAAA in r5, 0x3F // 1011 0110 0101 1111 = B6 5F b) Finn operasjonskoden for instruksjonen over. Svar: d = R5 = 0b00101. A = 0x3F = 0b0011 1111. Se over. Oppgave 3. (25 %) Skriv et program i assemblykode som skal utføre følgende: PORTB (PB7:0) er utganger og tenkt koblet til lysdiodene og PA0 er inngang tenkt koblet en trykknapp, for eksempel på STK600. Til å begynne med skal alle lysdiodene være slukket. For hver gang PA0 går lav (knapp koblet til trykkes) skal verdien som vises på lysdiodene økes med en, dvs: Led7 Led6 Led5 Led4 Led3 Led2 Led1 Led0 av av av av av av av Av
av av av av av av av På av av av av av av på av av av av av av av på På osv. Legg vekt på oversiktlig programstruktur og god dokumentasjon med beskrivende kommentarer. Løsningsforslag: /************************************************************************* * Mikroprosessorsystemer * * Eksamen 2011 - oppgave 3) assembly-kode * * Høgskolen i Sør-Trøndelag - Rolf Kristian Snilsberg * * * * Device: ATmega2560 * *************************************************************************/ #include <m2560def.inc> // Task 3 start: // Set PB0 as output and all leds off (active low). ldi r16,0xff out DDRB,r16 main_loop: out PORTB,r16 /* Check if PA0 is low, i.e. button pushed. If so skip the rjmp and decrement r16, otherwise an eternal loop. */ sbic PINA, PINA0 rjmp main_loop dec r16 /* Check if PA0 is high again, i.e. button released. If so continue with main loop which outputs the result.*/ debounce: sbis PINA,PINA0 rjmp debounce // continue eternal loop. rjmp main_loop Oppgave 4. (35 %) Skriv et program i c-kode for ATmega2560 for WinAVR/GCC kompilatoren. Klokkefrekvensen antas å være 1MHz. Programmet skal utføre følgende: Bruke Timer0 til å autotrigge ADC en hvert 100ms ved help av Timer/Counter0 Compare Match A. ADC en skal sample pinne PF7/ADC7 (single ended) med intern referanse på 2.56V. Så fort resultatet er klart skal ADC avbruddet legge ut de 8 mest signifikante bit ene på PORTB (PB0-PB7). Pass på at adc klokka er innenfor gyldig område for full oppløsning. Legg vekt på oversiktlig programstruktur og god dokumentasjon med beskrivende kommentarer. Programmet bør inneholde funksjonene:
Timer0_Init() ADC_Init() ISR(ADC_vect) ISR(TIMER0_COMPA_vect) Vedlegg: AVR Instruction set, sider: 1,79. ATmega2560 datablad, sider: 1-2,12-27,70-72, 105-106,118-135, 275-295, 410-417,436-442 Løsningsforslag: /************************************************************************* * Mikroprosessorsystemer * * Eksamen 2010 - oppgave 4) c-kode * * Høgskolen i Sør-Trøndelag - Rolf Kristian Snilsberg * * * * Device: ATmega2560 * *************************************************************************/ #define F_OSC 1000000UL #define SAMPLE_PERIOD 100 // Sample period in ms #define PRESCALER 1024 // Prescaler for timer 0 #include <avr/interrupt.h> #include <avr/interrupt.h> void Timer0_Init(void); void ADC_Init(void); int main(void) ADC_Init(); Timer0_Init(); DDRB = 0xFF; PORTB = 0xFF; sei(); do asm("nop"); while(1); /* Initializes Timer 0 to CTC mode, with 1024x prescaler, OC0A interupt and 100 ms compare value. */ void Timer0_Init(void) TCCR0A = (2<<WGM00); TCCR0B = (5<<CS00); TIMSK0 = (1<<OCIE0A); OCR0A = F_OSC*SAMPLE_PERIOD/1000/PRESCALER; /* Initializes ADC with ADC7/PF7 as input. Autotrigging on Timer/ Counter0 Compare Match A. Left adjusted result. 8x prescaler, i.e 125 khz adc clock @ 1MHz. Interrupt enabled. */
void ADC_Init(void) ADMUX = (1<<ADLAR) (7<<MUX0) (3<<REFS0); // 0xE7 ADCSRA = (1<<ADEN) (1<<ADATE) (1<<ADIE) (3<<ADPS0); // 0xAB ADCSRB = (3<<ADTS0); // 0x03 DIDR0 = (1<<ADC7D); // Disable digital input buffer on ADC7 pin ISR(TIMER0_COMPA_vect) // Empty. Enabled to clear interrupt flag. ISR(ADC_vect) PORTB = ~ADCH; // Output adc result (8msb) to leds. Active low. // TIMSK0 = (1<<OCIE0A); // Alternative clearing of Compare 0 A flag.