LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: CBX em 05 de Março de 2011, 20:29
-
boas
estou aqui a tentar usar interrupções externas num attiny25, a minha ideia é usar 2 pushbuttons, um para ligar o led ligado ao pino PB4 e o outro para o desligar.
se eu usar este código, faz o pretendido, acende o LED:
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void) {
DDRB |= (1<<PB4);
GIMSK = _BV (PCIE); // ligar mudança de estado nas interrupções
PCMSK = _BV (PCINT0); // ligar interrupções no pino INT0
MCUCR = _BV (ISC00); // detectar mudança estado INT0
sei(); // ligar interrupções globais
while(1) {
}
return 0;
}
ISR (PCINT0_vect) // Interrupção do Pino PB0 (INT0)
{
PORTB |= (1<<PB4);
}
mas se usar este, com os 2 pushbuttons, seguindo a mesma lógica de cima já não funciona:
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void) {
DDRB |= (1<<PB4);
GIMSK = _BV (PCIE); // ligar mudança de estado nas interrupções
PCMSK = _BV (PCINT0); // ligar interrupções no pino INT0
MCUCR = _BV (ISC00); // detectar mudança estado INT0
PCMSK = _BV (PCINT1); // ligar interrupções no pino INT1
MCUCR = _BV (ISC01); // detectar mudança estado INT1
sei(); // ligar interrupções globais
while(1) {
}
return 0;
}
ISR (PCINT0_vect) // Interrupção do Pino PB0 (INT0)
{
PORTB |= (1<<PB4);
}
ISR (PCINT1_vect) // Interrupção do Pino PB1 (INT1)
{
PORTB &= ~(1<<PB4);
}
o que é que estou a fazer mal?
EDIT: esqueci-me de referir, no segundo código tenho um warning:
../t25int.c:26: warning: 'PCINT1_vect' appears to be a misspelled signal handler
-
Verifica o Hardware se tá tudo bem...
-
já verifiquei e voltei a verificar, com o hardware não parece haver problema...
-
Devias dar ouvidos ao compilador, se ele diz que aquilo nao é um vector de interrupcao nao vai gerar código para o mesmo, logo nao funciona, ve o datasheet.
-
vamos lá ver se estou a perceber as coisas:
ao ler a datasheet vejo que o attiny25 só tem um "Pin Change Interrupt Request", INT0, ou seja qualquer um dos pinos vai apenas "despertar" a mesma interrupção e não dá para fazer o que eu quero com os 2 botões, dai o warning??
Edit: já vi que é assim ;D
-
A doc do winavr tem uma tabela com as interrupções e respectivos nomes suportadas por cada modelo de AVR.
Tens um pull-up/pull-down nos botões? E debouncing?
-
tenho pull down, 1.8k, debouncing neste caso acho que não é preciso pois só lá está uma instrução, mesmo que carregue no botão várias vezes não vai mudar o estado.
o meu problema era estar a pensar que "um pino, uma interrupção" mas agora acho que já percebi a coisa...
-
já está tudo a funcionar como eu queria, obrigado a todos pela ajuda:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main(void) {
int val;
DDRB |= _BV(PB4);
DDRB &= ~_BV(PB1);
PORTB |= _BV(PB1);
GIMSK = _BV(PCIE);
PCMSK = _BV(PCINT0);
MCUCR = _BV(ISC00);
sei();
while(1) {
val = PINB & _BV(PB1);
if (val == 0) {
_delay_ms(10);
}
if (val == 0) {
PORTB |= _BV(PB4);
}
}
return 0;
}
ISR (PCINT0_vect)
{
PORTB &= ~_BV(PB4);
}