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.
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.
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.
!TO: Time-out bit
1 = After power-up, CLRWDT instruction, or SLEEP instruction
0 = A WDT time-out occurred
for(int i=0;i<=indice;i++){
CLRWDT();
while(TXIF==0);
TXREG=probando[i];
}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?
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.
#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();
}
}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.
Haceme un favor. Compilalo y adjuntá el .cof y el .hex.
Joer, necesito todo el código fuente también, sino el .cof no me sirve de nada!
Agregale varios NOP; después del SLEEP(); y volveme a pasar todo modificado y compilado
Estas usando 9600 8N1 en ambas terminales? Puede ser un problema de polaridad de las lineas TX y RX...
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?
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.
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];
} 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();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.