Miksi keskeytyskoodini ei toimi?

Tausta

Yritän kirjoittaa koodia lukemaan signaaleja kuusikanavaisesta RC-vastaanottimesta Arduino Mega 2560 . Tällä hetkellä pidän koodia vain lukemaan yhden kanavan, jotta asioiden vianmääritys olisi helppoa. Ongelmana on, että jaettu muuttujani ei päivity, mikä saa minut uskomaan, että keskeytykseni Huoltorutiini ei havaitse nousevia reunoja.

Luulin, että vastaanotin oli rikki, joten testasin sen käyttämällä normaalia Arduino-liitäntäkatkaistutoimintoa . Se toimi täydellisesti, joten vastaanotin on kunnossa.

Käytin Serial.print () nähdäksesi, päivittyykö haihtuva kanavamuuttujani (ts. muuta sen arvo kanavan 1 lippuarvoksi). Se ei päivittynyt, joten ISR: n on oltava väärä. Löydät alkuperäisen koodin blogiviesti.

Mikä vikaa? Minulla ei ole ideoita.

 #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; } }  

Kommentit

  • Yritä yksinkertaistaa koodiasi. Pyydä ISR: tä esimerkiksi sytyttämään led. En näe ’ mitään väärää luonnetta.
  • Sain sen selville. Jostain syystä se toimii vain nastoilla 10,11 ja 12. En tiedä miksi. PinchangeIntin pitäisi toimia minkä tahansa digitaalisen nastan kanssa

. li>

  • Mutta käytätkö neulaa 10? Joka tapauksessa; iloinen, että sait sen toimimaan.
  • Vastaa

    Vain jotkut -portit Atmega2560-laitteessa tukevat pin-change-keskeytyksiä, erityisesti portit B, E (bitti 0), J (bittiä) 0–6) ja K.

    Viitekaavion tarkastelu tarkoittaa, että näitä taululla olevia nastoja tuetaan:

     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 

    Siten näet, että D10 – D12, jotka sanot toimivan, ovat luettelossa. Muut satunnaiset eivät olisi.


    SoftwareSerial

    Näet vahvistuksen sivulla SoftwareSerial , jossa sanotaan:

    Kaikki Megan ja Mega 2560 -tukien nastat eivät keskeyty, joten RX: lle voidaan käyttää vain seuraavia: 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).

    Tämä johtuu siitä, että SoftwareSerial käyttää pin-change-keskeytyksiä saapuvien sarjatietojen havaitsemiseksi ja siten kyseisen sivun vastuuvapauslausekkeeksi siitä, minkä nastojen kanssa se toimii.


    Atmega2560 -lisäosat

    Atmega2560-kiinnikkeet


    PinchangeIntin tulisi toimia millä tahansa digitaalisella nastalla

    Huomaa, että Atmega328P: ssä (kuten käytetään Unossa) on vähemmän portteja, ja kaikki ovat käytettävissä pin-change-keskeytyksille kyseisellä kortilla.

    Kommentit

    • Tämä ei voi olla ’ totta. Sivua, johon OP-vaarnanastat 2, 3, 18, 19, 20 ja 21 linkittivät ensimmäisen kerran, voidaan käyttää keskeytyksiin. Nämä kartoittavat PE4: n, PE5: n, PD3: n, PD2: n, PD1: n ja PD0: n goo.gl/DvHEUA ja goo.gl/xAwBGM Omasta puolestani olen ’ m enemmän vakuuttunut siitä, voidaanko PORTC: ta käyttää, kuten ros_arduino_bridge: goo.gl/rq6yQO
    • Linkitetty sivu viittaa ulkoisiin keskeytyksiin, mutta OP käyttää pin-vaihdon keskeytyksiä Näet osoitteesta #include <PinChangeInt.h>. Luetteloni ovat neulojen vaihdon keskeytysnastat.
    • Näen. Minulla oli aavistustapa, joka saattoi olla ero, mutta oletin, että kaikki nastat, jotka kykenevät ulkoisiin keskeytyksiin, pystyvät myös vaihtamaan nastoja, vaikkakaan ei päinvastoin.

    Vastaa

    ATmega1280 / 2560 -laitteessa vain porteilla B, J, F ja K on pin-vaihdon keskeytysominaisuus. Nämä kartoittavat suunnilleen nastat 10–15, 50–53 ja A6 – A15 (vaikka osa portista J ei ole kartoitettu Arduino-nastoihin, siksi PCINT11 – PCINT15 eivät ole käytettävissä Arduino Mega / Mega 2560: ssa).

    Vastaa

    Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *