Autor Tema: Como resetear un 18f4550 sin usar masterclear  (Leído 6158 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Como resetear un 18f4550 sin usar masterclear
« en: 31 de Marzo de 2017, 08:25:51 »
Saludos, quiero resetear mi pic 18f4550 externamente (un botón push) usalmente uso el masterclear, en esta ocasión lo tengo fuera de disponibilidad, por lo que me necesito usar otro pin. Me han dicho por interrupción externa pero tampoco puedo usar esos pines que son del puerto b. Y tampoco se como usar la interrupción a modo de reset.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #1 en: 31 de Marzo de 2017, 08:54:44 »
Entonces...

MCLR - No se puede
Pines que aceptan Interrupcion - No se puede
Pines que no aceptan interrupcion - Si podes
Cortar la alimentacion - No se si es posible

Te quedan esas 2 opciones, la unica que dijiste que es posible es leer el pin y pedir un reset por software.
El codigo seria algo asi... Segun el compilador va a cambiar la sintaxis, deberas ajustarlo a lo que uses

Código: C
  1. if ( RA5 = 1 )
  2. {
  3.    asm('RESET');
  4. }

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #2 en: 31 de Marzo de 2017, 11:43:29 »
Entonces...

MCLR - No se puede
Pines que aceptan Interrupcion - No se puede
Pines que no aceptan interrupcion - Si podes
Cortar la alimentacion - No se si es posible

Te quedan esas 2 opciones, la unica que dijiste que es posible es leer el pin y pedir un reset por software.
El codigo seria algo asi... Segun el compilador va a cambiar la sintaxis, deberas ajustarlo a lo que uses

Código: C
  1. if ( RA5 = 1 )
  2. {
  3.    asm('RESET');
  4. }

Utilizo el CCS,  en verdad es así de sencillo por programa  :shock: solo que no tengo idea de si la stdlib tine ese método asm(); o es otra librería,  me da la impresión que 'RESET' es instrucción de un resgistro que en efecto manda a reiniciar el pic.. o me equivoco?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #3 en: 31 de Marzo de 2017, 13:59:55 »
No pero CCS tiene las directivas #ASM y #ENDASM, :

Código: C
  1. if ( RA5 = 1 )
  2. {
  3. #ASM
  4.     RESET
  5. #ENDASM
  6. }
« Última modificación: 31 de Marzo de 2017, 19:07:16 por KILLERJC »

Desconectado joseluislo12

  • PIC10
  • *
  • Mensajes: 20
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #4 en: 31 de Marzo de 2017, 18:47:51 »
También se podría empleando el WTD

Primero se declara

Código: [Seleccionar]
#FUSES WDT
Luego en el main se configura

Código: [Seleccionar]
void main (void){
   setup_wdt(WDT_ON|WDT_2S);
   ...
}

Dentro del while, o cualquier otra función, se resetea el contador para que no se reinicie el PIC cuando no se desea

Código: [Seleccionar]
while(true){
 RESTART_WDT();
}

Finalmente para que SÍ se reinicie el PIC se hace de la siguiente forma

Código: [Seleccionar]
if ( RA5 = 1 ){
   while(true);
}

De esa forma el WDT no se reinicia y cuando se desborda del tiempo, los 2 segundos que se configuraron, el PIC se reiniciará

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #5 en: 31 de Marzo de 2017, 21:47:05 »
Lo intente por ambos caminos chicos pero ninguno me dio resultado. La recomendación de killerjc lo puse del siguente modo:
Código: [Seleccionar]
void main()
{
while true(){
if(input(pin_e0)==1)//mi programa aquí comienza
while (game_over!=0)
{
......
}
}
if(input(pin_a4)==1)
{
#asm
    RESET
#endasm
}
}
}
el código compila pero al usar el simulador proteus, e ingresar un nivel alto por el pin a4 no me resetea el programa :c

y el de ,método de joseluislo:

Código: [Seleccionar]
// previa declaración de fuses junto el WDT
void main()
{
setup_wdt(WDT_ON|WDT_2S);
while true(){
 RESTART_WDT();
if(input(pin_e0)==1)//mi programa aqui comienza
while (game_over!=0)
{
......
}
}
if (input(pin_a4)== 1 ){
   while(true);
}
}
}
en tu caso me compila error el "WDT_2s"
« Última modificación: 31 de Marzo de 2017, 21:49:38 por raul6162 »

