Autor Tema: Dudas del perro guardián  (Leído 6200 veces)

0 Usuarios y 3 Visitantes están viendo este tema.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Dudas del perro guardián
« en: 29 de Junio de 2012, 05:59:36 »
Hola

Sigo con mi proyecto y necesito utilizar el perro guardián, porque quiero utilizar temporizadores en el modo sleep y es el único que puedo utilizar en modo sleep en el pic16F877.

Pero tengo muchas dudas.

Estoy utilizando el compilador de Hi Tech, y al utilizar la macro SLEEP(), una vez se desborde el perro guardián, ¿que pasaría? Se que se despierta, pero no se si sigue con la siguiente instrucción al SLEEP() o ocurre igual que con las interrupciones, saltando a la función de las interrupciones.

En el caso de que siga con la siguiente instrucción al SLEEP(), ¿como podría mandarlo a la función de las interrupciones de forma óptima? He leido que el goto en el lenguaje C no es lo mas adecuado, y no se si se puede llamar a la función de las interrupciones...

También tengo una duda con los flags, una vez que se desborda el perro guardián, se activan ciertos flags dependiendo si se ha desbordado estando en SLEEP, si se ha desbordado sin estar en el SLEEP porque se ha quedado pillado el programa por algún sitio, etc etc. Estos flags, ¿se borran manualmente o automáticamente una vez haces el CLRWDT? También he pensado que no es necesario tocarlos o que ni siquiera se pueda escribir en ellos, que sea solo informativo para saber que paso la ultima vez que se ha desbordado.

Un saludo y gracias como siempre!

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #1 en: 30 de Junio de 2012, 00:02:05 »
Hola!

Estoy utilizando el compilador de Hi Tech, y al utilizar la macro SLEEP(), una vez se desborde el perro guardián, ¿que pasaría? Se que se despierta, pero no se si sigue con la siguiente instrucción al SLEEP() o ocurre igual que con las interrupciones, saltando a la función de las interrupciones.

Sacado del datasheet:

device RESET (Watchdog Timer Reset). If the device is
in SLEEP mode, a WDT time-out causes the device to
wake-up and continue with normal operation (Watchdog
Timer Wake-up). The TO bit in the STATUS register
will be cleared upon a Watchdog Timer time-out.

Por lo tanto, si el WDT desborda con el dispositivo en sleep, en lugar de producir un RESET, lo despierta y continúa con la ejecución del código.

En el caso de que siga con la siguiente instrucción al SLEEP(), ¿como podría mandarlo a la función de las interrupciones de forma óptima? He leido que el goto en el lenguaje C no es lo mas adecuado, y no se si se puede llamar a la función de las interrupciones...

No puedo ayudarte realmente con esto, ya que no tengo experiencia con el compilador de HITECH, pero si el tratamiento de las interrupciones se hace desde una sóla funcion explícita, podrías deshabilitar las interrupciones globales y llamar a la función directamente. Habría que ver cómo planteaste el código y qué limitaciones tiene el compilador.

También tengo una duda con los flags, una vez que se desborda el perro guardián, se activan ciertos flags dependiendo si se ha desbordado estando en SLEEP, si se ha desbordado sin estar en el SLEEP porque se ha quedado pillado el programa por algún sitio, etc etc.

En esa mismo párrafo menciona que ante un desbordamiento del WDT durante un estado de SLEEP el bit TO del registro STATUS se pondrá a cero. Será tu deber entonces ponerlo a 1 para poder luego detectar futuros desbordamientos del WDT estando en SLEEP.

Estos flags, ¿se borran manualmente o automáticamente una vez haces el CLRWDT? También he pensado que no es necesario tocarlos o que ni siquiera se pueda escribir en ellos, que sea solo informativo para saber que paso la ultima vez que se ha desbordado.

!TO: Time-out bit
1 = After power-up, CLRWDT instruction, or SLEEP instruction
0 = A WDT time-out occurred

Como se puede ver en el datasheet, dicho bit se pone a 1 al encenderse el uC, al ejecutarse una instrucción CLRWDT y al ejecutarse una instrucción SLEEP.

En la mísma página puede verse que dicho bit es sólo lectura.

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #2 en: 05 de Julio de 2012, 16:19:24 »
Hola de nuevo, perdon por la tardanza

Primero, muchas gracias Bruno, porque a pesar de no haber contestado si había leído desde el trabajo tu post y me ha ayudado bastante.

Una última pregunta, cuando el perro guardián despierta al PIC del modo bajo consumo...¿rompe lo que hay en las variables?¿Cambia el valor de algun registro? O simplemente sigue con la ejecución?

Es que estoy desesperado con mi proyecto, llevo muchisimas horas y no consigo que funcione y ya no se si es por el perro guardián o por otra razón.

EDITO:

Pongo la parte del codigo que no me esta funcionando por si hubiera algún error.

Código: [Seleccionar]
for(int i=0;i<=indice;i++){
CLRWDT();
while(TXIF==0);
TXREG=probando[i];
}

Explico un poco:

HYPERTERMINAL ( 1 ) <-----> PIC <--------> HYPERTERMINAL ( 2 )

Estoy usando los hyperterminal para hacer pruebas simulando que son los dispositivos que voy a usar en mi proyecto. El hyperterminal (1) se conecta mediante una UART que he implementado por software al PIC, y el hyperterminal (2) se conecta mediante la UART hardware que trae de serie el PIC.

Primero recojo mediante una UART software una cadena que le meto por el hyperterminal (1), y se va a dormir, en el momento que el perro guardian lo despierta entonces envia la cadena hacia el hyperterminal(2), pero no recibe bien :( y ya no se que puede ser de verdad. Tras esto, el programa se queda esperando una contestación del hyperterminal (2) (sin irse a dormir) y en este sentido si que funciona correctamente la comunicación, de ahí a que piense que el perro guardián al despertar el PIC trastoca algo, o al irse a dormir. Estoy MUY frustrado.

Tampoco quiero meter muchos mas detalles del codigo porque tal vez sería demasiado tocho, pero si a alguien le interesa para poder echarme una mano que le haga una explicación mas extensa de todo el codigo se lo haría por supuesto sin problemas, ya estoy desesperado.

Para mas inri, para saber si el problema era de recepción de la UART software por retardos y tal, le hice una modificación al codigo, y puse que reciba lo que reciba los 4 primeros caracteres para enviar hacia hyperterminal (2) fueran "PEPE", y tampoco los recibio bien hyperterminal (2), por lo que puedo llegar a pensar que sea la transmisión desde el PIC hacia hyperterminal (2) lo que falla, aunque es extraño que la UART hardware del PIC no funcione al transmitir cuando la recepción si que lo hace bien. Estoy muy frustrado...
« Última modificación: 05 de Julio de 2012, 16:36:12 por Clemen89 »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #3 en: 06 de Julio de 2012, 02:19:10 »
Hola de nuevo, perdon por la tardanza

Primero, muchas gracias Bruno, porque a pesar de no haber contestado si había leído desde el trabajo tu post y me ha ayudado bastante.

Una última pregunta, cuando el perro guardián despierta al PIC del modo bajo consumo...¿rompe lo que hay en las variables?¿Cambia el valor de algun registro? O simplemente sigue con la ejecución?

No, no tiene por qué romper ni modificar mas allá de el/los bits que normalmente afecta. Simplemente debería continuar con la ejecución.

Cuando la cosa falla, hay que eliminar complejidad al problema. Probaste enviar al Hyperterminal 2 información? Envía bien? A veces es algo tan sencillo como los baudios mal configurados o polaridad invertida, etc...

 Viendo el código asi aisladamente no veo problema alguno, aunque debería verlo completo para poder decirte mejor...

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #4 en: 06 de Julio de 2012, 03:00:56 »
Hola de nuevo, perdon por la tardanza

Primero, muchas gracias Bruno, porque a pesar de no haber contestado si había leído desde el trabajo tu post y me ha ayudado bastante.

Una última pregunta, cuando el perro guardián despierta al PIC del modo bajo consumo...¿rompe lo que hay en las variables?¿Cambia el valor de algun registro? O simplemente sigue con la ejecución?

No, no tiene por qué romper ni modificar mas allá de el/los bits que normalmente afecta. Simplemente debería continuar con la ejecución.

Cuando la cosa falla, hay que eliminar complejidad al problema. Probaste enviar al Hyperterminal 2 información? Envía bien? A veces es algo tan sencillo como los baudios mal configurados o polaridad invertida, etc...

 Viendo el código asi aisladamente no veo problema alguno, aunque debería verlo completo para poder decirte mejor...

Saludos.

Gracias de nuevo Bruno!

Ahora mismo estoy en el trabajo, en cuanto llegue a casa primero probaré una cosa, que será lo que envió desde hyperterminal (1) al pic, volverlo a enviar hacia hyperterminal (1) y ver si el problema es solo de transmisión desde el PIC hacia el hyperterminal 2.

La verdad es que me extraña porque antes de meter el perro guardián y las cadenas de caracteres, simplemente lo que llegaba por el (1) lo mandaba al (2) directamente sin pasos intermedios, y viceversa... y de esta forma si funcionaba bien. Bueno, creo recordar que funcionaba todo bien porque yo ya dudo de todo.

Si no me sigue funcionando pondré las partes del código relativas a esto, saltandome la configuración de la UART, temporizadores y eso para que no sea tan pesado, solo interrupciones y rutinas de transmisión. A ver si tengo algún fallo tonto y no consigo verlo :S.

Un saludo y gracias otra vez!

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #5 en: 06 de Julio de 2012, 11:51:04 »
Hola de nuevo

Vengo de probarlo todo y estoy desesperado de verdad. Pongo el codigo completo y en negrita lo importante, el resto son simplemente valores para configurar las interrupciones y demas:

EDITO: No me deja poner en negrita ninguna parte del codigo.

En cualquier caso hay tres funciones, la de interrupciones ( void interrupt_isr ), la de enviar() (obvio) y el main ( del main solo hace falta mirar la parte del while, y tampoco demasiado ).

Código: [Seleccionar]
#include "htc.h"
#include "stdio.h"
#include "string.h"
#define _XTAL_FREQ 10000000

__CONFIG(0x3F76);

char recibido=0b00000000;
char probando[60]="                                                           ";
int control=0;
int control_perro=0;
int indice=0;
int contador=0;
int control_envio=0;
int control_uart=0;

void enviar(void){
CLRWDT();
TMR1ON=0;
TMR1H=0x00;
TMR1L=0x00;
indice--;
if(control_envio<1){
control_envio++;
control_perro=1;
}else{
control_envio=0;
control_perro=0;
}
if(control==0){
control_uart=0;
for(int i=0;i<=indice;i++){           // ENVIO DE PIC A (2) LO RECIBIDO POR LA UART SOFTWARE
CLRWDT();
while(TRMT==0);
TXREG=probando[i];
}
}else if(control==1){

for(int i=0;i<=indice;i++){         // ENVIO UART SOFTWARE, de PIC A (1)
recibido=probando[i];
RB1=0;
__delay_us(95);
for(int i=0;i<8;i++){
if((recibido&0x01)==0x01){
RB1=1;
}else{
RB1=0;
}
recibido=recibido>>1;
__delay_us(89);
}
__delay_us(2);
RB1=1;
__delay_us(102);
CLRWDT();
}
}
indice=0;

}

void interrupt isr(void){
recibido=0b00000000;
CLRWDT();
if(INTF==1){
control=0;
__delay_us(89);
for(int i=0;i<8;i++){                                         // RECEPCIÓN UART SOFTWARE
recibido=recibido>>1;
if(RB0==1){
recibido = recibido | 0x80;
}else{
#asm
NOP;
#endasm
}
if(i!=7)__delay_us(85);
}
probando[indice]=recibido;                   // VOY GUARDANDO EN PROBANDO LOS CARACTERES, Y QUITO FLAG INTF
indice++;
INTF=0;
control_uart=1;                                  // VARIABLE CONTROL, PARA QUE LA PROXIMA VEZ QUE  WDT DESPIERTE A PIC VAYA A ENVIAR
CLRWDT();
}else if(RCIF==1){                    // RECEPCION UART HARDWARE, DE (2) A PIC
control=1;
TMR1ON=1;                    // ACTIVO TIMER1, CUANDO PASEN 10 SEGUNDOS, SE DA POR ACABADA LA RECEPCIÓN
recibido=RCREG;
probando[indice]=recibido;
indice++;
CLRWDT();

}else if(TMR1IF==1){
CLRWDT();
TMR1IF=0;
contador++;
if(contador==50){
contador=0;
enviar();                     // TRAS 10 SEGUNDOS DE RECIBIR POR UART HARDWARE, ENVIAR DATOS
}
}
CLRWDT();
}[/b]



void main(){

PSA=1;
PS0=1;
PS1=1;
PS2=1;
CLRWDT();
T1CON=0b00110000;
TMR1H=0;
TMR1L=0;
TMR1IF=0;
TMR1IE=1;
GIE=1;
PEIE=1;
INTF=0;
INTEDG=0;
INTE=1;
RB1=1;
TRISB=0b11111101;
TRISC=0b10111111;
BRGH=0;
TXEN=1;
SPBRG=15;
SPEN=1;
CREN=1;
RCIE=1;
[b]while(1){
if(control_perro==0){
SLEEP();
}
if(nTO==0&&control_uart==1){
enviar();
}
CLRWDT();
}
}

Explicación:

(1) <----> PIC <-----> (2)

Primero, el único dispositivo que tomará la iniciativa sera el (1), por eso al (1) le voy a colocar la UART por software que tengo como RX la patilla RB0, para que cada flanco de bajada en la patilla genere una interrupción. ¿Por qué? Porque en modo bajo consumo la interrupción asociada a la UART hardware no despierta al PIC, por lo que obligatoriamente tengo que usar el dispositivo que vaya a tomar la iniciativa en la comunicación en RB0 (UART software) para que despierte al PIC.

Vale, la comunicación por lo tanto sería de (1) a PIC, de PIC a (2), (2) responde a PIC, PIC responde a (1) dependiendo de lo que haya dicho (2).

Bien, mi idea era el PIC esta en modo bajo consumo, y en el momento que (1) se comunique con el PIC, se despertará ( porque RB0 generará una interrupción ), recibirá los caracteres necesarios y pasa a dormir el pic. El perro guardián lo tengo configurado para que cada 2,3s despierte al PIC, por lo que como tengo CLRWDT por ahí metidos, la secuencia sería: PIC se despierta, empieza a recibir caracteres y a guardarlos en la cadena de caracteres probando[], una vez estan todos los caracteres recibidos y guardados en probando[], se queda en el SLEEP hasta que lo despierte el WDT, cuando lo despierte tras haber recibido la cadena, pasará a llamar a la función enviar.

En la función enviar, simplemente configuro unas variables de control para no vuelva al modo bajo consumo hasta que acabe toda la comunicación de la UART hardware, porque en modo bajo consumo la UART hardware no funciona. Y por supuesto, en esta función envia por la UART harware lo que hemos recibido por la UART software anteriormente, recordemos que la UART hardawe va hacia dispositivo (2). Bien, ya tenemos un camino recorrido.

Ahora el PIC se queda esperando a que le llegue algo del dispositivo (2) sin entrar al modo bajo consumo recordemos. Recibe todos los caracteres y los va almacenando en la cadena de caracteres probando[] otra vez. Para controlar esto, uso un temporizador que se activa cuando empieza la transmision de datos entre (2) y PIC, tras 10 segundos, la comunicación se da por realizada ( he puesto 10 segundos para que le de tiempo de sobra ). Ahora los datos estan guardados en probando[], los datos que ha enviado (2) a PIC como respuesta a lo que el PIC le había enviado anteriormente.

Y finalmente, cuando el temporizador acaba tras 10s y tenemos guardado los datos en probando[], el PIC envia mediante la UART software ( hacia dispositivo (1) ) lo guardado en probando[] uno a uno.

Bien, mas o menos sería así, se que es muy complicado de entender un codigo que no has hecho tu y mas sino esta comentado, pero cualquier ayuda será muy bien recibida porque estoy completamente desesperado.

Datos a saber:

- La comunicación, curiosamente, no funciona de (1) a PIC y de PIC a (2), es decir el primer camino no funciona. Sin embargo, el camino de respuestas si, el caminos de respuestas me refiero a la 2ª parte de la comunicación, es decir de (2) a PIC y de PIC a (1), esta parte funciona perfectamente.

- He probado a justo antes de enviar de PIC a (2), poner en la cadena de caracteres al principio en las posiciones [ 0 ] y [1] los caracteres 'P' y 'E'. ¿Para que? para comprobar si la UART hardawe si funcionaba bien, y no funcionaba bien. Bueno aclaro que la recepción de la UART hardware ( de 2 a PIC ) si funciona bien, es la transmisión lo que no funciona bien ( de PIC a 2 ). He comprobado que al parecer no funciona nada del primer camino, ni de (1) a PIC ni de PIC a (2). Bueno, funcionar funciona, pero la comunicación no es la correcta, en el hyperterminal me salen caracteres raros.

- De momento, en vez de usar los dispositivos, que seran (1) modem gsm y (2) estación meteorológica, estoy usando dos ventanas de hyperterminal para simular a los dispositivos.

Si hay alguien que se haya podido leer este tochazo ( se que va a ser dificil ) y tiene alguna duda solo tiene que decirmelo. Y muchas gracias a todos y en especial a Bruno y AngelGris que me estais echando una mano bastante grande con el proyecto :)
« Última modificación: 06 de Julio de 2012, 12:08:01 por Clemen89 »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #6 en: 06 de Julio de 2012, 12:54:50 »
Hola, voy poniendo lo que encuentro:

Del datasheet:

Citar
Bit SPEN (RCSTA<7>) and bits TRISC<7:6> have to
be set in order to configure pins RC6/TX/CK and
RC7/RX/DT as the Universal Synchronous Asynchronous
Receiver Transmitter.

Fijate que vos configuras TX como salida, cuando según el datasheet debe ser configurado como entrada también.

GIE debería ser puesto en alto sólo una vez que terminaste de configurar e inicializar completamente TODO lo del uC
« Última modificación: 06 de Julio de 2012, 12:58:13 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #7 en: 06 de Julio de 2012, 13:09:10 »
Haceme un favor. Compilalo y adjuntá el .cof y el .hex.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #8 en: 06 de Julio de 2012, 13:14:33 »
Haceme un favor. Compilalo y adjuntá el .cof y el .hex.

Gracias Bruno otra vez!

Adjunto en un zip los dos archivos.

De verdad que te agradezco el tiempo que me estas dedicando :).

EDITO: Creo que el TX tengo que configurarlo como salida, como entrada lo acabo de probar y no envia nada, de la otra forma envia pero no los caracteres correctos.

Yo creo que el "set" en esa frase se refiere mas a "establecer" que a "poner a 1".

EDITO2: Vuelvo a adjuntar el archivo .zip, que el otro era de una versión antigua me había equivocado, aunque solo cambian un par de cosas, una de ellas es activar el WDT por lo que es importante el cambio.
« Última modificación: 06 de Julio de 2012, 13:31:16 por Clemen89 »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #9 en: 06 de Julio de 2012, 13:32:24 »
Joer, necesito todo el código fuente también, sino el .cof no me sirve de nada!
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #10 en: 06 de Julio de 2012, 13:38:07 »
Joer, necesito todo el código fuente también, sino el .cof no me sirve de nada!

