Autor Tema: comunicar pic  (Leído 3655 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
comunicar pic
« en: 01 de Junio de 2005, 11:02:00 »
tengo un f84a como master y dos f84a como esclavos .Mi pregunta es la siguiente el dataset del f84a dice que para comunicar en forma serie se usan PIN_B6 y PIN_B7 es lo mismo usar otros dos pines para tal fin ?

en mi programa tengo:
/*****pic master ****
#define Tx PIN_A4 // PIN de Transmisión
#define Rx PIN_B7 // PIN de Recepción
#use rs232(baud=9600, xmit=Tx, rcv=Rx)

/******pic esclavos *****
#define Tx PIN_B1 // PIN de Transmisión
#define Rx PIN_B0 // PIN de Recepción
#use rs232(baud=9600, xmit=Tx, rcv=Rx)

los configuré asi porque uso la interrupcion INT en lo pic esclavos .tengo todas las placas armadas ya para funcionar pero no lo pruebo porque no estoy seguro ahora despues de aber leido con mas detenimiento el dataset de los pic Enfurruñado .
Por otro lado ya los simulé en proteus pero..... Helado

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18310
    • MicroPIC
RE: comunicar pic
« Respuesta #1 en: 01 de Junio de 2005, 12:01:00 »
Si usas C, podrás utilizar prácticamente cualquier PIN como entrada o salida en una comunicación serie. Claro que siempre será más recomendable hacerlo en los pines asingados de fábrica, por que tienen implementada la USART a nivel hardware y, si quieres usar otros, el compilador emulará una USART por software, por lo que consumirá recursos del micro y tiempo de proceso.
Ahora bien, el 16F84 no tiene USART a nivel Hardware, y no la encontrarás en la datasheet. Lo que habrás visto y probablemente de ahí venga tu confusión es que los pines RB6 y RB7 son las señalos Clock y Data que se usan para programar el micro, pero sólo funcionan así en modo programación, no en modo ejecución.

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 682
RE: comunicar pic
« Respuesta #2 en: 01 de Junio de 2005, 21:42:00 »
Hola, si vas a usar la inetrrupcion RB0, tienes que colocar la rutina de RX en el vector de interrupcion, y configurar el pin para que correponda al cambio de flanco, ademas si es mas de un esclavo deberas acoplarlos a travez de rs-485, si no no va  funcionar, otra alternativa para tu caso es usar 1 hilo solo, en el manual de CCS encontraras detalles.

Otro consejo que puedo darte es que migres a un micro que posea USART en el hardware, puedes usar el 16F628 pero claro no podras usar cualquier pin, como ya esta explicado.

Para aclarate mas el asunto de usar RB0 como RX pin usando interrupcion, seria asi,

#INT_EXT

        ext_isr () {

       caracter=getc();

      }


Esto es para que tengas una idea de como implementarlo ademas, la configuracion del PIN_B0, ademas deberias definir este pin antes para que siempre sea entrada, asi es mas rapido, aqui va un ejemplo.

#use fixed_io(b_inputs=PIN_BO)      // aqui pones el pin b0 siempre como entrada

     ext_int_edge(H_TO_L);       // aqui set la interrupcion por fanco descendente                  
     enable_interrupts(INT_EXT);  // aqui set la interrupcion externa en PIN_B0
     enable_interrupts(global);     //  aqui habilita la interrupciones.        



Esto obviamente es para los receptores, y deberia funcionar, de cualquier modo te recomiemdo usar el ejemplo de 1 pin, pues va muy bien, yo lo he implementado con 5 micros en una sola tarjeta y responde 100%.

saludos

ARIEL

saludos
PikMan

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2569
RE: comunicar pic
« Respuesta #3 en: 01 de Junio de 2005, 23:53:00 »
Sí, puedes usar los pines que quieras. El CCS se las apañará para implementar la comunicación por software.

Como dice Nocturno, los pines RB6 y RB7 son las señalos Clock y Data que se usan para programar "en serie" el micro, pero una vez programado los puedes usar para lo que desees.

Un saludo

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #4 en: 03 de Junio de 2005, 11:24:00 »
gracias nocturno66 y pocher si que me equivoque en leyendo el dataset jajajaja.
gracias pikman tenia claro esos aspectos pero te agradezco mucho tus explicaciones que me ayudan a mi y al que encuentre un problema similar en sus proyectos .En cuanto a lo de usar un solo hilo no lo tengo visto pero voy a repasar el manual de ccs.
No me complique mucho tampoco solo se trata de que un pic le manda un byte a dos pic y dependiendo de que valor sea cada pic hace algo .En mi proyecto un pic lee en un teclado 3*4 y manda un byte (TECLA) y los otros dos pic operan un motor DC y un motor pap respectivamente .En Proteus anda 100 %
Gracias !!!

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #5 en: 05 de Junio de 2005, 12:45:00 »
bueno ya esta enchufado mi circuito Giño pero se me presentaron cosas que no esperaba como tener que mandar dos veces la orden con el pic master para que el esclavo haga lo que le dice .Por ejemplo presiono una tecla en el teclado y en el pic esclavo queda en:
 #use rs232(baud=9600, xmit=Tx, rcv=Rx) es como si se quedara esperando algo que no remino bien

cuando le mando otra vez la orden sí ejecuta lo que sigue:
#int_EXT
EXT_isr1()
{
a = getc();
if (!bit_test(a,7)){ /// con esto compruebo que la orden sea para este pic
      puerto_a=0;
      output_high(PIN_B2);           // prendo led
      delay_ms(100);
      output_low(PIN_B2);           // apago led
      funcion(a);   //una accion del motor
   }
}
salvando deste detalle todo anda bien Giño  

que pasa ?

*****///////// otro tema.... !

tengo en el proyecto cuatro displays pero parpadean mucho con la rutina siguiente y no creo que se pueda solucionar ya que si el tiempo que cada display se prende es de 50ms y si es menos no alumbrarian nadaLlorando la rutina que de visualizacion es :
void mostrar_d(){        //mostrar valores en displais
int i;
     for(i=0;i<=3;i++){                 
        port_temp=digito_in;         // en digito_in estan los 4 numeros a mostrar
     bit_set(port_temp,4);             // esto es para que no se me ativen los otros pic
     puerto_b=n_fila;                  //en n_fila estan los display que los manipulo con un 74ls139 al ygual que las filas del teclado
     puerto_a =port_temp;             //
     output_high(PIN_B1);             // prendo displays
     delay_ms(50);
     output_low(PIN_B1);             // apago displays
      }
}
 
la velosidad en que los displays rotan una vuelta es para que se den una idea cuatro veces mas rapido de lo que tardas en abrir y serrar los ojos jajajajajaja y queda feo jajajajajaja

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #6 en: 06 de Junio de 2005, 19:48:00 »
descubrí algo mas y no se como solucionarlo cuando el programa del esclavo comienza se activa la INT_EXT y se queda colgado en la siguiente linea:
#use rs232(baud=9600, xmit=Tx, rcv=Rx )
void main (void)
{
   delay_ms(100);
    set_tris_b( 0b01110001 );
   set_tris_a( 0b11110000 );
   setup_counters (RTCC_INTERNAL,0);
   ext_int_edge(H_TO_L);             
                port_b_pullups(FALSE);
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_RB);
   enable_interrupts(INT_EXT); //cuando se ejecuta esta linea salta a la interr. INT_EXT  en donde sta (a = getc() ;  ) y no sale de ese lugar hasta que le la interr. se ejecuta denuevo loco
   detener=0;
   t=20;
   while(TRUE){
      if(detener==1){
          output_low(PIN_B3);           
         output_low(PIN_B7);           
         run();
      }
      else puerto_a=0;
   };
}

cual sera el problema ??
ya mire mi circuito y la rutina del pic que causaria la interr. en los esclavos y no debería pasar esto desquiciado
mire el manual del ccs pero no hay nada explicado pikman comenta de hacer la comunicacion con un solo hilo. como seria esto?

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #7 en: 10 de Junio de 2005, 20:48:00 »
hola amigos siguiendo con mi monologo les cuento que en primer lugar llamar master o esclavo a los pic en este proyecto es solo para explicar de alguna manera lo que trato de hacer ya que el concepto de master y esclavo implica otras cosas como en el protocolo I2C que desconozco cor ser un aficionado a esto de los pic y veo una posibilidad de usar un recurso del compilador ccs para hacer algo simple con algo simple .Ahora bien me gustaría entender un poco mas pero el manual del ccs no dice mucho Llorando esto no me desanima demasiado ya que confió en la buena voluntad de la gente del foro Sonrisa .Me gustaría saber si esto de pasarle un byte a otro pic se puede realizar de la manera planteada mas arriba y si anda por aqui pikman que entiende mucho de estas cosas le voy a agradecer.

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #8 en: 11 de Junio de 2005, 21:18:00 »
Estuve leyendo sobre I2C y es espectacular Rebotado pero como lo implemento con unos 16F84A si no tienen esta prestación .Cono podría hacer para que dos pines de un puerto sean entrada en un momento y salida en otro ya que el protocolo lo requiere ? .La insistencia de usar los F84A es porque tengo el circuito armado y los únicos pines que tengo disponibles son los que en principio use para la comunicación RS232 .Existe una maneta en ccs de programar los puertos pines del puerto para que trabajen con el protocolo I2C ?

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 682
RE: comunicar pic
« Respuesta #9 en: 11 de Junio de 2005, 21:56:00 »
Gustavo03,
                   Bueno, mira con respecto al I2C, te explico CCS genera directamente el codigo necesario para que cuando en tu programa escribas i2c_start(); se genere un bit de stop en el bus sin que tengas que preocuparte como se hace, inclusive la inversion del sentido de SDA lo hace el mismo driver, asi que es mas facil de lo que parece.