Desconectado Duende_Azul

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 902
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #6 en: 31 de Marzo de 2017, 22:01:28 »
En CCS puedes usar
Código: [Seleccionar]
reset_cpu();

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #7 en: 31 de Marzo de 2017, 22:32:20 »
Los 2 metodos dados deberian funcionar correctamente en fisico. El compilador no deberia darte error del WDT, podria llegar a ser un Warning pero no un error.

Tal ves por lo raro que es CCS, la unica solucion sea la que propone Duende_Azul, debo imaginar que hace lo mismo que hice yo.

Y si ya tampoco te funciona lo de Duende_Azul, entonces empeza a pensar en que es problema del simulador.

Desconectado joseluislo12

  • PIC10
  • *
  • Mensajes: 20
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #8 en: 01 de Abril de 2017, 09:22:35 »
Con este código funciona correctamente:

Código: [Seleccionar]
#include <18F4550.h>
#FUSES WDT, INTRC_IO, NOMCLR
#use delay(clock=8M)

void main(){
   setup_wdt(WDT_ON|WDT_2S);
   RESTART_WDT();

   output_HIGH(PIN_B2);
   delay_ms(300);
   output_LOW(PIN_B2);
   delay_ms(300);
   RESTART_WDT();

   output_HIGH(PIN_B2);
   delay_ms(300);
   output_LOW(PIN_B2);
   delay_ms(300);
   RESTART_WDT();

   output_HIGH(PIN_B2);
   delay_ms(300);
   output_LOW(PIN_B2);
   delay_ms(300);
   
   while(true){
      if(input(pin_A4) == 1){while(true);}
      else{
         RESTART_WDT();
         output_toggle(PIN_B1);
         delay_ms(100);
      }
   }
}

Para comprobarlo se ejecuta una breve secuencia en el LED rojo de la simulación cada vez que se inicia el programa, la cual consiste en prender y apagar dicho LED 3 veces.
Posteriormente en el while se estará conmutando el estado del LED verde constantemente mientras no se pulse el botón que está conectado al pin B1 con una resistencia de pull-down. Importante, en este momento se reinicia el contador del WDT para evitar que el PIC se reinicie automáticamente.
Si se pulsa el botón, le llegará un pulso alto al PIC por lo que quedará en el bucle del while(true) y, al no resetear el contador del WDT, el PIC se reiniciará ejecutando nuevamente la secuencia del LED rojo.



View My Video
« Última modificación: 01 de Abril de 2017, 09:43:30 por joseluislo12 »

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #9 en: 03 de Abril de 2017, 20:41:10 »
Va el modo de trabajo de este código muy buna explicación y ejemplo.
Pero no me quedo una cosa del todo clara, tengo que llamar en mi código la función restart_wdt(), antes de que el contador llegue a los 2 segundos que se configuro el WDT. ósea cada que considere se esta por cumplir o acercar a los 2 segundos en tiempo de mi código tendré que colocarla, porque si uso bastantes delays y ciclos, que se llevan sus 5 segundos o mas.

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #10 en: 03 de Abril de 2017, 20:42:57 »
En CCS puedes usar
Código: [Seleccionar]
reset_cpu();
Como uso esa función y que argumentos necesita?

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #11 en: 03 de Abril de 2017, 20:44:39 »
Con este código funciona correctamente:

Código: [Seleccionar]
#include <18F4550.h>
#FUSES WDT, INTRC_IO, NOMCLR
#use delay(clock=8M)

void main(){
   setup_wdt(WDT_ON|WDT_2S);
   RESTART_WDT();

   output_HIGH(PIN_B2);
   delay_ms(300);
   output_LOW(PIN_B2);
   delay_ms(300);
   RESTART_WDT();

   output_HIGH(PIN_B2);
   delay_ms(300);
   output_LOW(PIN_B2);
   delay_ms(300);
   RESTART_WDT();

   output_HIGH(PIN_B2);
   delay_ms(300);
   output_LOW(PIN_B2);
   delay_ms(300);
   
   while(true){
      if(input(pin_A4) == 1){while(true);}
      else{
         RESTART_WDT();
         output_toggle(PIN_B1);
         delay_ms(100);
      }
   }
}