Te dejo este zip con casi todos los archivos.


Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #11 en: 06 de Julio de 2012, 14:04:32 »
Agregale varios NOP; después del SLEEP(); y volveme a pasar todo modificado y compilado
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #12 en: 06 de Julio de 2012, 14:07:26 »
Agregale varios NOP; después del SLEEP(); y volveme a pasar todo modificado y compilado

Ahí dejo con los NOP puestos. He puesto 7 o así, voy a meter el programa en el pic a ver que tal va.

Desconectado Clemen89

  • PIC10
  • *
  • Mensajes: 30
Re: Dudas del perro guardián
« Respuesta #13 en: 06 de Julio de 2012, 14:17:14 »
Nada, sigue sin funcionar.

Aquí dejo una captura del hyperterminal que simula al dispositivo (2), esto es lo que recibe cuando le he enviado "ATATAT" desde el hyperterminal que simula al dispositivo (1):



Lo dejo por si a alguien le ha pasado lo mismo y sabe cual es el problema.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Dudas del perro guardián
« Respuesta #14 en: 06 de Julio de 2012, 14:27:20 »
Pues dejame decirte que en el simulador funciona perfecto...


Estas usando 9600 8N1 en ambas terminales? Puede ser un problema de polaridad de las lineas TX y RX...

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.