Programmering for begyndere Brug af Arduino Programmeringskursus Interrupt - Arduino EDR Hillerød Knud Krogsgaard Jensen / OZ1QK
Interrupts Programmeringskursus Genbrug Interrupts Betyder blot at man afbryder det man er i gang med. Afbrydelse sker på maskinkode niveau, ikke i C-koden. Interrupts udnyttes Når man skal reagere med noget som indtræffer sjældent - man er fri for at holde øjet hele tiden. Når noget indtræffer som kræver øjeblikkelig handling. F.eks. et signal / en tilstand der kun er der kortvarigt Man kan vælge at se bort fra interrupts i kritiske dele af programmet.
Interrupts Intern og ekstern interrupt Intern interrupt er styret fra en timer startet af et program Kunne bruges ved en frekvenstæller Kunne være en stepmotor som skulle have et skub med bestemte intervaller Alt sammen noget hvor vi måske er i gang med noget andet når det skal ske. Det er emnet for næste gang Ekstern interrupt er styret fra ekstern hardware Kunne være impulser fra noget der drejer rundt Kunne være signal fra et tastatur, trykknap Alt sammen noget hvor vi skal reagere hurtigt uanset hvad programmet ellers laver og signalet måske kun er der kortvarigt. Det er emnet for nu.
Interrupts Ved interrupt skal der ske følgende: Programmet skal afbryde, det som er i gang Programmet skal finde ud af hvad det er, som kræver opmærksomhed Programmet skal tage hånd om hændelsen Programmet skal vende tilbage til det som var i gang. Set fra mikroprocessoren er problemet det samme om det er et internet eller et eksternt interrupt. Der er et vi kender godt: RESET og er bl.a. Power-on Reset,
Interrupt Programmeringskursus Den lette eksterne interrupt De digitale ind- udgange analoge udgange: Pin / ben Dig. ind/ud Anal. udg. 0 RX 1 TX 2 Ext intr 0 3 Ext intr 1 PWM 4 5 PWM 6 PWM 7 Pin / ben Dig. ind/ud Anal. udg. 8 9 PWM 10 PWM 11 PWM 12 13 (Diode) 5
Interrupt Fra program til hardware Programmeringskursus Styr på det med hardware Når vil vil bruge eksternt interrupt må vi genoverveje brug af ben på Arduino. Hidtil har vi defineret vores display ved følgende kommando: LiquidCrystal lcd(12, 11, 5, 4, 3, 2); Hvad er det nu det betyder. Lad os lige se på syntaksen:
Interrupt Programmeringskursus Fra program til hardware LiquidCrystal lcd(12, 11, 5, 4, 3, 2); betyder Ben 0 RX 1 TX 2 Ext intr 0 3 Ext intr 1 PWM Display d7 d6 4 d5 5 PWM d4 6 PWM 7 Ben 8 9 PWM 10 PWM Display 11 PWM Enable 12 RS 13 Det er vanskeligt at anvende ekstern interrupt 7
Display Arduino Programmeringskursus Genbrug LiquidCrystal() Syntaks LiquidCrystal(rs, enable, d4, d5, d6, d7) LiquidCrystal(rs, rw, enable, d4, d5, d6, d7) Ofte brugt med rw til stel LiquidCrystal(rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) LiquidCrystal(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) RS = 0 : Kommandoer (CGRAM) RS = 1 : Tegn der vises på display (DDRAM) enable : Angive at data er stabile Det tager vores C- kommandoer sig af 8
Interrupt Programmeringskursus Fra program til hardware Forslag: LiquidCrystal lcd(12, 11, 6, 5, 4, 3); Ben 0 RX 1 TX 2 Ext intr 0 3 Ext intr 1 PWM Display d7 4 d6 5 PWM d5 6 PWM d4 7 Ben 8 9 PWM 10 PWM Display 11 PWM Enable 12 RS 13 Nu kan ben 2 bruges til ekstern interrupt. 9
Interrupt - Software Ekstern interrupt Et interrupt er mulig efter følgende sætning i programmet, normalt i setup(): attachinterrupt(interrupt, funktion, mode) hvor: interrupt : Interrupt nummer. funktion : Funktion som kaldes når interrupt indtræffer. mode : Den hændelse som skal aktiver interrupt. Det tager vi lidt efter lidt. Der er faktisk også detachinterrupt(interrupt) ikke så vigtig
Interrupt - Software Beskrivelse af (for Arduino): attachinterrupt(interrupt, funktion, mode); Det kikker vi på om lidt. interrupt : værdi 0 eller 1 (Svarer til ben 2 hhv. ben 3) funktion : Navnet på den funktion, som skal aktiveres når der indtræder et interrupt. (Interrupt Service Routine - ISR). mode : Interrupt hændelse. Kan antage værdierne LOW : Interrupt når ben er lav. CHANGE : Interrupt når benet ændre sig. RISING : Interrupt når benet går fra lav til høj FALLING : Interrupt når benet går fra høj til lav.
Interrupt - Software Eksempel på interrupt definition attachinterrupt(0, handling, FALLING); Dette betyder at interrupt sker når der indtræffer ben 2 går fra høj til lav. Det er funktionen handling() som kaldes. Denne funktion skal være af typen void handling(), Dvs. returnerer ingenting og har ikke nogen argumenter. Så længe handling() er kaldt udsættes andre interrupts. Det kan have betydning hvis begge interrupts benyttes, eller nogle af timer funktionerne bruges. Bør (skal) være kort.
Interrupt - Software Eksempel /* Ændre LED på ben 13 når interrupt på ben 2 aktiveres */ int LED = 13; volatile int state = LOW; void setup() { pinmode(led, OUTPUT); attachinterrupt(0, blink, CHANGE); } void blink() { state =!state; } void loop() { /* her kunne være masser af kode */ digitalwrite(led, state); } Det er altså i denne kode der kan ske Interrupt, selvom der intet står her om interrupt.
Interrupt - Software Om Interrupt Service Rutinen (ISR) I det foregående var det funktionen handling() og i programmet blink(). Om den gælder Variable som ændres under interrupt skal være volatile, dvs. variablen skal bevares fra kald til til kald. Den skal findes i RAM, ikke på stakken. Interrupt service rutinen har intet argument. Interrupt service rutinen bør være kort, fordi så længe den er kaldt vil Arduino ikke reagere på interrupts.
Interrupt - Software Hvad sker der når vi afbryder noget? Vi skal se på hvorledes vi afbryder et program og kan vende tilbage til det og fortsætte som ingen ting var hændt. HUSK: Det er på maskinkode niveau vi afbryder dvs. inden for 64 µs. - Det vil sige det er en relativt simpelt proces vil afbryder det er noget med at flytte data rundt. Problem: Hvad skal der til for at kunne genoptage afviklingen af programmet igen? Det viser sig at det vigtigste / eneste er SREG status registeret.
Interrupt SREG indeholder en række oplysninger om status: Bit Navn 7 I Global Interrupt Enable 6 T Bit Copy Storage 5 H Half Carry Flag - Carry in some arithmetic operations 4 S Sign Bit, S = N V 3 V Two s Complement Overflow Flag 2 N Negative Flag indicates a negative result in an arithmetic operation. 1 Z Zero Flag - in an arithmetic or logic operation 0 C Carry Flag - in an arithmetic or logic operation Problemet er at det der sker under interrupt kan overskrive SREG og dermed vil brogramafviklingen gå i kludder når interrupt afsluttes.
Interrupt Gemme SREG void loop() { uint8_t oldsreg = SREG; cli(); Pos = encoderpos; SREG = oldsreg;...// mere kode } Kritisk instruktion Her gemmers SREG Her hindres (disables) Interrupt Her flyttes SREG tilbage og automatisk enables interrupt Jeg vil foreslå at vi kikker på det program hvorfra koden kommer. Først noget lidt andet
Interrupt Kritiske dele af programmet Som vi lige har set kan der være dele af programmet hvor vi ikke ønsker interrupt. Umiddelbart er der følgende funktioner til dette brug: nointerrupts() : Disabler interrupt. Visse timer funktioner virker heller ikke og indkommende seriekommunikation afbrydes også interrupts() : Enabler interrupt igen
Interrupt Knapt så godt dokumenteret er: cli(): Disabler interrupt. Nu kan SREG gemmes. Når SREG reetableres ved at gemme noget i SREG, enables interrupt igen. sei(): Enabler interrupt igen. Disse funktioner er direkte hentet fra maskininstruktionerne for ATmega328P og de funger tilsyneladende.
Interrupt Eksempel Programmeringskursus /*RotaryEncoderInterrupt sketch*/ const int encoderpina = 2; const int encoderpinb = 4; int Pos, oldpos; volatile int encoderpos = 0; void setup() { pinmode(encoderpina, INPUT); pinmode(encoderpinb, INPUT); digitalwrite(encoderpina, HIGH); digitalwrite(encoderpinb, HIGH); Serial.begin(9600); attachinterrupt(0, doencoder, FALLING); } Her etableres interrupt. void loop() { uint8_t oldsreg = SREG; cli(); Pos = encoderpos; SREG = oldsreg; if(pos!= oldpos) { Serial.println(Pos,DEC); oldpos = Pos; } delay(1000); /* her kunne laves meget mere kode. F.eks. udlæsning til display*/ } Her kan interrupt ske Kritisk kode
Interrupt Eksempel forsat Programmeringskursus void doencoder() { if (digitalread(encoderpina) == digitalread(encoderpinb)) encoderpos = encoderpos +1; // tæller op hvis benene er ens else encoderpos = encoderpos - 1; // Tæller ned hvis benene er forskellige } Forklaring næste overhead
Interrupt Eksempel forsat Programmeringskursus Programmet forudsætter en enkoder som denne: Signal A Signal B Bevægelsesretning På faldende flanke er de forskellige
Interrupt Eksempel forsat Programmeringskursus Programmet forudsætter en enkoder som denne: Signal A Signal B Bevægelsesretning På faldende flanke er de ens
Interrupt Interrupt prioritet: Arduino (Atmega328P) har 26 niveauer for interrupt. Vector No. Souce Interrupt Definition 1 RESET External Pin, Power-on Reset, Brown-out Reset and Watchdog System Reset 2 INT0 External Interrupt Request 0 3 INT1 External Interrupt Request 1 4 PCINT0 Pin Change Interrupt Request 0 5 PCINT1 Pin Change Interrupt Request 1 6 PCINT2 Pin Change Interrupt Request 2 7 WDT Watchdog Time-out Interrupt 8-17 Forskellige timere 19-26 Oplysninger om USART,