TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Clemen89 en 29 de Junio de 2012, 05:59:36

Título: Dudas del perro guardián
Publicado por: Clemen89 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!
Título: Re: Dudas del perro guardián
Publicado por: BrunoF 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:

Cita de: Microchip PIC16F87XA Datasheet (http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf#page=157)
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.

Cita de: Microchip PIC16F87XA Datasheet (http://ww1.microchip.com/downloads/en/DeviceDoc/39582b.pdf#page=24)
!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.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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...
Título: Re: Dudas del perro guardián
Publicado por: BrunoF 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.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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!
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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 :)
Título: Re: Dudas del perro guardián
Publicado por: BrunoF 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
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 13:09:10
Haceme un favor. Compilalo y adjuntá el .cof y el .hex.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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.
Título: Re: Dudas del perro guardián
Publicado por: BrunoF 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!
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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.

Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 14:04:32
Agregale varios NOP; después del SLEEP(); y volveme a pasar todo modificado y compilado
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 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):

(http://www.todopic.com.ar/foros/imgtiny/fohl4x.png)

Lo dejo por si a alguien le ha pasado lo mismo y sabe cual es el problema.
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 14:27:20
Pues dejame decirte que en el simulador funciona perfecto...

(http://www.todopic.com.ar/foros/imgtiny/2h6xb84.png)

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

Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 06 de Julio de 2012, 14:32:08
Estas usando 9600 8N1 en ambas terminales? Puede ser un problema de polaridad de las lineas TX y RX...

Si estoy usando esos valores en ambos terminales :(.

Y perdona la ignorancia, ¿como puedo saber si el problema es de polaridad de las lineas TX y RX?

Un saludo y muchas gracias de nuevo! Es desesperante ver que todo parece funcionar bien y en la práctica no :S
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 14:39:34
Pues por lo que veo tampoco parece ser un problema de polaridad.

No podés ver los valores que recibís en hexadecimal? Lo estás probando con el hard real?
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 06 de Julio de 2012, 14:46:49
Pues por lo que veo tampoco parece ser un problema de polaridad.

No podés ver los valores que recibís en hexadecimal? Lo estás probando con el hard real?

No se lo que es el hard real así que supongo que no jeje.

Para la simulación estoy usando el MPLAB, y funciona perfecto en la simulación claro.

En la práctica solamente uso dos ventanas de hyperterminal y los conectores RS232 para conectar por un lado de la placa y por el otro lado a las 2 UART. Para ver lo que llega en hexadecimal pues sería ir pasando los ascii del hyperterminal a hexadecimal. Ahora edito y paso lo que me ha llegado al hyperterminal de la captura de antes a hexadecimal.

En principio todo funciona bien, puesto que en diseños anteriores funcionaba bien la comunicación. El problema ha venido cuando he metido el sleep, el WDT, y el querer recoger lo que llega en una cadena de caracteres antes de enviarlo ( en las pruebas anteriores iba enviando conforme llegaban los caracteres ). Y estoy muy frustrado, porque encima es que la comunicación del otro lado ( de dispositivo 2 a dispositivo 1 ) funciona bien ...

Algo que se me ha ocurrido que podría ser, es que con el despertar del WDT o al meterse en sleep cambie algun registro o algo relacionado con la transmisión, o que tras despertar la UART necesite un tiempo antes de empezar a enviar datos.

EDITO:

Vale lo que llegaba antes eran:

Los dos puntos esos que no se como ponerlos, no se si es el "NULL" en ascii, en cuyo caso sería el 00 en hexadecimal, o es "¨" en cuyo caso sería F9 en hexadecimal.

Y la ó es el 162 en ascii, lo que sería A2 en hexadecimal.

Y eso es lo que me ha salido como he dicho antes en la captura, al enviar ATATAT, tiene poco sentido la verdad.
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 14:55:42
Bueno. Sí, eso sería Hard Real. Cuando estás utilizando el PIC físicamente, lo solemos llamar Hard REAL, contrario al simulado.

Pues está rara la cosa.

Cómo estas conectando de la PC al PIC los RS-232? Los niveles de tensión y corriente no son los adecuados para conectar el PIC a la PC directamente... Deberías usar un MAX232 o simil antes de conectar desde/hacia la PC.

Yo probaría algo más sencillo. Antes del loop principal, probá enviar un par de caracteres a la terminal 2 a ver si recibe bien. Ese sería un buen comienzo.

Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 06 de Julio de 2012, 14:58:58
Bueno. Sí, eso sería Hard Real. Cuando estás utilizando el PIC físicamente, lo solemos llamar Hard REAL, contrario al simulado.

Pues está rara la cosa.

Cómo estas conectando de la PC al PIC los RS-232? Los niveles de tensión y corriente no son los adecuados para conectar el PIC a la PC directamente... Deberías usar un MAX232 o simil antes de conectar desde/hacia la PC.

Yo probaría algo más sencillo. Antes del loop principal, probá enviar un par de caracteres a la terminal 2 a ver si recibe bien. Ese sería un buen comienzo.



El pic lo tengo en una placa que he diseñado y tengo el MAX232 puesto claro, descarto que sea algo de la placa puesto que antes de complicarlo con el WDT, el sleep y la cadena de caracteres funcionaba la transmisión :S.

Iré probando cosillas un poco mas sencillas, pero me da mucha rabia porque al final no tendré mas alternativa que volver a esta situación, porque necesito usar el WDT con el sleep si o si :S.

Y gracias de nuevo Bruno!
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 15:07:10
Probá lo básico. Si envía bien sin el WDT, entonces hay que analizar mejor por qué surge el problema. Espero novedades.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 06 de Julio de 2012, 16:03:21
Bien traigo noticias nuevas.

He estado haciendo pruebas transmitiendo antes de que haya una interrupción, y despues del wake up del WDT, y he descubierto dos cosas:

-1º: La transmisión funciona bien.

-2º: La transmisión con el puerto RS232 del ordenador no funciona bien, solo funcionaba una parte porque solo me iba el conector que iba al USB del ordenador, el que iba directamente al RS232 no iba bien, por lo que puede que fuese problema del ordenador.

Además, intuyo que el CLRWDT fastidia la transmisión. Seguire haciendo pruebas pasando del puerto del ordenador, y tirare directamente al modem. ¡A ver si hay suerte!

Iré trayendo las novedades... por lo menos ya he descubierto algo despues de mas de 15 horas buscando algo.

EDITO: Pues no, el CLRWDT no fastidia nada de nada, todo funciona bien... ¿apostamos a que lo conecto al modem en vez de al ordenador y le envio cualquier chorrada para que me responda aunque sea ERROR y funciona? Como funcione... me pego un tiro, habré hecho el panoli toda la semana
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 06 de Julio de 2012, 17:06:47
Pues no sería raro, parece estar todo bien. Debe ser un problema de hardware.

Ya nos contarás. Todos hemos perdido mucho tiempo y esfuerzo en cosas sencillas.

Saludos.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 08 de Julio de 2012, 13:30:20
Aquí estoy de nuevo jeje.

Bueno pues ha fallado de nuevo, con el modem GSM no se comunica bien, he hecho una pruebecilla, he puesto en el while(1) de la funcion principal la instrucción INTF=1 para activar la interrupción de RB0 automáticamente, y he metido en la cadena de caracteres "AT+CPIN", y la UART por hardware funciona perfecto. Por lo que no se que es lo que falla, pero ya esta bastante bien acotado el problema.

El problema debe de estar en una de estas dos cosas diría yo:

- La interrupción de RB0 no funciona del todo bien o hay algo que no estoy teniendo en cuenta. He pensado que podría haber algun retardo al despertarse del SLEEP, pero he quitado el WDT y el sleep y sigue sin funcionar, por lo que queda descartado, seguimos acotando el problema.

- La recepción de la UART software no esta funcionando bien.


Tengo una dudilla que se me ha ocurrido en la ducha (jaja) y que puede que sea algo obvio pero como soy algo novatillo en esto... pues bueno, he estado pensando en como funciona la UART, y sino me equivoco se podría decir que es una señal cuadrada ( 0s o 1s, lo que vendría a ser 0V o 5V ), primero pone el bit a 0 para empezar la conexión, en nuestro caso 9600 baudios corresponden a un bit cada 104us, es decir pone un 0 durante 104us, luego un 1 por ejemplo de datos durante otros 104us y asi hasta el bit de stop.

Pues bien yo en la UART por software para la recepción, en el momento que se genera la interrupción, espero 104us ( para pasar el bit de START ) y cojo el primer dato, y asi sucesivamente hasta el bit de STOP. Y he pensado que puede que al estar recogiendo los datos en el límite de tiempo, es decir cada 104us nada mas cambiar el bit, puede que este cogiendo el bit anterior por cualquier retardo mal calculado o cualquier cosa. ¿Sería mas eficiente si una vez que llega el bit de start me espero 154us en vez de 104us para no estar tan al límite?

Es decir sería algo así.


  START           1er BIT         ..........................
                ____________
_________|                   |________________________________
     aquí             aqui


Coger los datos donde pone "aquí", es decir en el centro en vez de al principio, porque tal vez no tenga nada que ver en el problema, pero para ir descartando cosillas. Pero no estoy seguro si esto que he pensado es algo obvio y es como debería de haberlo hecho o no se puede hacer así por alguna razón.

Seguiré contando novedades!

Un saludo y gracias como siempre!
     
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 08 de Julio de 2012, 13:42:21
Hola.

Sí, puede tener que ver. Pero cuidado, que al uC le lleva varias instrucciones atender la interrupcion, que también es tiempo que debes de considerar y quitarle a los 154 ideales.

Saludos.
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 09 de Julio de 2012, 13:07:35
Hola de nuevo,

Traigo novedades, he comprobado que no fallan ni las interrupciones ni la transmisión, por lo que el error debe de estar en la recepción de la UART software sin mas remedio.

He hecho esto:

Código: [Seleccionar]
probando[0]='A';
probando[1]='T';
probando[2]='+';
probando[3]='C';
probando[4]='P';
probando[5]='I';
probando[6]='N';
probando[7]='?';
probando[8]=0x0D;
for(i=0;i<=indice;i++){
while(TRMT==0);
TXREG=probando[i];
}

Justo antes de enviar le he añadido yo lo que quería y funciona correctamente, además, entra en las interrupciones bien porque el valor de indice va en la interrupción, y envía el numero correcto de carácteres, por lo que sino me equivoco no queda otra que problemas en la recepción, pero es que es muy extraño porque en el simulador el tiempo esta correcto, además ahora he hecho lo que había dicho antes, de coger los datos en el centro de cada dato, por lo que tengo un margen bastante grande para recoger el dato :S.

¿Alguna idea de que puede ser el problema? Pongo la funcion de recepción aquí de nuevo:

Código: [Seleccionar]
if(INTF==1){
__delay_us(130);
for(i=0;i<8;i++){
recibido=recibido>>1;
if(RB0==1){
recibido = recibido | 0x80;
}
if(RB0==0){
__delay_us(3);
}
if(i!=7)__delay_us(83);
}
probando[indice]=recibido;
control_uart=1;
indice++;
CLRWDT();

Es a 9600 baudios, por lo que es un bit cada 104us, he colocado un retardo de 130 al principio para coger el dato en el medio, que serían los 104us + 26us añadidos por mí + retardo por la interrupción + retardo por las instrucciones = aproximadamente 156 diría yo.

EDITO: He hecho otra prueba, he recogido los datos por la UART software, pero le he metido un retardo de 8 segundos antes de enviar para que me diera tiempo a cambiar el cable RS232 en la placa  :lol: para ver exactamente que estoy enviando, y efectivamente, recoge los datos erroneos, y de 8 caracteres que he enviado 7 erán el caracter 253 en ascii, que es este "²", el superindice 2 ese, en binario "11111101", casi todo unos, cuando yo he enviado "atatatat", donde la 'a' es "11111101" y la t "1110100".

No comprendo que puede estar pasando... ¿que retardo puede haber en la generación de la interrupción?¿Y al despertarse del sleep? Bueno eso suponiendo que sea problema de la recepción en la UART software, que yo creo que con esto ha quedado claro que si.

Un saludo!

EDITO 2:

He visto en esta página http://www.cursomicros.com/avr/proteus/configuracion-propiedades-pic.html lo siguiente:

(http://i.imgur.com/Q5M30.png)

¿Eso es cierto? ¿Al despertar el pic hay un retardo de 1024 ciclos de reloj?
Título: Re: Dudas del perro guardián
Publicado por: Clemen89 en 10 de Julio de 2012, 08:37:30
Ah y otra cosilla mas, tengo a disposición el MPLAB ICD 2, ¿se podría hacer algun tipo de debugger para saber exactamente donde esta fallando con este dispositivo? Es que se que se puede usar de debugger pero no tengo muy claro hasta que punto.

Un saludo de nuevo!
Título: Re: Dudas del perro guardián
Publicado por: BrunoF en 10 de Julio de 2012, 15:03:25
Hola.

Pues según el datasheet:

Citar
12.6 Oscillator Start-up Timer (OST)

The Oscillator Start-up Timer (OST) provides a delay of
1024 oscillator cycles (from OSC1 input) after the
PWRT delay is over (if PWRT is enabled). This helps to
ensure that the crystal oscillator or resonator has
started and stabilized.
The OST time-out is invoked only for XT, LP and HS
modes and only on Power-on Reset or Wake-up from
SLEEP.

Parece que cumples con los requisitos, por lo que debería estar generando dicha demora. Podrías ajustar los tiempos y volver a intentarlo, teniendo en cuenta esta demora adicional.

Con respecto al ICD2, la verdad que no soy un gran debugueador utilizándolo. De hecho sólo utilizo el Pickit 3 para debuguear. Por ahí un osciloscopio sería de mayor interés si puedieses medir la demora entre que envias una señal para que despierte al uC, y el uC responda. (por ej. utilizando RB0 para desperar al uC del sleep y toggleando una pata inmeditamente luego de levantarse)

Saludos.