Avbrottshantering Övningsuppgifter 2013 Lösningsförslag Uppgift 1-19 (eservation för diverse fel!)
1 Koppling: Q 1 Till bit 0 INPOT ÖKA A 1 /W 1 Write 8FF 16 NOLLA Write 8FFF 16 Q 2 1 Q 2 Till bit 1 INPOT IQ Avbrottsrutin (Interrupt handler) IQ LDAA INPOT (INPOT = $900) BITA #%00000001 Bit 0 är ansluten till ÖKA-vippan BN IQINC BITA #%00000010 Bit 1 är ansluten till NOLLA-vippan BN IQCL IQX TI * Avbrottsservicerutin för öka IQINC STAA $8FF Nollställ avbrottsvippa nr 1 LDAA KNAPP CMPA #255 Maxvärde? BQ IQX Ja, skippa ökning INC KNAPP BA IQX * Avbrottsservicerutin för nollställ IQCL STAA $8FFF Nollställ avbrottsvippa nr 2 CL KNAPP Nollställ KNAPP BA IQX
2 Koppling: Q 1 Till bit 0 INPOT ÖKA A 1 /W 1 Write 8FF 16 MINSKA Write 8FFF 16 Q 2 1 Q 2 Till bit 1 INPOT IQ Avbrottsrutin (Interrupt handler) IQ LDAA INPOT (INPOT = $900) BITA #%00000001 Bit 0 är ansluten till öka-vippan BN IQINC BITA #%00000010 Bit 1 är ansluten till minska-vippan BN IQDC IQX TI * Avbrottsservicerutin för öka IQINC STAA $8FF Nollställ avbrottsvippa nr 1 LDAA KNAPP CMPA #255 Maxvärde? BQ IQX Ja, skippa ökning INC KNAPP BA IQX * Avbrottsservicerutin för minska IQDC STAA $8FFF Nollställ avbrottsvippa nr 2 TST KNAPP KNAPP = 0? BQ IQX Ja, skippa minskning DC KNAPP BA IQX
3 Koppling: ÖKA Q 0 Till INPOT bit 0 CS Adr0 CS Adr1 MITT Q 1 Till INPOT bit 1 1 IQ MINSKA Q 2 Till INPOT bit 2 CS Adr2 Avbrottsrutin (Interrupt handler) IQ LDAA INPOT (INPOT = $900) BITA #%00000001 Bit 0 är ansluten till ÖKA-vippan BN IQINC BITA #%00000010 Bit 1 är ansluten till MITT-vippan BN IQMID BITA #%00000100 Bit 2 är ansluten till MINSKA-vippan BN IQDC IQX TI * Avbrottsservicerutin för öka IQINC STAA Adr0 Nollställ avbrottsvippa nr 0 LDAA KNAPP CMPA #255 Maxvärde? BQ IQX Ja, skippa ökning INC KNAPP BA IQX * Avbrottsservicerutin för mittvärde IQMID STAA Adr1 Nollställ avbrottsvippa nr 1 MOVB #128,KNAPP Sätt KNAPP till mittvärde BQ IQX * Avbrottsservicerutin för minska IQDC STAA Adr2 Nollställ avbrottsvippa nr 2 TST KNAPP KNAPP = 0? BQ IQX Ja, skippa minskning DC KNAPP BA IQX
4 Koppling: Händelse 0 Q 0 Till INPOT bit 0 CS Adr0 CS Adr1 Händelse 1 Q 1 Till INPOT bit 1 1 IQ Händelse 2 Q 2 Till INPOT bit 2 CS Adr2 Avbrottsrutin (Interrupt handler) IQ LDAA INPOT (INPOT = $0D0) BITA #%00000001 Bit 0 är ansluten till Händelse 0-vippan BN IQV0 BITA #%00000010 Bit 1 är ansluten till Händelse 1-vippan BN IQV1 BITA #%00000100 Bit 2 är ansluten till Händelse 2-vippan BN IQV2 IQX TI * Avbrottsservicerutin för Händelse 0 IQV0 STAA Adr0 Nollställ avbrottsvippa nr 0 INC VCNT0 8-bitars räknare BA IQX * Avbrottsservicerutin för Händelse 1 IQV1 STAA Adr1 Nollställ avbrottsvippa nr 1 LDX VCNT1 16-bitars räknare INX STX VCNT1 BQ IQX * Avbrottsservicerutin för Händelse 2 IQV2 STAA Adr2 Nollställ avbrottsvippa nr 2 LDX VCNT2+2 32-bitars räknare, låg del INX STX VCNT2+2 BN IQX Carry till hög del = 0 LDX VCNT2 Carry till hög del = 1 INX STX VCNT2 BA IQX VCNT0 (DC00 16 ) VCNT1 VCNT2 VCNT2+2 ms ls ms ls Subrutin för initiering av variabler och avbrottssystem INIQ CL Adr0 Nollställ avbrottsvippor CL Adr1 CL Adr2 CL VCNT0 Nollställ variabler MOVW #0,VCNT1 MOVW #0,VCNT2 MOVW #0,VCNT2+2 MOVW #IQ,$FFF2 TS Avbrottsvektor
5 Koppling: A 10 A 9 CS IQ_AD 250 Hz Q IQ A 8 A 7 /W Avbrottsrutin IQ TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) DC IQCNT Avbrottsräknare BN IQX j 1s, hoppa ut MOVB #250,IQCNT Ominitiera avbrottsräknare MOVB SNS,$D00 Läs givaren och uppdatera värdet IQX TI IQCNT MB 1 Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) MOVB #250,IQCNT Initiera avbrottsräknare för 1s MOVW #IQ,$FFF2 Avbrottsvektor
6 Koppling: A 10 A 9 CS IQ_AD 50 Hz Q IQ A 8 A 7 /W Avbrottsrutin IQ TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) DC IQCNT Avbrottsräknare BN IQX j 1s, hoppa ut MOVB #50,IQCNT Ominitiera avbrottsräknare MOVB $600,$2800 Läs givaren och uppdatera värdet IQX TI IQCNT MB 1 Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) MOVB #50,IQCNT Initiera avbrottsräknare för 1s MOVW #IQ,$FFF2 Avbrottsvektor
7 Antag att varje händelse genererar en puls Huvudprogrammet: (Stackpekaren antas vara initierad tidigare) Huvudprogrammet måste initiera avbrottssystemet, dvs se till att hopp görs till avbrottsrutinens adress vid avbrottsförfrågan (IQ) genom att skriva in adressen till avbrottsrutinen IQ-vektorn ventuella variabler som kan behövas av servicerutinerna för de fyra olika avbrottskällorna måste också initieras Avbrottsvipporna skall nollställas för att falska avbrott inte skall uppträda vid startsom sista åtgärd skall avbrottsystemet aktiveras genom att I-flaggan i CC-registret nollställs Avbrottsrutinen: Avbrottsrutinen måste först identifiera avbrottskällan genom att läsa av vilket Q i -värde enligt figuren nedan som är aktivt och sedan hoppa till aktuell servicerutin I servicerutinen skall de uppgifter utföras som är förknippade med det aktuella avbrottet Före återhopp till avbrottsrutinen och senare återhopp till det avbrutna programmet med TI måste också avbrottsvippan nollställas med en puls på vippans ST-ingång genom att en läsning eller skrivning görs på aktuell adress enligt figuren nedan Koppling: Händelse 0 Q 0 Till INPOT bit 0 CS Adr0 CS Adr1 Händelse 1 Q 1 Till INPOT bit 1 1 IQ Händelse 2 Q 2 Till INPOT bit 2 CS Adr2 Händelse 3 Q 3 Till INPOT bit 3 CS Adr3
8 Antag att varje händelse genererar en puls Huvudprogrammet: (Stackpekaren antas vara initierad tidigare) Huvudprogrammet måste initiera avbrottssystemet för både XIQ- och IQ-avbrott, dvs se till att hopp görs till respektive avbrottsrutins adress vid avbrottsförfrågan (XIQ eller IQ) genom att skriva in adressen till XIQ-rutinen i XIQ-vektorn ($FFF4) och adressen till IQ-rutinen i IQ-vektorn ($FFF2) ventuella variabler som kan behövas av servicerutinerna för de olika avbrottskällorna måste också initieras Avbrottsvipporna skall nollställas för att falska avbrott inte skall uppträda vid start Som sista åtgärd skall avbrottsystemet aktiveras genom att X- och I-flaggan i CC-registret nollställs Avbrottsrutinen (IQ): ftersom det bara finns en avbrottskälla för IQ kan man i avbrottsrutinen IQ direkt utföra de uppgifter som är förknippade med det aktuella avbrottet, inklusive eventuella ominitieringar av variabler som används av avbrottsrutinen Före återhopp till det avbrutna programmet från IQrutinen med TI måste IQ-avbrottsvippan nollställas med en CS -puls på vippans ST-ingång genom att en läsning eller skrivning görs på den adress man har valt för detta ändamål I detta fall kan man t ex bilda CS -signalen genom att avkoda läsning av IQ-vektorn och då sker nollställningen av avbrottsvippan automatiskt då IQ-avbrottet accepteras Om en begäran om XIQ-avbrott kommer medan IQ-avbrottet behandlas så avbryts IQ och XIQ-rutinen tar över Återhopp görs sedan till IQ med TI i XIQ-rutinen
9 Koppling: A 10 A 9 CS IQ_AD 100 Hz Q IQ A 8 A 7 /W Avbrottsrutin IQ TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) LDX IQCNT Hämta avbrottsräknare DX STX IQCNT Uppdatera avbrottsräknare BN IQX j 1 min, hoppa ut MOVW #6000,IQCNT Ominitiera avbrottsräknare CL ADSTT MOVB #$80,ADSTT Positiv flank på bit 7 startar AD-omvandling ILOOP TST ADSTAT Bit 7 = 1? BPL ILOOP Nej, vänta MOVB PSS,CUP Ja Läs givaren och uppdatera värdet IQX TI IQCNT MB 2 Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) MOVW #6000,IQCNT Initiera avbrottsräknare för 1 min MOVW #IQ,$FFF2 Avbrottsvektor
10 Koppling: Q 1 eady 1 Write 8FF 16 Q 2 1 IQ A 1 /W 50 Hz Write 8FFF 16 Avbrottsrutin (Interrupt handler) IQ LDAA ADSTAT Läs eady-signal på bit 0 BITA #%00000001 eady = 1? BN IAD Ja, A/D-omvandling färdig CL $8FFF Nej, alltså 50 Hz avbrott Nollställ avbrottsvippa 2 LDX IQCNT 50 Hz-avbrott, hämta avbrottsräknare DX STX IQCNT Uppdatera avbrottsräknare BN IQX j 10 min, hoppa ut MOVW #30000,IQCNT Ominitiera avbrottsräknare för 10 min och starta ADC MOVB #1,ADCTL Negativ flank på bit 0 startar AD-omvandling CL ADCTL som ger nytt avbrott om ca 100 mikrosek IQX TI IAD CL $8FF Nollställ avbrottsvippa 1 MOVB LVL,NWLW Läs nivå och uppdatera Nollställ också eady BA IQX IQCNT MB 2 Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) CL $8FF Nollställ avbrottsvipporna CL $8FFF MOVW #30000,IQCNT MOVW #IQ,$FFF2 Initiera avbrottsräknare för 10 min Avbrottsvektor
11 Koppling: Q 1 Till bit 0 på inport DOO 50 Hz A 1 /W 1 Write 8FF 16 Dörrpuls Write 8FFF 16 Q 2 1 Q 2 Till bit 1 på inport DOO IQ Avbrottsrutin (Interrupt handler) IQ LDAA DOO Läs avbrottsvippor BITA #%00000001 Bit 0 är ansluten till 50 Hz-vippan BN IQ50HZ BITA #%00000010 Bit 1 är ansluten till Dörr-vippan BN IQD IQX TI * Avbrottsservicerutin 50 Hz IQ50HZ STAA $8FF Nollställ 50Hz-vippan LDX IQCNT 50 Hz-avbrott, hämta avbrottsräknare DX STX IQCNT Uppdatera avbrottsräknare BN IQX j 1 min, hoppa ut MOVW #3000,IQCNT Ominitiera avbrottsräknare för 1 min MOVB AI,FLOW Läs tryck och uppdatera BA IQX * Avbrottsservicerutin för DOO IQD STAA $8FFF Nollställ DOO-vippan MOVB DOO,POS Läs dörrposition och uppdatera BA IQX Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) CL $8FF Nollställ avbrottsvipporna CL $8FFF MOVW #3000,IQCNT Initiera avbrottsräknare för 1 min MOVW #IQ,$FFF2 Avbrottsvektor OG $1FF0 IQCNT MB 2
12 Koppling: A 10 A 9 CS IQ_AD 50 Hz Q IQ A 8 A 7 /W Avbrottsrutin IQ TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) DC ICNT1 Avbrottsräknare för tiondels sekund BN CHK1S j tiondels sekund, kolla om 1 sekund har gått MOVB #5,ICNT1 Ominitiera avbrottsräknare för tiondels sekund MOVB POT1,GIV1 Läs givaren och uppdatera värdet CHK1S DC ICNT2 Avbrottsräknare för 1 sekund BN IQX j 1 sekund, hoppa ut MOVB #50,ICNT2 Ominitiera avbrottsräknare för 1 sekund MOVB POT2,GIV2 Läs givaren och uppdatera värdet IQX TI Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) MOVB #5,ICNT1 Initiera avbrottsräknare för tiondels sekund MOVB #50,ICNT2 Initiera avbrottsräknare för 1s MOVW #IQ,$FFF2 Avbrottsvektor OG $1FF0 ICNT1 MB 1 äknare för tiondels sekund ICNT2 MB 1 äknare för en sekund
13 Koppling: 100 Hz Q 1 Till bit 7 på inport JOY A 1 /W 1 Write 8FF 16 Knappuls Write 8FFF 16 Q 2 1 Q 2 Till bit 6 på inport JOY IQ Avbrottsrutin (Interrupt handler) IQ LDAA JOY Läs avbrottsvippor BITA #%10000000 Bit 7 är ansluten till 100 Hz-vippan BN INT100 BITA #%01000000 Bit 6 är ansluten till Knapp-vippan BN IKNP IQX TI * Avbrottsservicerutin 100 Hz INT100 STAA $8FF Nollställ 100Hz-vippan DC IQCNT 100 Hz-avbrott, hämta avbrottsräknare BN IQX j 20-dels sekund, hoppa ut MOVB #5,IQCNT Ominitiera avbrottsräknare för 20-dels sekund MOVB JOY,JSTICK Läs av joysticksläge och uppdatera BA IQX * Avbrottsservicerutin för tryckknapp IKNP STAA $8FFF Nollställ Knapp-vippan INC KNAPP Uppdatera antal knapptryckningar BA IQX Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) CL $8FF Nollställ avbrottsvipporna CL $8FFF MOVB #5,IQCNT Initiera avbrottsräknare för 20-dels sekund CL KNAPP Nollställ antal knapptryckningar MOVW #IQ,$FFF2 Avbrottsvektor OG $1FF0 IQCNT MB 1
14 Koppling: A 10 A 9 CS IQ_AD 50 Hz Q IQ A 8 A 7 /W Avbrottsrutin IQ TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) DC IQCNT Avbrottsräknare BN IQX j 1s, hoppa ut MOVB #50,IQCNT Ominitiera avbrottsräknare MOVB SNS,$D00 Läs givaren och uppdatera värdet IQX TI IQCNT MB 1 Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) MOVB #50,IQCNT Initiera avbrottsräknare för 1s MOVW #IQ,$FFF2 Avbrottsvektor
15 Koppling: Q CS INPOT 30 Hz IQ Avbrottsrutin IQ MOVB INPOT,INVA Uppdatera INVA och nollställ avbrottsvippan DC COUNT Avbrottsräknare för tiondels sekund BN IQX j tiondels sekund Hoppa ut MOVB #3,COUNT Ominitiera avbrottsräknare för tiondels sekund JS OUTPUT Sköter utmatning till utport IQX TI Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST INPOT Nollställ avbrottsvippan MOVB #3,COUNT Initiera avbrottsräknare för tiondels sekund MOVW #IQ,$FFF2 Avbrottsvektor
16 Koppling: A 10 A 9 A 8 A 7 /W Avbrottsrutin CS IQ_AD 50 Hz IQ TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) DC COUNT Avbrottsräknare BN IQX j 1s, hoppa ut MOVB #50,COUNT Ominitiera avbrottsräknare LDAA CLOCK+2 Hämta sekundvärdet ADDA #1 n sekund till DAA Decimaljustera STAA CLOCK +2 Uppdatera sekundvärdet CMPA #$60 Hel minut? BN SHOW Nej, visa tid CL CLOCK +2 Ja, nollställ sekundvärdet LDAA CLOCK +1 Hämta minutvärdet ADDA #1 n minut till DAA Decimaljustera STAA CLOCK +1 Uppdatera minutvärdet CMPA #$60 Hel timma? BN SHOW Nej, visa tid CL CLOCK +1 Ja, nollställ minutvärdet LDAA CLOCK Hämta timvärdet ADDA #1 n timma till DAA Decimaljustera STAA CLOCK Uppdatera timvärdet CMPA #$24 Helt dygn? BN SHOW Nej, visa tid CL CLOCK Ja, nollställ timvärdet SHOW MOVB CLOCK,TIM Visa timvärdet MOVB CLOCK+1,MIN Visa minutvärdet MOVB CLOCK+2,SK Visa sekundvärdet IQX TI Q IQ Initiering av variabler och avbrottssystem (Stackpekaren antas initierad tidigare) TST $24FF Nollställ avbrottsvippan (T ex adr $24FF enligt figuren) MOVB #50,COUNT Initiera avbrottsräknare för 1s CL CLOCK Nollställ timvärdet CL CLOCK +1 Nollställ minutvärdet CL CLOCK +2 Nollställ sekundvärdet MOVW #IQ,$FFF2 Avbrottsvektor
17 UTPOT QU $3000 Utport för ASCII-tecken till skrivare Subrutin för initiering av avbrottsstyrd utmatning av en textsträng INIST CL UTPOT Nollställ avbrottsvippan STX STPNT Initiera global pekare till textsträng MOVW #PINT,$FFF2 Avbrottsvektor TS Avbrottsrutin för utmatning av textsträng till skrivare PINT LDX STPNT Hämta pekare till textsträng LDAA 1X+ Hämta tecken från textsträng STAA UTPOT Mata ut ASCII-tecken och nollställ avbrottsvippa BN PIX Uthopp om ej strängslut MOVB #$FF,FLAG Signalera klart till huvudprogram PULA Hämta CC-värde från stack OAA #$10 Sätt I = 1 (Stäng av avbrott) PSHA Skriv tillbaka CC-värde till stack PIX STX STPNT Uppdatera pekare till textsträng TI
18 Koppling: CS IQ_AD 200 Hz Q IQ /W BOS0 QU $1FF0 BOS för program P0 BOS1 QU $2FF0 BOS för program P1 STAT0 QU $1000 Startadress för program P0 STAT1 QU $2000 Startadress för program P1 IQS QU $8FFF Läsadress för nollställning av IQ-vippa IQVC QU $FFF2 Avbrottsvektorn GLOBAL QU $1FF0 (Denna krockar inte med BOS0 ovan!) OG STAT0 P0 MOVB #$C0,BOS1-9 CC till stack1 MOVW #STAT1,BOS1-2 Startadress för program P1 till stack1 MOVW #BOS1-9,SPSAV Stackpekarvärde efter avbrott till stack1 LDS #BOS0 Initiera stack för program 0 TST IQS Nollställ avbrottsvippan MOVW #IQ,IQVC Initiera IQ-vektorn et P0LOOP NOP BA P0LOOP vighetsslinga i P0 OG STAT1 P1 NOP vighetsslinga i P1 BA P1 IQ TST IQS Nollställ avbrottsvippan LDX SPSAV Hämta den andra stackpekaren STS SPSAV Spara den aktiva stackpekaren TF X,SP Byt stackpekare TI Återvänd till det andra programmet OG GLOBAL SPSAV MB 2 Plats för den passiva (andra) stackpekaren
19 Koppling: CS IQ_AD 200 Hz Q IQ /W BOS0 QU $8000 BOS för program P0 BOS1 QU $C000 BOS för program P1 STAT QU $1000 Startadress för program PINIT (t ex) STAT0 QU $4000 Startadress för program P0 STAT1 QU $8000 Startadress för program P1 IQS QU $8FFF Läsadress för nollställning av IQ-vippa IQVC QU $FFF2 Avbrottsvektorn GLOBAL QU $2000 OG STAT PINIT MOVB #$C0,BOS1-9 CC till stack1 MOVW #STAT1,BOS1-2 Startadress för program P1 till stack1 MOVW #BOS1-9,SPSAV Stackpekarvärde efter avbrott till stack1 LDS #BOS0 Initiera stack för program 0 TST IQS Nollställ avbrottsvippan MOVB #0,TOGGL För att välja varannat avbrott MOVW #IQ,IQVC Initiera IQ-vektorn et LBA P0 OG STAT0 P0 NOP vighetsslinga i P0 BA P0 OG STAT1 P1 NOP vighetsslinga i P1 BA P1 IQ TST IQS Nollställ avbrottsvippan COM TOGGL ndast processbyte vartannat avbrott BQ IQX j processbyte LDX SPSAV Processbyte, hämta den andra stackpekaren STS SPSAV Spara den aktiva stackpekaren TF X,SP Byt stackpekare IQX TI Återvänd till det andra programmet OG GLOBAL TOGGL MB 1 SPSAV MB 2 Plats för den passiva (andra) stackpekaren