Logré hacer un UART de software sin usar el módulo USI y sus interrupciones.
Los ejemplos de código AVR en Atmel y avrfreaks simplemente no funcionan ni en la simulación ni en un dispositivo real, así que recibí ayuda e hice este UART suave.
Utilizando Proteus puedo enviar mensajes y recibirlos en mi ventana de terminal en una PC, puedo enviar un el carácter '1' a la simulación de Proteus y enciende un LED pin fine.
Cuando programo el ATTiny861 puedo recibir mensajes a 9600bps perfectamente, pero el procedimiento de interrupción nunca se dispara, debe dispararse una vez en el inicio y luego esperar mientras la CPU está inactiva para el cambio de bit en el PIN.
int main(int argc, char **argv)
{
USICR = 0; // Disable USI.
MCUCR |= (0<<ISC00);
MCUCR |= (0<<ISC01);
GIFR = (1<<PCIF); // Clear pin change interrupt flag.
DDRA = 0xFE;
PORTA |= (1<<PA0); //int. Pull-up an PA1
PINA = 0x00;
PCMSK0 |= (1<<PCINT0);
GIMSK |= (1<<PCIE0);
CLKPR = (1 << CLKPCE);
CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
MCUCR = (1<<SE) | (0<<SM1) | (0<<SM0); // Enable Sleepmode: Idle
while(1){
//send some startup messages ..
sei();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();
}
}
ISR(PCINT_vect) // interrupt for change in porta0
{
// pin change interrupt handler
GIMSK &= ~(1<<PCIE0);
if (!( PINA & (1<<PA0) ))
{
static char chr;
get_char(&serial_pins, serial_pin_in, &chr);
RxData = chr;
}
PCMSK0 |= (1<<PCINT0); // tell pin change mask to listen to pin0
GIMSK |= (1<<PCIE0); // enable PCINT interrupt in the general interrupt mask of the porta
GIFR = (1<<PCIF); // Clear pin change interrupt flag.
static char message[] PROGMEM = " INTERRUPTED MESSAGE ";
put_flash_string(&serial_port, serial_pin_out, (PGM_P) message);
}
Tengo otras bibliotecas y segmentos de código cargados y sé que la función put_flash_string funciona bien. Si saco sleep_mode, volcará los mensajes en el terminal, puedo retrasarlo y también funciona. Pero por alguna razón desconocida en mi hardware ATTiny861 simplemente no se interrumpirá.
Hace dos semanas que estoy viendo este código y realmente necesito ayuda. Atmel, como puedes imaginar, es vago y no es realmente útil. No estoy seguro de qué comprobar más y por qué funciona la simulación de Proteus y no mi hardware.