我正在尝试使用引脚更改中断来检测按下的按钮。到目前为止,我从未使用过此类中断,并且存在一些问题,因此我想确定这是否正确。
如果我正确地获得了数据表,则必须执行以下操作以使用引脚更改中断:
- 在PCMSK寄存器中设置要控制的PIN
- 启用PIN寄存器以进行引脚更改中断控制(PCICR)
- 启用中断
- 使用相应的中断向量
项目:简单的Moodlamp,通过4个按钮控制颜色。
设定:
- Atmega168A-PU
- 4个迷你按钮开关
- MOSFETs控制我的3瓦RGB LED
这是我正在使用的代码无法正常工作:
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define BUTTON1 (1<<PC5)
#define BUTTON2 (1<<PC4)
#define BUTTON3 (1<<PC3)
#define BUTTON4 (1<<PC2)
#define GREEN (1<<PB1)
#define BLUE (1<<PB2)
#define RED (1<<PB3)
void init() {
// enable LED
DDRB |= GREEN;
DDRB |= BLUE;
DDRB |= RED;
// button pullups
PORTC |= BUTTON1;
PORTC |= BUTTON2;
PORTC |= BUTTON3;
PORTC |= BUTTON4;
// pin change interrupts for buttons
PCMSK1 |= PCINT13;
PCMSK1 |= PCINT12;
PCMSK1 |= PCINT11;
PCMSK1 |= PCINT10;
// enable pin change for buttons
PCICR |= PCIE2;
sei();
}
ISR(PCINT2_vect) {
PORTB = BLUE;
}
void ledTest() {
PORTB ^= RED;
_delay_ms(250);
PORTB ^= RED;
_delay_ms(250);
PORTB ^= RED;
_delay_ms(250);
PORTB ^= RED;
PORTB ^= BLUE;
_delay_ms(250);
PORTB ^= BLUE;
_delay_ms(250);
PORTB ^= BLUE;
_delay_ms(250);
PORTB ^= BLUE;
PORTB ^= GREEN;
_delay_ms(250);
PORTB ^= GREEN;
_delay_ms(250);
PORTB ^= GREEN;
_delay_ms(250);
PORTB ^= GREEN;
}
int main() {
init();
ledTest();
_delay_ms(500);
PORTB |= GREEN;
while(1) {
_delay_ms(100);
}
}
注意:按钮应被消除抖动。由于我正在尝试逐步进行,并且不应该打开LED,因此在这里我忽略了它。
问题:我尝试使用中断的方式是否正确?
我的安装出现问题:
- Button1-3完全被忽略。
- Button4触发atmega的重置
我检查过的事情:
- 按钮根本没有连接到重置PIN
- 如果按下按钮,则按钮已正确连接到GND
- 如果不按,则按钮未连接到GND
如果我不间断地使用按钮,按钮会很好地工作,例如:
if(!(PINC&BUTTON4)){PORTB ^ =蓝色; }
- 16MHZ外部晶体/内部晶体
- 路由中的任何错误
- 我在atmega的PWR和GND之间使用100nF电容器
- VCC(7),GND(8),GND(22),AVCC(20)已连接(由于我不需要AREF,因此未连接)