Miért nem működik a megszakítási kódom?

Háttér

Kódot próbálok írni egy hatcsatornás RC vevőből érkező jelek olvasására egy Arduino Mega 2560 . Jelenleg azért tartom a kódot, hogy csak egy csatornát olvassak el, hogy a dolgok könnyen elháríthatók legyenek. A probléma az, hogy a megosztott változóm nem frissül, ami azt hiheti, hogy a megszakításom A szerviz rutin nem észlel emelkedő éleket.

Úgy gondoltam, hogy a vevőm elromlott, ezért a szabványos Arduino csatolási megszakítási funkcióval teszteltem . Tökéletesen működött, így a vevőm rendben van.

A Serial.print () fájlt használtam, hogy megnézzem, frissül-e az illékony csatornaváltozóm (vagyis változtassa meg az értékét az 1. csatorna jelző értékére). Nem frissült, ezért tévesnek kell lennie az ISR -nek. Az eredeti kódot itt találja: a blogbejegyzés.

Mi a baj? Nincsenek ötleteim.

 #include <PinChangeInt.h> //Pin assignment #define channel1PIN 10 //Bit flags #define Channel1FLAG 1 //Flag holder volatile uint8_t bFLAGUPDATESHARED; //Shared variables: Accessed by the interrupt service routine and read in "void loop". volatile uint16_t unCHANNEL1SHARED; //Start time variables: These are used to set the start time of the rising edge of //a pulse. They are only accessed by the ISR, and thus they are unsigned integers and //not volatiles. uint32_t ulCHANNEL1START; void setup() { Serial.begin(9600); Serial.print("RC Channel PWM Read Interrupt Test"); //PinChangInt library function. Used to set attach interrupts. PCintPort::attachInterrupt(channel1PIN, calcCHANNEL1, CHANGE); } void loop() { //In-loop variables to hold local copies of channel inputs. //This is static so it retains values between call loops. static uint16_t unCHANNEL1IN; //The in-loop copy of the bSHAREDFLAGUPDATE volatile flag holder static uint8_t bFLAGUPDATELOCAL; //Check to see if any channels have received signals. If so, copy //shared variables to local in loop variables. if (bFLAGUPDATESHARED) { //Switch off interrupts when I copy shared variables to local variables noInterrupts(); bFLAGUPDATELOCAL = bFLAGUPDATESHARED; if (bFLAGUPDATELOCAL & Channel1FLAG) { unCHANNEL1IN = unCHANNEL1SHARED; } bFLAGUPDATESHARED = 0; interrupts(); } Serial.println(unCHANNEL1IN); //Clear local update flags copy as all values have been copied to local variables bFLAGUPDATELOCAL = 0; } void calcCHANNEL1() { if (digitalRead(channel1PIN) == HIGH) { //If pin goes high, start timer and set ulCHANNEL1START to timer start ulCHANNEL1START = micros(); } else { //If it is not rising, it must be falling so set shared //variable to current time-start time unCHANNEL1SHARED = (uint16_t)(micros() - ulCHANNEL1START); //Tell that channel 1 has received a signal bFLAGUPDATESHARED |= Channel1FLAG; } }  

Megjegyzések

  • Próbálja meg egyszerűsíteni a kódot. Kérje meg az ISR-t, hogy világítson meg például egy ledet. Nem látok ‘ semmi eredendően rosszat.
  • kitaláltam. Valamilyen oknál fogva csak a 10, 11-es és 12-es csapoknál működik. Nem tudom, miért nem. li>
  • De Ön a 10-es tűt használja? Mindenesetre; örülök, hogy működött.

Válasz

Csak néhány port az Atmega2560-on támogatja a pin-change megszakításokat, különösen a B, E (0. bit), J (bit) portokat (0-tól 6-ig) és K.

A referenciavázlatot nézve ez azt jelenti, hogy ezek a csapok a táblán támogatottak:

 Chip Name Pin Pin on board ----------------------- Port B PB0 - 19 - D53 (SS) PB1 - 20 - D52 (SCK) PB2 - 21 - D51 (MOSI) PB3 - 22 - D50 (MISO) PB4 - 23 - D10 PB5 - 24 - D11 PB6 - 25 - D12 PB7 - 26 - D13 Port E PE0 - 2 - D0 (RXD0) Port J PJ0 - 63 - D15 (RXD3) PJ1 - 64 - D14 (TXD3) PJ2 to PJ6 - not connected on board Port K PK0 - PK7 - (89 - 82) - A8 - A15 

Így láthatja, hogy a D10-től D12-ig, amely szerinte működik, szerepel ebben a listában. Más véletlenszerűek nem lennének.


SoftwareSerial

Megerősítést láthat a SoftwareSerial oldalon, ahol ez áll:

A Mega és a Mega 2560 támogatás nem minden csapja megszakítja a megszakítást, így az RX-hez csak a következők használhatók: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

Ennek oka, hogy a SoftwareSerial pin-change megszakításokat használ a bejövő soros adatok észleléséhez, és így az adott oldalon található felelősség kizárását arról, hogy melyik csapokkal fog működni.


Atmega2560 kivezetések

Atmega2560 kitűzések


A PinchangeInt-nek működnie kell bármely digitális tűn

Ne feledje, hogy az Atmega328P (az Uno-ban használt módon) kevesebb porttal rendelkezik, és mindegyik rendelkezésre áll pin-change megszakításokra az adott táblán.

Megjegyzések

  • Ez ‘ nem lehet igaz. Az OP 2., 3., 18., 19., 20. és 21. csapok által először linkelt oldal megszakításokra használható. Ezek leképezik a PE4, PE5, PD3, PD2, PD1 és PD0 elemeket a goo.gl/DvHEUA és goo.gl/xAwBGM A magam részéről ‘ m jobban egyetértek azzal, hogy használható-e a PORTC, mint a ros_arduino_bridge-ben: goo.gl/rq6yQO
  • A linkelt oldal külső megszakításokra utal, azonban az OP a tűváltást megszakításként használja. a #include <PinChangeInt.h> oldalról láthatja. A csapváltó megszakító csapok azok, amelyeket felsoroltam.
  • Látom. Volt egy elképzelésem, amely lehet a megkülönböztetés, de azt feltételeztem, hogy minden külső megszakításra képes csap is képes lesz a tűcserére, bár nem fordítva.

Válasz

Az ATmega1280 / 2560-on csak a B, J, F és K port rendelkezik tűváltási megszakítási képességgel. Ezek hozzávetőlegesen a 10–15, az 50–53 és az A6 – A15 érintkezőkhöz kapcsolódnak (bár a J port egy része nincs hozzárendelve az Arduino csapokhoz, ezért a PCINT11 – PCINT15 nem érhető el az Arduino Mega / Mega 2560 készülékeken).

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük