내 인터럽트 코드가 작동하지 않는 이유는 무엇입니까?

배경

Arduino Mega 2560 . 현재 문제 해결을 쉽게하기 위해 하나의 채널 만 읽는 코드를 유지하고 있습니다. 문제는 공유 변수가 업데이트되지 않아 인터럽트가 발생한다고 믿게됩니다. 서비스 루틴이 상승 에지를 감지하지 않습니다.

수신기가 고장난 것으로 생각했기 때문에 표준 Arduino 연결 인터럽트 기능 을 사용하여 테스트했습니다. . 완벽하게 작동 했으므로 수신기는 괜찮습니다.

Serial.print () 를 사용하여 휘발성 채널 변수가 업데이트되었는지 확인했습니다. (즉, 값을 채널 1 플래그 값으로 변경합니다.) 업데이트되지 않았으므로 내 ISR 이 잘못되었을 것입니다. 원본 코드는 다음에서 찾을 수 있습니다. 블로그 게시물입니다.

무슨 일입니까? 아이디어가 없습니다.

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

댓글

  • 코드를 단순화 해보세요. 예를 들어 ISR이 LED를 켜도록합니다. ' 본질적으로 잘못된 것은 없습니다.
  • 알았습니다. 어떤 이유로 핀 10,11 및 12에서만 작동합니다.하지만 ' 그 이유를 모르겠습니다. PinchangeInt는 모든 디지털 핀에서 작동해야합니다.
  • 하지만 핀 10을 사용하고 계십니까? 어쨌든 작동하게되어 기쁩니다.

답변

Atmega2560의 일부 포트만 핀 변경 인터럽트, 특히 포트 B, E (비트 0), J (비트 0 ~ 6) 및 K.

참조 회로도를 보면 보드의 다음 핀이 지원된다는 의미입니다.

 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 

따라서 작동한다고 말하는 D10에서 D12가 그 목록에 있음을 알 수 있습니다. 다른 임의의 것은 그렇지 않습니다.


SoftwareSerial

다음과 같은 SoftwareSerial 페이지에서 확인을 볼 수 있습니다.

Mega 및 Mega 2560의 모든 핀이 변경 인터럽트를 지원하는 것은 아니므로 RX에는 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).

SoftwareSerial은 핀 변경 인터럽트를 사용하여 들어오는 직렬 데이터를 감지하므로 해당 페이지에서 사용할 핀에 대한 면책 조항을 사용하기 때문입니다.


Atmega2560 핀아웃

Atmega2560 핀아웃


PinchangeInt는 모든 디지털 핀에서 작동해야합니다.

Atmega328P (Uno에서 사용됨)에는 포트 수가 적고 해당 보드의 핀 변경 인터럽트에 모두 사용할 수 있습니다.

댓글

  • 이것은 ' 정답이 아닙니다. OP 클레임 핀 2, 3, 18, 19, 20 및 21에 의해 처음 연결된 페이지는 인터럽트에 사용할 수 있습니다. goo.gl/DvHEUA goo.gl/xAwBGM 저는 ' ros_arduino_bridge 에서처럼 PORTC를 사용할 수 있는지에 대해 더 우려합니다. goo.gl/rq6yQO
  • 연결된 페이지는 외부 인터럽트를 참조하지만 OP는 핀 변경 인터럽트를 다음과 같이 사용합니다. #include <PinChangeInt.h>에서 확인할 수 있습니다. 핀 변경 인터럽트 핀은 제가 나열한 핀입니다.
  • 알겠습니다. 나는 구별이 될 수도 있지만, 외부 인터럽트가 가능한 모든 핀이 그 반대는 아니지만 핀 변경이 가능하다고 가정했습니다.

답변

ATmega1280 / 2560에서는 포트 B, J, F 및 K에만 핀 변경 인터럽트 기능이 있습니다. 약 10 ~ 15, 50 ~ 53, A6 ~ A15에 매핑됩니다 (단, 포트 J의 일부는 Arduino 핀에 매핑되지 않으므로 PCINT11 ~ PCINT15는 Arduino Mega / Mega 2560에서 사용할 수 없습니다).

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다