Arduino hög hastighet oscilloskop med PC-gränssnitt (3 / 7 steg)
Steg 3: Ställa in avbrottet för programvaran utlöste version
Har man flera utmärkta instructables om att inrätta snabb datainsamling på arduino.
Jag har utvecklat följande från olika källor.
Jag använder den variabla prescalar för att styra hur ofta provtagning avbrottet.
I huvudsak vi inrätta ett avbrott som tar tag i data automatiskt i en kontrollerbar frekvens.
När det avbrott startar, data fångas i rutinen avbrott.
Om utlöser är på, data inte överförs till bufferten tills utlösande villkoret är uppfyllt.
Den analoga porten anges av den variabla adport. (ADMUX | = adport)
Frekvensen definieras med hjälp av ett prescalar. (ADCSRA register: bitar ADPS2, ADPS1 och ADPS0.)
Dessa bitar Bestäm division faktorn mellan systemet klockfrekvens och input klockan för att ADC.
.
Arduino 5V används som referens spänning. (Den REFS0 biten)
Observera att spänningen på min USB-port visas att driva min Arduino vid 4.76V.
Om jag kopplar är en strömförsörjning till Arduino "5V" linjen på 5.06V
Om du söker noggrannhet, strömförsörjning extern!.
.
Ange antalet bitar som används i analoga port capture. Hastighet som 8 bitar läses. ADLAR lite styr presentationen av ADC konvertering skriva en till ADLAR till vänster justera. I annat fall justeras värdet direkt. Detta har en omedelbar effekt på ADC Data registrera dig.
.
Som bitarna i ADCSRA för frekvens prescalar. (ADPS0, ADPS1, ADPS2 bitar)
.
Inställd på avbrottet upprepade gånger automatisk utlösare när analoga porten läses. (ADATE och Ebba Grön lite)
Möjligt för att ADC. (Den ADEN lite)
Observera användningen av funktionen sbi. Detta och cbi funktionen är mycket användbar för inställning och clearing data registrera bitar.
Börja på ADC avbryta. (ADSC lite)
.
Setup kontinuerlig läsning av adc port "adport" med ett avbrott
//
CLI(); Inaktivera avbrott så att vi kan ändra register utan att bli avbruten
Rensa ADCSRA och ADCSRB register
ADCSRA = 0;
ADCSRB = 0;
ADMUX | = adport; Ställ in kontinuerlig provtagning av analoga pin adport
ADMUX | = (1 << REFS0); ange referens spänning till AVCC
ADMUX | = (1 << ADLAR); Vänsterjustera ADC värde - så vi kan läsa högst 8 bitar från ADCH register endast
Ange prescalar. 8 är snabbast fungerande frekvens
8 prescalar 143Khz (efter acceptabla avbrott hastighetsminskning)
om (prescalar == 8) ADCSRA | = (1 << ADPS1) | (1 << ADPS0);
16 prescalar - 72 Khz provtagning
om (prescalar == 16) ADCSRA | = (1 << ADPS2);
32 prescaler - 16mHz/32 = 500 kHz - producerar 37 Khz provtagning
om (prescalar == 32) ADCSRA | = (1 << ADPS2) | (1 << ADPS0);
64 prescalar producerar 19,2 Khz provtagning
IF(prescalar==64) ADCSRA | = (1 << ADPS2) | (1 << ADPS1);
128 prescalar - 9,4 Khz provtagning om (prescalar == 128) ADCSRA | = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
ADCSRA | = (1 << ADATE); Aktivera automatisk utlösare
ADCSRA | = (1 << Ebba Grön); Aktivera ADC konvertering komplett avbrott
SBI(ADCSRA,ADEN); Aktivera ADC
ADCSRA | = (1 << ADSC); Starta ADC mätningar på avbrott
StartTime=Micros(); spela in tid så att vi kan beräkna tid och frekvens
Aktivera avbrott och ger vi iväg!
SEI();
.
Avbryta koden
Adc avbrottet är servad av rutinen ISR(ADC_vect).
Variabla bufcount är positionen i bufferten, vars storlek är BUF_SIZE (= 1000).
Flagga utlöste gäller när data kan fångas.
När bufferten är full är flaggan writeit sant och adc är inaktiveras. (cbi(ADCSRA,ADEN);)
För att utlösa avbrottet är antingen utlöste värdet true i setup och data börjar omkodning omedelbart.
Eller newval dataobjektet är jämfört med den tidigare oldval.
Om skillnaden är större än på avtryckaren, utlöste är värdet true och data sparas i bufferten.
Den variabla trigcount används för att räkna antalet data artiklar läses under utlöser.
Detta nummer läggs till buffertstorleken under frekvens beräkningen för bibehållen noggrannhet av observerade frekvensen.
.
Detta är nyckeln till programmet!
ISR(ADC_vect) {
om (utlösta) {
BUFA [bufcount] = ADCH;
bufcount ++; Increment buffert counter
om (bufcount == BUF_SIZE) {
CBI(ADCSRA,ADEN); Inaktivera ADC
EndTime=Micros(); spela in sluttid för intervall beräkning
writeit = sant; flagga att det behövs en skriva
}
} annat {
Leta efter en utlösare
newval = ADCH;
trigcount ++;
resa = newval-oldval;
IF(!trigplus) resa = - resa;
om (resa > trigger) utlöses = sant; annat oldval = newval;
}
}