No todos los compiladores incluyen estas funciones si bien incluyen librerias no estan incluidas por defecto, asi que ojo con este punto, si usas CCS no hay porque precuparse de nada, esta todo resuelto.

Como haces para usarlo en un PIC que no tenga modulo HW, pues sencillamente le decis en que pines queres usar como I2C SDA y SDL, asi por ejemplo en los pines A0 y A1 del 16F84

#use I2C(master, sda=PIN_A0,scl=PIN_A1)

ó en el pin que te plazca,


Ahora se complica si queres comunicar 2 pics via I2C pues CCS no puede usar un PIC que no posea modulo de HW I2C, como es el caso del 16F84, no puedes porque como esclavo solo los que tienen modulo de HW CCS maneja,  si podes hacerlo con un PIC16F88, o simplemente con cualquiera que posea esta prestacion.

Y si no tenes PIC con I2C HW, puedes bajar de www.microchip.com una libreria en ASM que hay para hacer un esclavo I2C, incluirla en el programa de tu esclavo y bueno, funciona yo lo probe con PIC16C54 que es un micro viejo de 12 bits, para hacer una aplicacion que consistia BPK para un LCD que debia poseer protocolo I2C, el programa lo hice completo en ASM porque este micro tiene 512 bytes de memoria, y bueno en C andaba muy justo.

Quizas debas hacerle algunas modificaciones a la libreria de microchip para incluirla en el C de CCS, en lo que refiere al uso de la memoria, lo demas anda casi seguro de una.

UNa vez que ese funcionado tenes que implementar en tu programa un sistema maestro esclavo pues solo puede en el I2C inciar comunicacion el MASTER, asi que deberas hacer poolling a cada esclavo si hay mas de uno, en periodos de acuerdo a tu aplicacion.

Si la comunicacion es entre 2 pics insisto en que mires el ejemplo del manual de CCS de 1 solo hilo (ver pagina 218 el manual de CCS), ademas podes bajar el manual de CCS y sus parches de la web de www.ccsinfo.com, y seguro vas a descubrir lo maravilloso que es este compilador.

Disculpa la tardanza en contestar,


saludos

ARIEL


saludos
PikMan

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #10 en: 13 de Junio de 2005, 22:20:00 »
Hola pikman me bajé el manual y experimente un poco con los ejemplos que da en EX_PBUSM.C y EX_PBUSR.C pero no logro nada .Simplifique un coco para solo dejar lo importante pero no se me ocurre mucho que digamos Enfurruñado .  
En un pic coloque solo la parte para transmitir y en el otro solo la parte para recibir  pero nada esperado.


#include <16F84A.h>
#fuses XT,NOWDT,NOPROTECT,NOPUT
#use delay(clock=20000000)

#use rs232(baud=9600, float_high, bits=9, xmit=PIN_B0, rcv=PIN_B0)


#define OUR_ID 1

#define MAX_MESSAGES 4
#define MAX_LENGTH   7

byte pbus_buffer[MAX_MESSAGES][MAX_LENGTH+1];
byte next_in=0;
byte next_out=0;
enum pbus_states {PBUS_IDLE=0x80,PBUS_NEED_LEN=0x81,PBUS_NEED_TO=0x82,
                  PBUS_NEED_FROM=0x83,PBUS_NEED_CS=0x84};
byte pbus_state=PBUS_IDLE;
byte checksum;
byte last_byte;

#bit ninth_bit = RS232_ERRORS.7
#bit collision = RS232_ERRORS.6
#bit intf = 11.1


