Arduino Timer avbryter (4 / 6 steg)
Steg 4: Exempel 2: seriell kommunikation
För detta projekt använde jag timer2 avbrott att regelbundet kontrollera om det fanns någon inkommande seriell data, läsa den och spara den i matrisen "ledData []". Om du tar en titt på koden kommer du se att det viktigaste kretsar av skissen är vad som faktiskt ansvarar för med info i ledData att lysa upp den korrekta lysdioder och kontrollera status för knapparna (en funktion som kallas "shift()"). Rutinen avbrott är så kort som möjligt - bara kontroll för inkommande byte och lagra dem på lämpligt sätt.
Här är inställningarna för timer2:
(CLI); //stop avbrott
Ange timer2 avbryta varje 128us
TCCR2A = 0; / / Ställ in hela TCCR2A register till 0
TCCR2B = 0; / / samma för TCCR2B
TCNT2 = 0; //initialize värde till 0
Set jämför match registrera för 7,8 khz steg
OCR2A = 255; / / = (16 * 10 ^ 6) / (7812.5 * 8) - 1 (måste vara < 256)
Aktivera CTC läge
TCCR2A | = (1 << WGM21);
Ange CS21 bit för 8 prescaler
TCCR2B | = (1 << CS21);
Aktivera timern jämför avbrott
TIMSK2 | = (1 << OCIE2A);
SEI (); //allow avbrott
Här är den kompletta Arduino skissen:
KNAPPEN TEST / 74HC595 och 74HC165 och seriell kommunikation
av Amanda Ghassaei
Juni 2012
/*
* Detta program är fri programvara; Du kan vidaredistribuera det och/eller ändra
* det enligt villkoren i GNU General Public License som offentliggjorts av
* den Free Software Foundation; antingen version 2 av licensen, eller
* (på ditt alternativ) någon senare version.
*
*/
denna firmware kommer att skicka data fram och tillbaka med maxmsp patch "beat slicer"
PIN-anslutningar
#define ledLatchPin A1
#define ledClockPin A0
#define ledDataPin A2
#define buttonLatchPin 9
#define buttonClockPin 10
#define buttonDataPin A3
looping variabler
byte i.
byte j;
byte k;
byte ledByte;
lagring för ledde staterna, 4 byte
byte ledData [] = {0, 0, 0, 0};
lagring för knappar, 4 byte
byte buttonCurrent [] = {0,0,0,0}.
byte buttonLast [] = {0,0,0,0}.
byte buttonEvent [] = {0,0,0,0}.
byte buttonState [] = {0,0,0,0}.
knappen Dämpningstid counter - 16 byte
byte buttonDebounceCounter [4] [4].
void setup() {
DDRC = 0xF7; //set A0-2 och A4-5 utgång, A3-ingång
DDRB = 0xFF; //digital stift 8-13 utgång
Serial.BEGIN(57600);
(CLI); //stop avbrott
Ange timer2 avbryta varje 128us
TCCR2A = 0; / / Ställ in hela TCCR2A register till 0
TCCR2B = 0; / / samma för TCCR2B
TCNT2 = 0; //initialize värde till 0
Set jämför match registrera för 7,8 khz steg
OCR2A = 255; / / = (16 * 10 ^ 6) / (7812.5 * 8) - 1 (måste vara < 256)
Aktivera CTC läge
TCCR2A | = (1 << WGM21);
Ange CS21 bit för 8 prescaler
TCCR2B | = (1 << CS21);
Aktivera timern jämför avbrott
TIMSK2 | = (1 << OCIE2A);
SEI (); //allow avbrott
}
buttonCheck - kontrollerar status för en viss knapp.
denna buttoncheck funktion är i stort sett kopierade från monome 40h firmware brian crabtree och joe sjö
void buttonCheck (byte rad, byte index)
{
om (((buttonCurrent [rad] ^ buttonLast[row]) & (1 << index)) & & / / om det aktuella fysiska knapp läget skiljer sig från den
((buttonCurrent [rad] ^ buttonState[row]) & (1 << index))) {/ / last fysisk knapp staten och nuvarande debounced staten
om (buttonCurrent [rad] & (1 << index)) {/ / om nuläget fysisk knapp trycks
buttonEvent [rad] = 1 << index; köa upp en ny knapp händelse omedelbart
buttonState [rad] | = (1 << index); och ställa in debounced ner.
}
annat {
buttonDebounceCounter [rad] [index] = 12.
} / / annars knappen tidigare var deprimerad och nu
har släppts så vi våra debounce counter.
}
annars om (((buttonCurrent [rad] ^ buttonLast[row]) & (1 << index)) == 0 & & / / om det aktuella fysiska knapp läget är samma som
(buttonCurrent [rad] ^ buttonState[row]) & (1 << index)) {/ / den senaste fysiskt knappen stat men den nuvarande fysiskt
knappläge skiljer sig från den nuvarande debounce
statliga...
om (buttonDebounceCounter [rad] [index] > 0 & &--buttonDebounceCounter [rad] [index] == 0) {/ / om den räknaren debounce har
varit minskas till 0 (menande den
knappen har varit upp i
kButtonUpDefaultDebounceCount
iterationer / / /
buttonEvent [rad] = 1 << index; köa en knapp staten change-händelse
om (buttonCurrent [rad] & (1 << index)) {/ / och växla knapparna debounce staten.
buttonState [rad] | = (1 << index);
}
annat {
buttonState [rad] & = ~ (1 << index);
}
}
}
}
{Ogiltig shift()
för (jag = 0; jag < 4; i ++) {
buttonLast [i] = buttonCurrent [i];
byte dataToSend = (1 << (jag + 4)) | (15 & ~ ledData[i]);
ställa in spärren pin låg så lysdioderna inte ändra samtidigt skickas i bitar
digitalWrite (ledLatchPin, låg);
flytta ut bitarna av dataToSend
shiftOut (ledDataPin, ledClockPin, LSBFIRST, dataToSend);
ställa in spärren pin hög så lysdioderna kommer att få nya uppgifter
digitalWrite (ledLatchPin, hög);
När en rad har ställts in hög, ta emot data från knappar
ställa in spärren pin hög
digitalWrite (buttonLatchPin, hög);
skifta i data
buttonCurrent [i] = shiftIn (buttonDataPin, buttonClockPin, LSBFIRST) >> 3.
latchpin låg
digitalWrite (buttonLatchPin, låg);
för (k = 0; k < 4; k ++) {
buttonCheck(i,k);
om (buttonEvent [i] << k) {
om (buttonState [i] & 1 << k) {
Serial.write(((3-k) << 3) + (i << 1) + 1);
}
annat {
Serial.write(((3-k) << 3) + (i << 1) + 0);
}
buttonEvent [i] & = ~ (1 << k);
}
}
}
}
ISR(TIMER2_COMPA_vect) {
göra {
om (Serial.available()) {
ledByte = Serial.read (); //000xxyys
booleska ledstate = ledByte & 1.
byte ledy = (ledByte >> 1) & 3;
byte ledx = (ledByte >> 3) & 3;
om (ledstate) {
ledData [ledy] | = 8 >> ledx;
}
annat {
ledData [ledy] & = ~ (8 >> ledx);
}
} //end om seriell tillgängliga
} //end gör
medan (Serial.available() > 8);
}
void loop() {
Skift (); //updates lysdioder och tar emot data från knappar
}
Ladda ner MaxMSP nedanstående patch (det kommer att köras i Max Runtime också).