Interrupt non eseguito

Buongiorno a tutti, sto finendo la libreria per la seriale UART su Atmega328p. Il codice è completo, sono passato alla fase di test finale, in fase di trasmissione il tutto funziona perfettamente (l’AVR invia correttamente i dati) in fase di ricezione però non si comporta come dovrebbe.
Il codice

#include <avr/io.h>
#include <avr/interrupt.h>
#include "CPP.h"
#include "UART.h"

namespace UART
{
	Buffer* rxBuffer;//Puntatore al buffer software di ricezione del UART
	Buffer* txBuffer;//Puntatore al buffer software di Trasmissione del UART
}

void UART::Init(uint16_t ubrr)
{
	UCSR0B = (1<<RXEN0) | (1<<TXEN0); //Abilito il pin di ricezione e il pin di trasmissione
	UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);//Imposto a 8 la lunghezza in bit di un carattere
	
	UBRR0H = ubrr >> 8;
	UBRR0L = ubrr;
	
	UART::rxBuffer = new Buffer(UARTRxBufferSize);//Creo una nuova istanza di Buffer per il buffer di ricezione
	UART::txBuffer = new Buffer(UARTTxBufferSize);//Creo una nuova istanza di Buffer per il buffer di trasmissione
	
	UART::RxInterruptEnabled();//Abilito l'interrupt per la ricezione di un byte
	UART::TxInterruptEnabled();//Abilito l'interrupt per la conclusione di invio di un byte
}

void UART::DoubleSpeedEnabled()
{
	UCSR0A |= 1 << U2X0;
}
void UART::DoubleSpeedDisabled()
{
	UCSR0A &= ~(1 << U2X0);
}

void UART::RxInterruptEnabled()
{
	UCSR0B |= 1 << RXCIE0;
}
void UART::RxInterruptDisabled()
{
	UCSR0B &= ~(1 << RXCIE0);
}
void UART::TxInterruptEnabled()
{
	UCSR0B |= 1 << TXCIE0;
}
void UART::TxInterruptDisabled()
{
	UCSR0B &= ~(1 << TXCIE0);
}

uint8_t UART::RxAvailable()
{
	return UART::rxBuffer->Count();//Restituisco il numero di byte nel buffer di ricezione
}

uint8_t UART::Rx()
{
	return UART::rxBuffer->Pull();//Restituisco il primo byte ricevuto
}

void UART::Tx(uint8_t data)
{
	UART::TxInterruptDisabled();//Disabilito l'interrupt per la conclusione di invio di un byte
	
	UART::txBuffer->Push(data);//Posiziono un byte nel buffer
	
	UART::TxInterruptEnabled();//Abilito l'interrupt per la conclusione di invio di un byte
	
	UART::SendData();//Rinizio la procedura di invio dei dati nel buffer
}
void UART::Tx(uint16_t data)
{
	UART::Tx((uint8_t*) &data, 2);
}
void UART::Tx(uint32_t data)
{
	UART::Tx((uint8_t*) &data, 4);
}
void UART::Tx(char data)
{
	UART::Tx((uint8_t) data);
}
void UART::Tx(char* s)
{
	while(*s != '\0')
	{
		UART::Tx((uint8_t) *s);
		s++;
	}
}
void UART::Tx(uint8_t* punt, int n)
{
	if(n > 0)
	{
		UART::Tx(*punt);
		UART::Tx(punt++, n--);
	}
}

void UART::ReceiveData()
{
	uint8_t waste;//Alloco un byte in caso dovessi eliminare dei dati
	if(UART::rxBuffer->IsFull()) waste = UDR0;//Se il Buffer di ricezione è pieno scarto il valore ricevuto
	else UART::rxBuffer->Push(UDR0);//Altrimenti inserisco il byte ricevuto nel buffer di ricezione
}
void UART::SendData()
{
	if(!UART::txBuffer->IsEmpty())
	{
		while(!(UCSR0A & (1 << UDRE0)));//Attendo che il buffer sia pronto
		UDR0 = UART::txBuffer->Pull();//Prelevo dal buffer di trasmissione ed invio il dato ad 8 bit
	}
}

ISR(USART_RX_vect) { UART::ReceiveData(); }//Al verificarsi dell'interrupt che segnala la fine della ricezione di un byte inizio la ricezione software dello stesso
ISR(USART_TX_vect) { UART::SendData(); }//Al verificarsi dell'interrupt che segnala la fine della trasmissione di un byte inizio la procedura per inviare un altro byte

Come potete vedere la gestione dei dati in arrivo o in invio sono gestiti mediante interrupt, quello corrispondente alla trasmissione viene chiamato correttamente, ma non vale lo stesso per quello in ricezione che non viene eseguito, posso assicurare che il byte viene inviato dal PC perché si distingue chiaramente che “qualcosa” è stato inviato dal LED RX sull’Arduino UNO che si illumina, ora pero non capisco perché l’interrupt non viene lanciato, mi sapete aiutare?
Un altra domanda, ho notato che i vettori di interrupt inclusi in automatico da Atmel Studio non corrispondono a quelli presenti sul datasheet
esempio
Sul DS USART_RX è 19 e nel file iom328p.h è 18

Sei sicuro di aver fatto il setup della seriale correttamente? Hai controllato sei i bit di errore ti indicano qualche problema in ricezione, es. parity o data overrun?

Un altra domanda, ho notato che i vettori di interrupt inclusi in automatico da Atmel Studio non corrispondono a quelli presenti sul datasheet
esempio
Sul DS USART_RX è 19 e nel file iom328p.h è 18

Ti frusto subito o dopo? ]:smiley:
Stai confondendo il numero di vettore con l’indirizzo del vettore :wink:

Il vettore n° 1 è il reset, che ha indirizzo $00.
Il vettore n° 2 è l’INT0, che ha indirizzo $01

Il vettore n° 19 è USART_RX che ha indirizzo $12 → 1810

Ok perfetto, non capivo bene questa storia dei vettori. Prendevo come riferimento il datasheet ma nella sezione interrupt a parer mio sono stati un po avidi di informazioni. Grazie

E' tutto il datasheet che spesso è stringato ;)

leo72:
E’ tutto il datasheet che spesso è stringato :wink:

Parole sagge, ma non ho molti altri riferimenti tutt’ora :frowning: