TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: japifer_22 en 28 de Septiembre de 2009, 21:07:35

Título: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 28 de Septiembre de 2009, 21:07:35
hola gente nuevamente, estoy teniendo un proble en el esclavo de una comunicacion RS 485 entre dos pic. la transmicion como tal funciona bien pero al agregarle mas rutina al esclavo aparte de la que lleva para la comunicacion, me empiesa a andar raro. les comento:
 el master me funciona a la perfeccion. el cual esta encerrado en un siclo while(TRUE){ }. para refrescar siempre la variable de envio de dato.

por otra parte el esclavo tiene dos interrupciones una es para recivir los datos del puerto RS-485 y el otro es para manejar un teclado matricial 4x4, pero el punto es que este si pongo esta interrupcion y sin lo demas que maneja esta interrupcion la comunicacion funciona bien, pero a la hora de agregarle el resto del codigo me empiesa adar problemas este consta de un par de if y else nada complejo y tambien lo probe en otro programa para descartar que fuera este pedaso de codigo,pero funciona bien.

bueno que raresas me da esto. es que cuando empieso a simular el master le tranmite bien los datos al esclavo pero cuando el master le entrego varios datos al esclavo este se pega, pero solo si ejecuto una rutina que viene del teclado, pero tambien lo raro esque la rutina del teclado no me anda. yo pienso que puede ser que al esclavo no le tengo un siclo infinito como un while(TRUE){} o for (;;){}...... bueno me explique bien ????? se entendio ????nesesito ayuda porfavor para ver que esta mal
este codigo tengo que hacerlo ante que llegen mis padres de unas mini vacaciones que se dieron por que quiero darle una sopresa  :lol:
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 28 de Septiembre de 2009, 23:44:24
hola, les comento que estuve viendo por aqui y por alla y no me acuerdo donde pero lei que se podia dever este error que se produce en mi esclavo por que teng oen este dos interrupciones, y en el momento que se requieran de las dos el nomeacuerdo que colapsa  :mrgreen: entonses se me acurria que podria ir activando de a una interrupcion a mdedida que la nesesito por medio de un botón. como puedo hacer esto ??????.
las interrupciones que uso en mi esclavo son la INT_RDA y la INT_RB.

lo que mensiono tiene algo que ver??????????? se podra hacer lo que digo ???????????
bueno saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: MLO__ en 29 de Septiembre de 2009, 00:32:47
Hola.

Puedes poner al inicio del código:

Código: C
  1. #priority RDA, RB

De esa manera le das prioridad a la interrupción RDA.

Saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 29 de Septiembre de 2009, 00:51:01
hola mlo gracias por responder pero probe lo que me dijiste y no resulta sigue asiendo nada. mejor les pongo el codigo para que vean de quese trata

Código: [Seleccionar]
unsigned char key;          //Variable global tecla
char string[7],stringg[7],sstringg[7];  //almasena nueros pulsados
int a,b,c,e,f,g,h,i,j,k,m;
int16 lectura;
float clave=0,password,comprobarClave,nuebaclave;

#int_RDA    //interrupcion para la resepcion del master
RDA_isr()
{
 lectura=GETC();  //guarda el valor enviado por el RS-485
}

// Interrupcion RB4 - RB7 /////////////////////////////////////////////////////
#INT_RB
void interrupt_keypad()               
{
   key=read_keypad();         //Asigna la tecla pulsada   
   clear_interrupt(INT_RB);   //Limpia bandera RBIF
   delay_ms(10);     
   
}

   // Programa Principal /////////////////////////////////////////////////////////
void main(void)
{     
 
   init_keypad();
   enable_interrupts(INT_RB);      //interrupcion INT_RB activada
   enable_interrupts(INT_RDA);     //interrupcion INT_RDA activada. comunicacion RS-485
   enable_interrupts(GLOBAL);      //todas las interrupciones activadas

/*
* Pin RC5 que habilita la transmisión por el canal RS485
* \li LOW Habilita recepción RS485
* \li HIGH Habilita transmisión RS485.
*/
      output_low(PIN_C5);
   
      output_d(lectura); //avilito puerto D como resepcion de comunicacion con master   



///////////////////nueva clave//////////////////////
if(key=='B'){         ///////////////presionar B + # para poder cambiar nueva clave if(key=='B'&&key=='F')
   output_high(PIN_A2);       //visulisa mediante LED vicolor el ingreso para cambiar clave (verde)
   output_high(PIN_A3);       //visulisa mediante LED vicolor el ingreso para cambiar clave (rojo)
   e=90;
}
e++;
if(e>=90){
   stringg[g]=key;
   f++;
   g=f-1;
if(key=='D'){
   a=0;
   e=0;
   f=0;
   g=0;
}
}
comprobarClave=atof(stringg);
if(comprobarClave==password&&key=='D'){
   strcpy( stringg,"       "); // borra string
   strcpy( sstringg,"       "); // borra string
   h=40;
}
if(h==40&&key=='C'){
i=90;
   output_low(PIN_A3); //led vicolor lo cambio a verde apagando el rojo para indicar el ingreso de nueva clave
}
i++;
if(i>=90){
   sstringg[k]=key;
   j++;
   k=j-1;
if(key=='D'){
   a=0;
   e=0;
   j=0;
   k=0;
   i=0;
   m=50;
output_low(PIN_A2);  //cambio de color led vicolor a rojo termino de cambio de clave                   
output_high(PIN_A3);   
}
}
if(m==50){
nuebaclave=atof(sstringg);
password=nuebaclave;
}
else{
password=123456;
}
////////////termino de nueva clave//////////////

/////////ingreso de clave/////////////////
if(key=='A'){                //presionar la A para ingresar clave (if(key=='A'&&key=='*');)
  a=90;
  output_high(PIN_A0);       //visulisa mediante LED rojo que no hay clave puesta
  output_low(PIN_A1);        //visulisa mediante LED verde el ingreso de clave correcta
  }
a++;
if(a>=90){
  string[b]=key;
  c++;
  b=c-1;
 
if(key=='D'){                //presionar D para finalisar ingreso de clave
  a=0;
  c=0;                         // borra contador de posicion string
  b=0;                         // borra borra el contador y pone en pocision cero del string
  e=0;
  i=0;
}
}

clave=atof(string);
//////////////////////termino de ingreso clave//////////////
/////////////////////verificar clave pulsada///////////////
if(password==clave&&key=='D'){ //comprueva la clave......

   output_low(PIN_A0);
   output_high(PIN_A1);
   strcpy( string,"       "); // borra string
}
/////////////////////termono de verificar clave///////////////
}

este es el esclavo
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: MLO__ en 29 de Septiembre de 2009, 00:54:37
Hola.

Ahi es mas claro que el agua jeje  ;-)

No se debe poner delays_ms() dentro de las interrupciones, eso hace que durante esos 10mS se deshabiliten todas las interrupciones.

Me imagino que al compilar te sale algun warning no?

Quita ese delay_ms() y prueba.

Hay algún delay en la función read_keypad()?

Saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 29 de Septiembre de 2009, 01:11:31
hola otra ves mlo te coment oque le saque lo que me digiste y me sigue aparesiendo un warning pero me di cuenta que si por ejemplo empieso transmitiendo datos del master al esclavo lo hace bien pero si presiono alguna tecla se interrumpe todo, y viseversa pasa lo mismo.

de todas formas te dejo el master para que veas = masel warning del esclavo

Código: [Seleccionar]
int8 x;

void main()
{     
   
/*
* Pin que habilita la transmisión por el canal RS485
* \li LOW Habilita recepción RS485
* \li HIGH Habilita transmisión RS485.
*/
 
   output_high(PIN_C5);

  while(true){
   x=PORTB;
   putc(x);
  }
}

Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: MLO__ en 29 de Septiembre de 2009, 01:16:38
Hola.

Ese warning es porque no has puesto void en la #int_RDA

