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 ).
#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