Atmega328P - ¿Cómo se supone que funciona la detección de parches?

5

[RESUELTO] [ACTUALIZACIÓN]:

El problema fue con los bits de fusible. De alguna manera, los fusibles se escribían incorrectamente como 0xFE en lugar de 0xFD. FE corresponde a 1.8V y, por lo tanto, el tablero de arduino estaba trabajando hasta 1.8V. Reinstalé Arduino y empecé todo desde cero y con el código Show Info sugerido por bigjosh, pude verificar los bits del fusible . Configuré el nivel de BOD a 2.7V y ahora está funcionando como se esperaba. El microcontrolador reanuda todas las operaciones una vez que haya suficiente voltaje disponible.

Otra actualización: estaba viendo la configuración de fusibles extendidos para 1.8V debido a los permisos de escritura del archivo en C: \ en Windows. Aparentemente, el archivo de los tableros era de solo lectura y las ventanas no generan errores cuando presiono Ctrl + S. Me hizo pensar que el archivo de los tableros se estaba actualizando mientras aún estaba atascado en el nivel predeterminado de BOD de 1.8V. La segunda vez, elegí instalar en D: \ y todo funciona perfectamente.

Estoy tratando de averiguar cómo usar BOD para hacer que mi proyecto arduino sea más sólido, pero parece ser otro problema. Mi sistema funciona con 3.3V, así que elegí establecer el nivel de BOD a 2.7V (fusibles extendidos = 0x05).

Como prueba de prueba, cargué un código de impresión en serie que imprime "Started" cuando el microcontrolador se inicia y luego "Working" cada medio segundo.

El experimento consistió en encender la atmósfera usando una fuente de alimentación de sobremesa y monitorear el texto de serie en una PC. Esperaba que sucediera algo extraño una vez que el voltaje descienda por debajo de 2.7V. No pasó nada hasta 2.2V. Por debajo de 2.2V, había múltiples escenarios allí:

(Configuración experimental: no usé la placa arduino. La construí en una placa de pruebas separada y la tensión se estaba alimentando directamente mediante el uso de una fuente de alimentación de sobremesa. Había tapas de filtro - 300 uF cerca de las clavijas IC. La serie era conectado a la PC directamente sin aislamiento óptico. También se hizo GND común.)

Caso 1: el microcontrolador se reinició varias veces y siguió funcionando normalmente a 2.1 V o menos. Al reducir aún más, dejó de imprimir. Al aumentar el voltaje, nunca se reanudó a un estado normal de trabajo. El restablecimiento externo lo llevó al estado normal.

Caso 2: Continuó imprimiendo algunas cosas al azar en serie hasta que disminuí aún más el voltaje, momento en el que dejó de imprimir. No reanudó la impresión, incluso después de que el voltaje se elevó a los niveles normales. El restablecimiento externo lo llevó al estado normal.

Caso 3: Se restableció varias veces y se siguió imprimiendo "Wmrkmng". En ese momento, comencé a elevar el voltaje a niveles normales (3.3 V) pero aún seguía imprimiendo el texto incorrecto. El restablecimiento externo lo llevó al estado normal.

Mi expectativa era que cuando se detectara un apagón, el microcontrolador se apagaría (todos los GPIO LOW y UART no imprimirían nada, de forma similar al microcontrolador apagado) y tan pronto como el voltaje se normalice, actuaría como si hubiera estado encendido desde un estado apagado. Sin embargo los resultados son totalmente diferentes. Como tal, si lo uso en un producto y, por algún motivo, se produce un apagón, la única forma conveniente de ponerlo en funcionamiento es apagarlo y volverlo a ENCENDER para que reciba la señal de reinicio de encendido. Definitivamente, tal procedimiento no será aceptable en muchos casos (incluido el mío). Como tal, ¿qué debo hacer para evitar dicho estado de bloqueo? No estoy seguro de que incluso watch-dog sea de gran ayuda (considere el caso 3: la mayoría del código estaba funcionando. ¿Qué pasa si WDT no ve ningún problema y deja que el microcontrolador funcione de la manera en que se está ejecutando)?

(Edición: WDT falló en algunos casos como se esperaba)

No pude encontrar mucho en la hoja de datos de Atmel, pero me encontré con una pregunta de intercambio de pila aquí que describe una similar problema para la familia PIC.

(Edición 2: Mientras esperaba cualquier respuesta a esta pregunta, realicé algunas otras pruebas que no involucraban ninguna conexión externa. Eliminé la serie y cargué un código simple para parpadear un LED a 1 Hz cuando el pin era ALTO y a 5 Hz cuando el pin estaba BAJO. Incluso este código no funcionó. Los resultados en este caso se pueden comparar con los casos 1, 2 y 3. También probé WDT. Sin beneficio. Una cosa extraña. Me di cuenta de que a pesar de que estaba cambiando la configuración del gestor de arranque para establecer diferentes niveles de BOD (1,8 V, 2,7 V y 4,5 V, el código utilizado para desordenar a alrededor de 2,2 V en todos los casos). Aquí está la definición de arduino:

uno.name=Arduino Uno

uno.vid.0=0x2341
uno.pid.0=0x0043
uno.vid.1=0x2341
uno.pid.1=0x0001
uno.vid.2=0x2A03
uno.pid.2=0x0043

uno.vid.0x2A03.warning=Uncertified

uno.upload.tool=avrdude
uno.upload.protocol=arduino
uno.upload.maximum_size=32256
uno.upload.maximum_data_size=2048
uno.upload.speed=115200

uno.bootloader.tool=avrdude
uno.bootloader.low_fuses=0xFF
uno.bootloader.high_fuses=0xDE
uno.bootloader.extended_fuses=0x05
uno.bootloader.unlock_bits=0x3F
uno.bootloader.lock_bits=0x0F
uno.bootloader.file=optiboot/optiboot_atmega328.hex

uno.build.mcu=atmega328p
uno.build.f_cpu=16000000L
uno.build.board=AVR_UNO
uno.build.core=arduino
uno.build.variant=standard

Cambié los bits de fusible extendido a 0x04, 0x05 y 0x06 para probar los tres niveles de BOD.

Código de parpadeo de LED básico utilizado para probar:

int ledPin = 17;
int inputPin = 2;


void setup() {
  // put your setup code here, to run once:
//  Serial.begin(115200);
//  Serial.println("BOOT");
  pinMode(ledPin,OUTPUT);
  pinMode(inputPin,INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
//  delay(500);
//  Serial.println("XXXXXXXXXX");

  if (digitalRead(inputPin)==1)
  toggle(17,1000);
  else if (digitalRead(inputPin)==0)
  toggle(17,200);
}

void toggle(int pin_number, long int delay_time)
{
  digitalWrite(pin_number, HIGH);
  delay(delay_time);
  digitalWrite(pin_number, LOW);
  delay(delay_time);
}
    
pregunta Whiskeyjack

1 respuesta

8

El detector de oscurecimiento pondrá el chip en modo de reinicio si el voltaje en el pin Vcc cae por debajo del umbral. Cuando se reinicia, todos los pines GPIO pasan al modo de alta impedancia y no se ejecuta ningún código. Cuando la tensión de alimentación vuelve a elevarse por encima del umbral por un período mínimo de tiempo, el chip saldrá del reinicio y comenzará a ejecutar el código en el vector de reinicio, similar a un arranque normal.

Tenga en cuenta que muchas placas Arduino tienen circuitos de alimentación adicionales como un regulador de voltaje. Esto significa que el voltaje que usted suministra a la placa Arduino podría no ser el voltaje que el chip real ve en su pin Vcc. Puede usar un voltímetro para verificar el voltaje real que se ve en ese pin, así que vea si coincide con lo que espera.

También tenga en cuenta que los chips AVR tienen diodos de sujeción en sus entradas, por lo que si un pin GPIO está conectado a un voltaje más alto que el pin Vcc, entonces el chip puede continuar alimentándose desde el pin de entrada. Me encontré con un error muy interesante debido a esto ...

enlace

¿Cómo estás haciendo tu conexión serial al chip? ¿Es posible que pueda haber poder a través de esa conexión?

Solo para simplificar las cosas mientras se da cuenta de esto, puede intentar sacar el chip del Arduino y colocarlo solo en una tabla de pan para poder controlar la energía directamente. También es posible que desee deshacerse de la conexión en serie y, en su lugar, utilizar un LED parpadeante para indicar si el programa se está ejecutando o está detenido.

Finalmente, verificaría la suposición de que los fusibles se están configurando como se esperaba durante su proceso de programación. Puede usar avrdude para volver a leer los fusibles del chip programado para ver si son lo que desea, intente leyendo los fusibles en tiempo de ejecución a través del software , o simplemente intente cambiar la velocidad del reloj a través de fusibles, programando el chip con su parpadeo código, y luego verifique que la velocidad de parpadeo haya cambiado para ser consistente con la nueva configuración del fusible.

Una vez que logre que el BOD esperado funcione como se espera, puede comenzar a agregar complejidad nuevamente para encontrar el problema.

    
respondido por el bigjosh

Lea otras preguntas en las etiquetas