¿Por qué atmega168 / 328p comienza a reiniciarse?

2

Primero configuramos los bits de fusible:

avrdude -c usbasp -p atmega328p -U lfuse:w:0xFF:m -U hfuse:w:0xDF:m -U efuse:w:0x07:m # same for atmega168

En los siguientes ejemplos, usamos los siguientes comandos para compilar y grabar todos los programas:

avr-gcc -Os -mmcu=atmega328p -c -o serial.o serial.c
avr-ld -o serial.elf serial.o
avr-objcopy -O ihex serial.elf serial.hex
avrdude -c usbasp -p atmega328p -U flash:w:serial.hex

Vamos a grabar el siguiente programa:

#define F_CPU 16000000UL
#include <avr/io.h>
void main (void) {
  DDRB |= (1<<PB5); // enable output on pin PB5 (default led on arduino)
  PORTB |= (1<<PB5); // set the led on
  while (1);
}

Hace que el led esté encendido constantemente. Y permanece así por un período infinito de tiempo.

Luego quemamos el siguiente programa:

#define F_CPU 16000000UL
#include <avr/io.h>
char data = 0;
void main(void) {
  // Initialize USART:
  UBRR0H = 0x00; // set the speed (Higher bit)
  UBRR0L = 0x67; // set the speed (Lower bit)
  UCSR0B = 0x10; // enable receiver
  UCSR0C = 0x06; // set mode (8N1)
  DDRB |= (1<<PB5); // enable output on pin PB5 (default led on arduino)
  while(1) {
    while(!(UCSR0A&(1<<RXC0))); // wait until a byte is received
    data = UDR0; // read it
    if (data) PORTB |= (1<<PB5); // set the led on
  }
}

Luego abrimos un terminal (9600,8N1) y presionamos varias teclas, hasta que el led se apaga. Ahora volvemos a grabar el primer programa y el led parpadea constantemente. La razón de esto es que los tiempos de vigilancia se inician cuando presionamos las teclas en el terminal. Pero, ¿por qué y cuándo se inicia WDT? ¿Cómo hacer para que no comience?

También se debe tener en cuenta que podemos deshabilitar el parpadeo solo con el apagado / encendido completo; solo después, el led se enciende constantemente sin parpadear, según sea necesario.

Esto sucede en atmega168 y atmega328p, 100% reproducible.

avr-gcc versión 4.8.1 avrdude versión 6.1

NOTA: el cargador de arranque no se usa en absoluto.

    
pregunta Igor Liferenko

1 respuesta

1

La mayoría de tu código y publicación no tiene absolutamente nada que ver con el temporizador de vigilancia.

En los comentarios anteriores, observa que usa un oscilador externo de 16 MHz, pero sus fusibles configuran el chip para un oscilador externo de 8 MHz. ¿Realmente estás usando un cristal con condensadores o un resonador cerámico?

¿Es este un PCB personalizado? ¿Estás usando Arduino o alguna otra placa de desarrollo? ¿Si es así, Cuál? ¿Cómo se está comunicando con este chip ... a través del puerto serie desde una computadora? ¿Cuál es tu configuración? No has explicado nada sobre lo que realmente estás tratando de hacer. Si está utilizando Arduino, dígalo ... y probablemente pregunte esto en el canal Arduino.

El código utilizado para habilitar y usar el USART no es muy bueno, pero esa es una conversación diferente. Los archivos de encabezado (.h) nunca deben incluirse en medio del código, todos deben incluirse en la parte superior del archivo. También debe incluir avr / interrupt.h para usar cualquier vector ISR.

El temporizador de vigilancia AVR tiene bits de registro específicos que deben configurarse.

En lugar de publicar una respuesta larga, lo dirigiré a esta pregunta sobre el WDT que respondí anteriormente con detalles sobre cómo iniciar y operar el WDT.

Cualquier otro detalle que pueda necesitar se puede encontrar en la hoja de datos para los microcontroladores de la serie ATmegax8 , específicamente la sección 10.8 .

    
respondido por el Kurt E. Clothier

Lea otras preguntas en las etiquetas