Estaba usando ATmega32A antes y ahora estoy migrando a ATmega324PA solo para mejorar la administración de energía. Ahora estoy probando el nuevo controlador en todos los aspectos. Este es un código simple para verificar el temporizador de vigilancia, pero sigue reiniciando el controlador.
Código:
int main(void)
{
uart_init();
PORTA|=(1<<PORTA1);
_delay_ms(1500);
PORTA&=~(1<<PORTA1);
_delay_ms(2000);
uart_array("FFFFFFFFFFFFFFFFFF");
wdt_enable(WDTO_2S);
_delay_ms(5000);
}
void uart_init()
{
/*set PinA1 as output for LED*/
DDRA|=(1<<1);
/*set PinD3 as output for UART*/
DDRD|=(1<<3);
/*set pinD2 as input for UART*/
DDRD&=~(1<<2);
/*enabling TX and RX*/
UCSR1B |=(1<<TXEN1) | (1<<RXEN1);
/*asynchronous mode selection*/
UCSR1C&=~(1<<UMSEL11);
UCSR1C&=~(1<<UMSEL10);
/*setting data format to 8 bit*/
UCSR1B &=~(1<<UCSZ12);
UCSR1C|=(1<<UCSZ11)|(1<<UCSZ10);
/* setting one bit as stop bit*/
UCSR1C &=~(1<<USBS1);
/*Disabling parity*/
UCSR1C &= ~((1<<UPM11) | (1<<UPM10));
/* loading 8 LSB to UBRRL*/
UBRR1L = UBRRL_VALUE;
/* loading 4 MSB to UBRRH*/
UBRR1H = UBRRH_VALUE;
}
El código funciona bien por primera vez, pero después de eso, el LED sigue parpadeando.
Nota: el bit de fusible de vigilancia (WDTON) está deshabilitado.
Sí, eso se debe a que después de que se dispara el perro guardián, debe restablecer el indicador correspondiente antes de que main comience de nuevo (hay un registro donde puede leer qué causó el reinicio) y desactivar el perro guardián para que no se dispare una y otra vez.
Este código solucionará su problema:
// This function is called upon a HARDWARE RESET:
void reset(void) __attribute__((naked)) __attribute__((section(".init3")));
/*! Clear SREG_I on hardware reset. */
void reset(void)
{
cli();
// Note that for newer devices (any AVR that has the option to also
// generate WDT interrupts), the watchdog timer remains active even
// after a system reset (except a power-on condition), using the fastest
// prescaler value (approximately 15 ms). It is therefore required
// to turn off the watchdog early during program startup.
MCUSR = 0; // clear reset flags
wdt_disable();
}
Esta .init3
cosa es una sección de código especial donde puede poner el código que se ejecuta antes de que se inicie la principal. Aquí hay un enlace que lo describe, pero no debe preocuparse demasiado por eso, el código anterior funcionará bien cuando se coloque en el archivo main.c
.
Más allá de los consejos de funciones anteriores reset()
, debe deshabilitar el perro guardián en el gestor de arranque (si se usa, por supuesto). Hay/había, por ejemplo, un error conocido del gestor de arranque Arduino original que no deshabilitó el perro guardián.
gzix
jjstcool
gzix
jjstcool