Ciao a tutti, stavo cercando di far funzionare gli interrupt su attiny45.
Facendo svariate ricerche in rete e scopiazzando qua e la sono arrivato a partorire questo codice:
#include <avr/interrupt.h>
int pin = 4;
volatile int state = LOW;
void setup()
{
PCMSK |= (1<<PB3);
MCUCR = (1<<ISC01) | (1<<ISC00);
GIMSK |= (1<<INT0);
sei();
// Le istruzioni sopra dovrebbero essere più o meno l'equivalente di: attachInterrupt(0, ISR, FALLING);
pinMode(pin, OUTPUT);
}
void loop()
{
digitalWrite(pin, state);
}
ISR (INT0_vect)
{
state =!state;
}
che non fa altro che accendere e spegnere un led ogni volta che un determinato pin viene portato da HIGH a LOW.
Il codice funziona, ma volevo capirlo meglio, nel senso che vorrei provare a fare in modo che il pin dell'interrupt sia
diverso da quello che ora sta funzionando.
A tale scopo ho provato a cambiare i parametri su PCMSK, MCUCR e GIMSK anche se da quello che ho capito, l'icriminato
dovrebbe essere PCMSK.
Il risultato è che anche cambiando i parametri, comunque l'interrupt funziona sempre e solo sul pin 7 (PB2) e questo mi
fa pensare di non averne capito niente
Ho letto e riletto la documentazione: http://www.atmel.com/Images/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf e da quello che capisco la possibilità di attivare gli interrupt sui vari pin dovrebbe esserci.
Qualche buonanima mi può spiegare la logica di questi 3 registri?
Grazie.
Ciao.
Registro PCMSK - Pin Change Mask Register
Serve per attivare gli interrupt di tipo PinChange sui singoli bit.
L'istruzione attiva l'interrupt PCINT3 (che è agganciato al pin PB3)
Registro MCUCR - MCU Control Register
E' il registro che controlla alcune funzioni vitali del micro, come gli interrupt. La tua istruzione richiama l'INT0 su un segnale in salita (RISING).
Registro GIMSK - General Interrupt Mask Register
Attivi l'INT0, ossia se arriva un segnale rispondente ai criteri impostati nel registro MCUCR, la CPU eseguirà la corrispondente ISR:-
ISR (INT0_vect)
Quindi, nel tuo caso attivi anche il PinChange ma poi non gli dai una ISR. Inoltre PCINT3 è sul pin B3 mentre INT0 è su PB0.
Infine... attachInterrupt compila per i Tiny, perché semplicemente non usi questa funzione?
Intanto grazie della risposta
Premesso che non mi sono ancora letto il link che mi hai passato, volevo risponderti sulla tua ultima domanda:
Infine... attachInterrupt compila per i Tiny, perché semplicemente non usi questa funzione?
La risposta è: perchè ho visto che compila ma da prove fatte non sembra funzionare su attiny45 che ho io, mentre sulla UNO funziona perfettamente.
Quando ho visto che non funzionava mi è venuto il dubbio che forse l'attiny non lo supportasse e quindi mi sono messo a fare ricerche dove poi ho scoperto che esiste una libreria dedicata (forse obsoleta?) che si chiama "pinchangeinterrupt-0001" e probabilmente da li sono partite una serie di seghe mentali ]
Ora riprovo con attachinterrupt.
Mi sai dire l'attachinterrupt(0, funz, FALLING) su quale pin dovrebbe intercettare il cambio di stato sul tiny45?
Grazie.
Ciao.
@Stefanoxjx:
un INTx è leggermente diverso da un PCINTx, hanno livelli di gestione diversi ed inoltre un INTx è individuato singolarmente mentre i PCINTx sono gestiti da un unico registro che devi poi leggere per vedere quale pin ha sollevato l'interrupt.
Tornando alla funzione attachInterrupt, guarda che funziona. Non è che forse hai sbagliato ad usarla? Magari sbagliando pin (come ho fatto io prima) oppure usando un codice non corretto?
Intanto, che core per i Tiny stai usando?
leo72: @Stefanoxjx:
un INTx è leggermente diverso da un PCINTx, hanno livelli di gestione diversi ed inoltre un INTx è individuato singolarmente mentre i PCINTx sono gestiti da un unico registro che devi poi leggere per vedere quale pin ha sollevato l'interrupt.
Ok, capito.
Immaginavo ci fosse una differenza ma non capivo quale.
Ora tu dirai che è scritto tutto sulla documentazione del micro e infatti ne sono sicuro, solo che mi ci vuole qualche mese per leggere tutta quella pappardella in inglese
Tornando alla funzione attachInterrupt, guarda che funziona. Non è che forse hai sbagliato ad usarla? Magari sbagliando pin (come ho fatto io prima) oppure usando un codice non corretto?
No, lo stesso identico codice su arduino uno e pro mini funziona perfettamente.
Su attiny vedo che arriva il segnale di interrupt ma si comporta in modo strano, sembra quasi non riesca a starci dietro :~
Mi riservo comunque di fare altre prove, perchè ora sono rimasto senza il sensore (Hall) che genera il segnale di interrupt, quindi finchè non riesco a recuperarne un altro sono fermo