Xmega 只有两个 IO 端口中断(INT0 和 INT1)
Posted
技术标签:
【中文标题】Xmega 只有两个 IO 端口中断(INT0 和 INT1)【英文标题】:Only two IO port interrupts for Xmega (INT0 and INT1) 【发布时间】:2015-10-07 09:23:33 【问题描述】:在avr Xmega设备中,只有两个IO口中断向量INT0和INT1。
我有三个开关应该产生三个中断。 我已经使用 INT0 为第一个开关编写了中断代码。现在,我可以使用 INT1 编写第二个中断,这将耗尽我的向量。 以下是我的 INT0 ISR 代码:
ISR (PORTD_INT0_vect)
PORTD.INTFLAGS = 0x01; // clear INT0IF flag.
PORTD_OUT = PORTD_OUT | (1<<4); // led on.
我可以重新定义此 ISR 以启用第二次切换的中断吗?
我在main函数中设置的寄存器如下:
PORTD.INT0MASK = 0x04; // PD2 is the source of interrupt for INT0.
PORTD.INTCTRL = 0x03; // Disable INT1, enable INT0 and place it a high-priority level.
PORTD.PIN2CTRL = 0x03; // configure PD2 pin to interrupt on the low level of signal.
PMIC.CTRL = 0x07; // enable high,medium, and low level interrupts.
sei(); // enable interrupt globally.
【问题讨论】:
为什么不使用单个中断向量并在中断时测试源? 如果是这样,ISR 应该记住我按下了哪个开关。这可能吗? @PradeepCh:是的,ISR 可以通过将 PORTx_IN 寄存器的状态存储在变量中来记住按下了哪个开关。 【参考方案1】:外部中断的想法是让您知道发生了什么事,但不知道发生了什么。在您的 ISR 中,您必须读出开关连接到的输入的状态,并根据读数确定要做什么。要检测状态是否发生了变化,请保留端口输入状态的副本,并与新读出的值进行异或(对整个端口执行此操作,而不仅仅是单个引脚)。
【讨论】:
是否可以让 ISR 记住按下了哪个开关?考虑到 ISR 记得哪个开关被按下,我可以为所有三个开关分配一个 ISR。 您可以实施此答案的建议。然后你仍然可以有一个空闲的中断向量用于其他目的。当你让它工作时,你可以考虑将它扩展到去弹机械开关闭合。 @PradeepCh:“ISR 记得按下了哪个开关吗?” – 呃,只需将输入端口值读入某个(全局)变量即可。portdstate_at_isr = PORTD_IN
【参考方案2】:
我不是 XMEGA 的专家,但我可以建议,例如使用 PD1 作为中断引脚:
PORTD.INT0MASK = 0x04; // PD2 is the source of interrupt for INT0.
PORTD.INT1MASK = 0x02; // PD1 is the source of interrupt for INT1.
PORTD.INTCTRL = 0x0F; // Enable INT1, enable INT0 and place them a high-priority level.
PORTD.PIN2CTRL = 0x03; // configure PD2 pin to interrupt on the low level of signal.PORTD.PIN1CTRL = 0x03; // configure PD1 pin to interrupt on the low level of signal.
【讨论】:
【参考方案3】:每个端口都有 2 个中断。如果您需要多于 2 个的中断,则可以使用更多端口。您可以将第三个交换机连接到第二个端口并在那里使用 INT0。
【讨论】:
【参考方案4】:如何从您的代码、循环或定时器中断例程中轮询输入?这样,您可以处理与能够感应信号变化的输入一样多的输入信号。
但限制因素是轮询频率和轮询软件引入的延迟。
当然,我假设您想观察信号的高/低电平。对于更精细的信号感应(上升、下降、频率变化),ADC 的使用是不可避免的。
我希望这会有所帮助。
【讨论】:
以上是关于Xmega 只有两个 IO 端口中断(INT0 和 INT1)的主要内容,如果未能解决你的问题,请参考以下文章