void pbus_send( byte * message, byte to, byte len) {
   byte checksum,i;

   retry:
      checksum=len^OUR_ID^to;
      disable_interrupts(GLOBAL);
      collision=false;
      ninth_bit=1;

      putc(0xf1);           if(collision) goto error;
      putc(to);             if(collision) goto error;
      putc(OUR_ID);         if(collision) goto error;
      putc(len);            if(collision) goto error;
      ninth_bit=0;
      for(i=1;i<=len;++i) {
        checksum^=*message;
        putc(*(message++)); if(collision) goto error;
      }
      putc(checksum);       if(collision) goto error;
      intf=false;
      enable_interrupts(GLOBAL);
      return;

   error:
      delay_ms(16);
      enable_interrupts(GLOBAL);
      goto retry;
}

#include <input.c>
 
void main() {
   byte to,len,i,msg[MAX_LENGTH];
   set_tris_b(0b11111111);      
   set_tris_a(0b11111111);      
   do {
   for(i=0;i<5;++i) {
        msg=3; // solo por mandar algo
   }
     pbus_send(msg,2,5);//msg,to,len
   } while (TRUE); }

///********************en el otro pic******************

#include <16F84A.h>
#fuses XT,NOWDT,NOPROTECT,NOPUT
#use fast_io(A)
#use fast_io(B)
#use delay( clock = 4000000 )     /* reloj de 4 MHz */
#use rs232(baud=9600, float_high, bits=9, xmit=PIN_B0, rcv=PIN_B0)


#define OUR_ID 2

#define MAX_MESSAGES 4
#define MAX_LENGTH   7

byte pbus_buffer[MAX_MESSAGES][MAX_LENGTH+1];
byte next_in=0;
byte next_out=0;
enum pbus_states {PBUS_IDLE=0x80,PBUS_NEED_LEN=0x81,PBUS_NEED_TO=0x82,
                  PBUS_NEED_FROM=0x83,PBUS_NEED_CS=0x84};
byte pbus_state=PBUS_IDLE;
byte checksum;
byte last_byte;

#bit ninth_bit = RS232_ERRORS.7
#bit collision = RS232_ERRORS.6
#bit intf = 11.1

#int_ext
void pbus_isr() {
    byte data;

    if(kbhit()) {

      data=getc();

      if(ninth_bit) {
         switch(pbus_state) {
           case PBUS_IDLE : if(data==0xf1)
                                pbus_state=PBUS_NEED_TO;
                            break;
           case PBUS_NEED_TO :
                            if(data==OUR_ID)
                               pbus_state=PBUS_NEED_FROM;
                            else
                               pbus_state=PBUS_IDLE;
                            checksum=data;
                            break;
           case PBUS_NEED_FROM :
                            pbus_buffer[next_in][0] = data;
                            pbus_state=PBUS_NEED_LEN;
                            checksum^=data;
                            break;
           case PBUS_NEED_LEN :
                            last_byte = data+1;
                            pbus_buffer[next_in][1] = data;
                            pbus_state=2;
                            checksum^=data;
                            break;
         }
      } else
        if(pbus_state==PBUS_NEED_CS) {
           if(checksum==data)
               next_in = (next_in+1) % MAX_MESSAGES;
           pbus_state=PBUS_IDLE;
        } else if(pbus_state<0x80) {
           pbus_buffer[next_in][pbus_state] = data;
           checksum^=data;
           if(++pbus_state>last_byte)
              pbus_state=PBUS_NEED_CS;
      }
    }
}


#include <input.c>

void main() {
   byte i;
   set_tris_b(0b11111111);            
   set_tris_a(0b11111111);        
   ext_int_edge( h_to_l );
   enable_interrupts(global);
   enable_interrupts(int_ext);

   do {
      if(next_in!=next_out) {
         for(i=2;i<=pbus_buffer[next_out][1]+1;++i)
         next_out=(next_out+1) % MAX_MESSAGES;
      }

   } while (TRUE); }
 

Desconectado gustav03

  • PIC10
  • *
  • Mensajes: 31
RE: comunicar pic
« Respuesta #11 en: 15 de Junio de 2005, 23:24:00 »
Logre la comunicacion sin problemas de la comunocasion con dos hilos en mode serie disminuyendo los baudios a 300 .
En cuanto la comunicacion por un solo hilo sige sin andar transmite los datos pero el otro pic los toma con errores de transmicion en otras palabras activa la interrupcion pero no toma el valor transmitido .Cual es el problema ya probe muchas cosas pero bueno no tengo muy en claro como trabaja el protocolo serie.
otra pregunta que es esto (checksum=len^OUR_ID^to; ) ?


 

anything