Código: C
  1. #int_RDA
  2. void RDA_isr(void)
  3. {
  4.  lectura = getc();
  5. }

No olvides la directiva #priority RDA, a ver que sucede.

Algo que puedes hacer es deshabilitar la interrupción RB, cuando entras a la interrupción RDA, o usar una rutina para el teclado sin interrupción.

Saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 29 de Septiembre de 2009, 01:28:15
te coment oque no paso nada siguie igual. ahora te tengo 2 preguntas 1 tu tienes alguna rutina para manejar un teclado 4x4 sin interrupcion ?? que me puedas fasilitar ??? y lo otro es que yo en la mañana le pude al esclavo desavilitar una interrupcion si estaba apretado un boton osea

if(input(PIN_C0)){

disable_interrup(INT_RDA);
}
else{
disable_interrup(INT_RB);

estara bien esto para desactivar la interrupcion ??
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: MLO__ en 29 de Septiembre de 2009, 01:51:48
Si claro, pero al volver a habilitarla, debes limpiar el flag de la interrupcion en el registro y limpiar el bufer de recepcion, de caso contrario, éste va a almacenar el último dato enviado.

Saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 29 de Septiembre de 2009, 02:07:09
y como ago eso  :mrgreen: ??
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: MLO__ en 29 de Septiembre de 2009, 02:21:29
Eso se hace, si no estoy mal,  poniendo a ceros el bit 4 (TXIF) del registro PIR1.

Saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 29 de Septiembre de 2009, 02:27:40
suuuuuuu me pillaste nose como se hace todo eso de poner a cero lo que me dijiste pero aver si encuentro algo por algun lado.de todas maneras muchas gracias por la ayuda otorgada
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: Suky en 29 de Septiembre de 2009, 09:30:55
Para borrar los flags de las interrupciones está:

Código: C
  1. clear_interrupt(INT_RDA);
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: AKENAFAB en 29 de Septiembre de 2009, 09:50:04
Hola.

Puedes poner al inicio del código:

Código: C
  1. #priority RDA, RB

De esa manera le das prioridad a la interrupción RDA.

Saludos

Hola!

Tengo entendido que eso sirve si se llegase a producir interrupcion en el mismo instante.ENtonces ahí la rutina que toma la prioridad , esto solo en los 16F porque disponen de 1 solo vector, en los 18F usan High o Low por los vectores de interrupcion , el alto y el bajo y en esta gama 18F si se puede salir de una interrupcion baja para atender una alta.

Prueba agregando un retardo o revisa el estado del bit TRMT antes de volver a enviar.

Código: [Seleccionar]
int8 x;

void main()
{     
   
/*
* Pin que habilita la transmisión por el canal RS485
* \li LOW Habilita recepción RS485
* \li HIGH Habilita transmisión RS485.
*/
 
   output_high(PIN_C5);

  while(true){
   x=PORTB;
   putc(x);

delay_ms(1);   // <----Retardo Acorde al tiempo de tranmision

  }
}


[/quote]

Si solo usas 2 pics como indicas . pic-pic . puedes usar rs-422 , que usa la misma adaptacion hardaware , pero es full-duplex.Asi lo que sería como tener conectado RX1-TX2 TX1-RX2.Aunque seria un poco más caro , porque si solo usabas un max485 u otro similar , ahora sera otro más.


Saludos!

Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 29 de Septiembre de 2009, 22:46:04
hola aver si entendi AKENAFAB, la comunicacion full duplex es para que los dos pic transmitan y resivan informacion a la vez ?????. el hardaware son los mismos max-485?? solo que en vez de 1 por cada pic ahora son 2 ?????.
ahora bien el sofware en ves de definir 1 sola salita de TX y RX ahora tengo que definir 2 ?? osea

#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#use rs232(baud=9600, xmit=pin_c4, rcv=pin_c3, bits=8)

eso???

por otro lado tendria que poner a cada uno de los pic la interrupcion de #INT_RDA para capturar mi dato transmitido pero esta interrupcion la tengo que dejar siempre activada en ambos pic o la tengo que activar solo cando la nesesite?????????.

bueno me salen muchas dudas con respecto a lo que me mensionas...........me puedes explicar un poco mas de esto ???? por favor.
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: AKENAFAB en 30 de Septiembre de 2009, 00:23:56
Hola

No tienes que configurar 2 veces el puerto.

Es como si conectaras directamente los 2 pics con sus temrinales TX-RX.

La interrupcion #int_RDA , pues si la tienes que tener habilitada.

Asi El master Envia , el esclavo recibe y entra interrupcion , procesas el dato o lo que tengas que hacer y respondes , el master recibe el dato del slave , entra en interrupcion y procesas.

Para que no estes enviando coonstantemente el mismo dato del puerto , puedes crear una variable , en la cual guardes el ultimo valor del puerto y dato enviado , asi que mientras no sea diferente no envia nada y evitas entrar constantemente en Interrpcion.

Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: MLO__ en 30 de Septiembre de 2009, 00:27:30
Hola.

Creo que la mejor solución es usar una función de escaneo para el teclado sin interrupción. Revisa en la carpeta drivers del CCS el archivo KBD.C.

Saludos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 30 de Septiembre de 2009, 02:22:15
hola mlo bueno dejame desirte que en eso ando estoy probando la kbd2.c y me anda de lo mas bien ahora me queda probarla solo con la comunicacion para ver que tal anda.
saludos i de antemano gracias a todos
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 30 de Septiembre de 2009, 03:49:54
hola.... bueno e probado la comunicacion del RS-485 quitandole la interrupcion del teclado osea INT_RB pero susede ahora algo raro. en este caso el esclavo refleja lo del puerto B del master solo si presiono la tecla A del teclado del esclavo o la B, solo estas dos por que las tengo en un for( ; ; ){ }  y con estas dos teclas entro a 2 funciones diferentes. pero al presionar estas tecla no hace lo que deveria hacer (encender led). pero a parte de eso no me anda mal la comunicacion por lo menos no se pierde la comunicacion y transmite. ahora que se devera este problema ?????????????????????????

esto es la parte de las funciones del esclavo, por que el master no lo e tocado

Código: [Seleccionar]
int16 lectura;
#int_RDA    //interrupcion para la resepcion del master
void RDA_isr()
{
 lectura=GETC();  //guarda el valor enviado por el RS-485
}

///PROGRAMA
void main(void)
{   
   enable_interrupts(INT_RDA);     //interrupcion INT_RDA activada. comunicacion RS-485
   enable_interrupts(GLOBAL);      //todas las interrupciones activadas


   for(;;){   //bucle...
/** Pin RC5 que habilita la transmisión por el canal RS485
* \li LOW Habilita recepción RS485
* \li HIGH Habilita transmisión RS485.
*/
      output_low(PIN_C5);
      output_d(lectura); //avilito puerto D como resepcion de comunicacion con master       
     do{               //espera hasta...
         c=kbd_getc();   
         }while(c==0);   //...pulsar una tecla
     
      if(a==50){ nuevoPassword=password;}
         else{password=123456;}

       
      if(c=='B')         //ve a introducir nueva clave
         nueva_clave();
     
      if(c=='A')         //ve a comprobar clave
         comprueba_clave();
     
      }      //...infinito
}

por favor una ayudita  :mrgreen:
Título: Re: comunicacion RS 485 entre 2 pic
Publicado por: japifer_22 en 02 de Octubre de 2009, 03:22:02
hola otra vez, bueno solucione mi problema con la comunicacion, pero para mi mala suerte no encuentro el MAX-485 por ninguna tienda. asi que yo creo que tendre que emigrar al MAX232. alquien tiene algun ejemplo de mastes/slave con esta comunicacion?? en este yo puedo hacer que el mastes y el esclavo se comporter como master/slave ??? osea que un pic s pueda transmitir datos y recivir datos ???. saludos aa y algun esquematico para ver la conexion de este mismo alguien tendra ???? :mrgreen: