我是否正确地认为如果有两个引脚引起相同的AVR PCINT中断(例如,由PCINT0或PCINT1引脚引起的PCINT0 向量 -我认为向量和引脚的命名重叠会令人困惑)是确定哪个引脚的唯一方法(s)导致中断是在每次中断后记录其状态,并比较在PCMSKn中启用的所有引脚的先前值和当前值?
我是否正确地认为如果有两个引脚引起相同的AVR PCINT中断(例如,由PCINT0或PCINT1引脚引起的PCINT0 向量 -我认为向量和引脚的命名重叠会令人困惑)是确定哪个引脚的唯一方法(s)导致中断是在每次中断后记录其状态,并比较在PCMSKn中启用的所有引脚的先前值和当前值?
Answers:
我认为向量和图钉的命名重叠令人困惑
它是!
中断向量有8个不同的外部引脚的原因是,如果与另一个引脚功能发生冲突,可以更轻松地布局PCB或使用其他引脚。
我的想法是否正确……确定导致中断的引脚的唯一方法是记录每次中断后的状态,并比较PCMSKn中启用的所有引脚的先前值和当前值?
几乎可以说,您只关心PB0(PCINT0)和PB1(PCINT1)。因此,引脚更改使能掩码PCMSK0将设置为0x03。
// External Interrupt Setup
...
volatile u_int8 previousPins = 0;
volatile u_int8 pins = 0;
ISR(SIG_PIN_CHANGE0)
{
previousPins = pins; // Save the previous state so you can tell what changed
pins = (PINB & 0x03); // set pins to the value of PB0 and PB1
...
}
因此,如果pins
是0x01,则您知道它是PB0...。如果您需要知道更改了什么,则需要将其与进行比较previousPins
,几乎完全是您的想法。
请记住,在某些情况下,pins
如果引脚自中断以来但在之前具有更改状态,则可能不准确pins = (PINB & 0x03)
。
另一种选择是对每个向量使用单独的中断向量和一个引脚,以便您知道哪个被更改。同样,这也有一些问题,例如中断优先级,并且一旦CPU进入ISR,将清除全局中断允许位I-bit
,SREG
以便禁用所有其他中断,尽管您可以根据需要在中断内部设置它,嵌套中断。
有关更多信息,请参阅Atmel的应用笔记“ 为megaAVR设备使用外部中断”。
更新资料
这是我在这里找到的完整代码示例。
#include <avr/io.h>
#include <stdint.h> // has to be added to use uint8_t
#include <avr/interrupt.h> // Needed to use interrupts
volatile uint8_t portbhistory = 0xFF; // default is high because the pull-up
int main(void)
{
DDRB &= ~((1 << DDB0) | (1 << DDB1) | (1 << DDB2)); // Clear the PB0, PB1, PB2 pin
// PB0,PB1,PB2 (PCINT0, PCINT1, PCINT2 pin) are now inputs
PORTB |= ((1 << PORTB0) | (1 << PORTB1) | (1 << PORTB2)); // turn On the Pull-up
// PB0, PB1 and PB2 are now inputs with pull-up enabled
PCICR |= (1 << PCIE0); // set PCIE0 to enable PCMSK0 scan
PCMSK0 |= (1 << PCINT0); // set PCINT0 to trigger an interrupt on state change
sei(); // turn on interrupts
while(1)
{
/*main program loop here */
}
}
ISR (PCINT0_vect)
{
uint8_t changedbits;
changedbits = PINB ^ portbhistory;
portbhistory = PINB;
if(changedbits & (1 << PB0))
{
/* PCINT0 changed */
}
if(changedbits & (1 << PB1))
{
/* PCINT1 changed */
}
if(changedbits & (1 << PB2))
{
/* PCINT2 changed */
}
}