Para comprobarlo se ejecuta una breve secuencia en el LED rojo de la simulación cada vez que se inicia el programa, la cual consiste en prender y apagar dicho LED 3 veces.
Posteriormente en el while se estará conmutando el estado del LED verde constantemente mientras no se pulse el botón que está conectado al pin B1 con una resistencia de pull-down. Importante, en este momento se reinicia el contador del WDT para evitar que el PIC se reinicie automáticamente.
Si se pulsa el botón, le llegará un pulso alto al PIC por lo que quedará en el bucle del while(true) y, al no resetear el contador del WDT, el PIC se reiniciará ejecutando nuevamente la secuencia del LED rojo.



View My Video
Va el modo de trabajo de este código muy buna explicación y ejemplo.
Pero no me quedo una cosa del todo clara, tengo que llamar en mi código la función restart_wdt(), antes de que el contador llegue a los 2 segundos que se configuro el WDT. ósea cada que considere se esta por cumplir o acercar a los 2 segundos en tiempo de mi código tendré que colocarla, porque si uso bastantes delays y ciclos, que se llevan sus 5 segundos o mas.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #12 en: 03 de Abril de 2017, 20:56:27 »
Citar
porque si uso bastantes delays y ciclos, que se llevan sus 5 segundos o mas.

Los delays son malos por naturaleza, podrias usar un Timer y solucionarlo, la otra es separar los delays de tal forma que no llega a cumplirse el tiempo e insertar la funcion de restar del WDT.

Esto tambien significa que vas a tener que esperar 2 segundos como maximo para que se resetee luego de detectada la condicion.

Desconectado joseluislo12

  • PIC10
  • *
  • Mensajes: 20
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #13 en: 06 de Abril de 2017, 09:35:14 »
Va el modo de trabajo de este código muy buna explicación y ejemplo.
Pero no me quedo una cosa del todo clara, tengo que llamar en mi código la función restart_wdt(), antes de que el contador llegue a los 2 segundos que se configuro el WDT. ósea cada que considere se esta por cumplir o acercar a los 2 segundos en tiempo de mi código tendré que colocarla, porque si uso bastantes delays y ciclos, que se llevan sus 5 segundos o mas.

Como bien dice KILLERJC, los delays tienen sus repercusiones.
Revisando el archivo fuente del PIC en cuestión que tiene CCS se encuentra la siguiente información:

Código: [Seleccionar]
#define WDT_4MS    0x300 
#define WDT_8MS    0x500 
#define WDT_16MS   0x700 
#define WDT_32MS   0x900 
#define WDT_64MS   0xB00 
#define WDT_128MS  0xD00 
#define WDT_256MS  0xF00 
#define WDT_512MS  0x1100 
#define WDT_1S     0x1300 
#define WDT_2S     0x1500 
#define WDT_4S     0x1700 
#define WDT_8S     0x1900 
#define WDT_16     0x1B00 
#define WDT_32S    0x1D00 
#define WDT_64S    0x1F00 
#define WDT_128S   0x2100

Eso quiere decir que para ese PIC el WDT puede tomar esos valores de tiempo. Los 2S fueron obviamente un solo ejemplo de cómo funciona el WDT, pero se puede seleccionar cualquiera de esa lista.

Si se tienen rutinas lo suficientemente largas que superen el tiempo del WDT de espera, como delays, solo veo las dos opciones mencionadas:
  • Hacer uso de algún TIMER para reemplazar dichos delays (Tal vez la más óptima pero más complicada)
  • Anidar diferentes delays que sumados resulten en el tiempo final, y entre X delays hacer el reseteo del WDT (no tan vistosa pero mucho más fácil de implementar)

Desconectado raul6162

  • PIC10
  • *
  • Mensajes: 19
Re:Como resetear un 18f4550 sin usar masterclear
« Respuesta #14 en: 08 de Abril de 2017, 20:14:39 »
Gracias a todos por su tiempo y conocimiento, al final si pude implementar el reset por el WDT :)