Ir ao conteúdo

Comunicação entre dispositivos


Rodrigo Lange

Posts recomendados

Postado

Pow pessoal desculpem a demora em responder...

Faculdade e trabalho matam qualquer um..

E ainda construindo casa.. To morto.. 

Mas a ideia é fazer mesmo @xykote..

Até ja estou deixando preparada a construção para receber quaisquer tipo de automação.. Seja wireless.. cabeamento estruturado POE.. etc...

Poderia comprar pronto mas não teria o mesmo prazer de fazer e opinar haha.

Essa semana vou dar alguns passos a diante e posto a evolução do projeto.

abraços

Postado

Olá amigo, faz tempo que não passo por aqui mas como estou retomando meus trabalhos com PIC, resolvi dar uma passada e li o seu tópico. A um tempinho atrás eu estava com o mesmo problema, o de estabelecer uma rede de comunicação entre diversos pics. O meu objetivo nesse projeto era "multiplexar" uma porta serial em 6 ou mais. Para isso, eu tinha como intuito usar um PIC18F4620 ou 4550 como master e PIC18F2550 como slaves, e estabelecer a comunicação entre eles usando o protocolo I2C. Eu cheguei a fazer um programa para o master, e outro para o slave que funcionaram no Proteus, mas minhas prioridades mudaram e eu acabei desistindo de evoluir o projeto, até porque, o programa acabou ficando confuso pra caramba e eu fiquei com preguiça de arruma-lo. Como base para começar o programa, eu usei o tutorial do site microcontrolandos que ensina fazer comunicação entre 2 Pics via I2C e usar um deles como memória RAM. Com esse sistema, eu posso criar uma rede de até 16 Pics slaves cada um com um endereço que vão de 254 a 222 se não me engano. 

Vou postar os programas:

Slave:

#define SSPCON SSPCON1   //PIC18F//#define SSPCON SSPCON  //PIC16F//ENDEREÇO DO SALVEconst ADDRESS_SLAVE = 224;char ADDRESS_SLAVE_STR[4]="224";//VARIAVEIS//rx char i = 0;//int j;char sspd; //leo conteudo de SSPBUF só para apaga-lo.//rx unsigned EnderecoDaRAM = 0;int aux=0; // ...Slave é requisitado para enviar um byte ao Mastershort xEndereco=0;//char repet=43;//bit flag_buff;char xbuffer[500];//auxiliar buffer de stringchar buffer2[500]="teste teste teste 3x";//buffer secundaria. Armazena penultima string recebida.char buffer3[500];//char xstring[10];//string auxiliarchar Comando[100]=""; //string que recebe o Comando a ser enviado//char valor[10]="";int xComando=0; //contador da string comandoint xBuff; //auxiliar marca de imediato quantos bytes foram recebidos em buffint xfor;  //auxiliar contador geral loop forint xSSPBUF2; //auxiliar contador buffer 2 transmissão I2Cint xSSPBUF3; //auxiliar contador buffer 3 transmissão I2Cint ContBuff3;Contbuff2; //auxiliar contador do bufferint timer1; //contador de timer 1//int ComaShift;int xTres;//contador que impede a gravacao dos 3 primeiros dados na string Comandobit flagComando; //flag sinaliza recebeu novo Comando. Ativa o Tx do UART.bit flagTimer1; //flag de estouro de timer 1bit flag232; //flag de nova transmissao 232/UART recebida;bit flag_buffer3; // flag de conteudo no buffer 3;bit dadoRecebido;//bit flagFirstPass;//PONTEIROchar *Ptr = 0x0000;void Buffer_Read(char *buff){ SSPBUF = *buff; Uart_write(*buff); SSPCON.CKP = 1; buff++;}void I2C_Slave_Init(){  ADCON1 = 0x0f; //Desliga a porta analogica  TRISB = 255; //Define os pinos do modulo I2C como entrada  SSPADD =  ADDRESS_SLAVE; //Define o endereço do slave  SSPCON = 0x36;   //configura I2c como slave, 7bits  PIE1.SSPIE = 1;  //habilita interrupção do modulo I2c  INTCON = 0xC0;   //habilita interrupçao global e dos perifericos  TRISC.RC2=0;  LATC.RC2 =1;}void interrupt(){  // interrupção para Timers    if (TMR1IF_bit)     {      TMR1IF_bit = 0;      TMR1H         = 0x0B;  //1s 8MHz      TMR1L         = 0xDC;  //1s 8MHz      //TMR1H         = 0xB1;//10ms 8Mhz      //TMR1L         = 0xE0;//10ms 8Mhz      xbuffer[xbuff]=0; //encerra a string.      timer1++;      if(flag232==1){flagtimer1=1;}     }/*if (TMR2IF_bit)     {      TMR2IF_bit = 0;      //LATB.B6=~LATB.B6;     }*//////////////////////////////////////////////////////////////////////  //interrupção para armazenamento em buffer (sensor -> Buffer)  if(RCIF_bit)   {     RCIF_bit=0;     RCIE_bit=0; //desabilita interrupção no Rx       if(xbuff>498){xbuff=0;} //impede overflow do buffer       xbuffer[xbuff]=UART1_Read(); // grava na posição xbuff o dado recebido       xbuff++; //passa uma posição adiante       flag232=1; //... se houver escrita no xbuffer, buffer3 = buffer2 e                  // buffer2 = xbuffer feito no while do void main.     RCIE_bit      = 1; //habilita interrupção no Rx     TMR1IE_bit    = 1; //será habilitado quando houver escrita no 232     TMR1ON_bit    = 1;     dadoRecebido  = 1;   }/////////////////////////////////////////////////////////////////////  if (PIR1.SSPIF == 1)  {    LATC.RC2=~LATC.RC2;    PIR1.SSPIF = 0;/////////////////////////////////////////////////////////////////////    //Slave é requisitado para enviar um byte ao Master    if (SSPSTAT.R_W == 1)    { //envia os 3 bytes que contem o endereco primeiro.            if(xEndereco<3)        {         SSPBUF = ADDRESS_SLAVE_STR[xEndereco];         SSPCON.CKP = 1;         xEndereco++;}      else{        //Transmite o que tem no buffer 2        SSPBUF = buffer2[aux];        SSPCON.CKP = 1;//libera o clock - envia o dado no SSPBUF        aux++;        if(aux>1)//não deixa executar na primeira e segunda passada. =D         {       //se executar na prim./segun. passada, aux == (-2) apontará                 //endereço inexistente de memória e enviará valor incorreto.         if(buffer2[aux-2]==0){aux=0;xEndereco=0;} //verifica qual valor no buffer ==0                //o buffer2 precisa enviar dois bytes a mais para o master                 //para que ele receba o byte de valor 0 e o próximo,                 //onde ele irá encerrar a comunicação, porque é o master                 //quem pede a comunicacao.         }        } //fecha else      } //Fecha o if (SSPSTAT.R_W == 1)/////////////////////////////////////////////////////////////////////    //Slave é requisitado para receber um byte do Master    if(SSPSTAT.R_W == 0)    {            if (SSPSTAT.D_A == 0)          //Recebeu um endereço?        {         sspd = SSPBUF;                 //ler o buffer para esvazia-lo        }        else                           //Recebeu um dado qualquer?        {        Comando[xComando]=SSPBUF;        if(xTres<3){xTres++;} //impede a gravacao dos 3 primeiros bytes enviados        else{xComando++;}        flagComando = 1; //Ativa no main o envio da string        }// fecha o else     }    //Buffer    if (SSPSTAT.BF == 0)    {      //j = SSPBUF;      return;    }  } // fecha o PIR1.SSPIF == 1} // fecha o interruptvoid main(){    //Configuração do interrupção USART RX - RS-232.    RCIF_bit=0; //EUSART Receive Interrupt Flag bit    RCIE_bit=1; //EUSART Receive Interrupt Enable bit    RCIP_bit=1; //EUSART Receive Interrupt Priority bit (High)    TXIE_bit=0;  //EUSART Transmit Interrupt Enable bit //Configuração do I2C_Slave    I2C_Slave_Init(); //Configuração dos timers. // InitTimer1()    T1CON         = 0x31;    TMR1IF_bit    = 0;    TMR1H         = 0x0B; //1 segundo 8MHz    TMR1L         = 0xDC; //1 segundo 8MHz    TMR1IE_bit    = 0; //será habilitado quando houver escrita no 232    TMR1ON_bit    = 0;    //TMR1H         = 0xB1;//10ms 8Mhz    //TMR1L         = 0xE0;//10ms 8Mhz // InitTimer2()/*T2CON         = 0x26;    PR2           = 250;    TMR2IE_bit    = 0;    INTCON        = 0xC0;    TMR2ON_bit=1;*/    //INTCON         = 0xE0;    UART1_Init(9600);    delay_ms(100); //Configurações adicionais.    TRISB.B7=0;    TRISB.B6=0;    TRISB.B5=1;    TRISB = 0b00011111; //define pinos como entrada para I2C (RB0 + RB1). //Habilitando interrupções    INTCON      = 0xC0; //Zerando variaveis.xbuff=0; //auxiliar marca de imediato quantos bytes foram recebidos em buffxfor=0;  //auxiliar contadorContBuff3=0;Contbuff2=0;timer1=0;flagTimer1=0;flag232=0;flag_buffer3=0; //xSSPBUF2 = 0;xSSPBUF3 = 0;flagComando=0;xComando=0;aux =0;//flagFirstPass=0;//ComaShift=0;xTres=0;    while(1){      ////////////////////////////////////////////      if(flagComando) // indica o recebimento de comando e ativa o envio       {        delay_ms(100);//essencial para dar tempo da int. do I2C escrever todo vetor.        UART1_Write_text(Comando); //transmite o comando        Uart1_Write(10);        Uart1_Write(13);        xComando=0; // depois de enviar a mensagem, reseta o contador xComando        flagComando=0; //reseta o flag de comando        xTres=0; //reseta o contador que impede a gravacao dos 3 primeiros bytes transm.        }              /////////////////////////////////////////       if(flagtimer1==1)//Se houve o esturo de timer 1...       {//Uart_write_text("flagtimer1");        TMR1IE_bit = 0; //Desativa o timer 1        TMR1ON_bit = 0;        flagtimer1 = 0; //Apaga o flag do timer1        if(flag232==1)//... E se houve escrita no 232          { flag232=0;            ContBuff3=ContBuff2;//passa o que tiver no buffer2 para o buffer3            for(xfor=0;xfor<contbuff3;xfor++)               {               buffer3[xfor]=buffer2[xfor];               }            contbuff2=xbuff;//passa o que tiver no xbuffer para o buffer2            for(xfor=0;xfor<contbuff2;xfor++)               {               buffer2[xfor]=xbuffer[xfor];               }            xbuff=0; //depois de copiado o conteudo de xbuffer para buffer2, prepara para receber nova string            flag_buffer3=1;            if(dadoRecebido)               {               Uart1_Write_Text("Dado Recebido \r\n");               Uart1_Write_Text(buffer2);               Uart1_Write(1);               dadorecebido=0;               }           }//if(flag232==1)       }//fecha  if(TMR1IF_bit == 1)       ///////////////////////////////////////////    }//fecha while 1}

Master:

// VARIAVEIS GLOBAISint xComando=0;int xfor=0;int ADDRESS_SLAVE = 224;int iTemp=0;char Comando[100]="   abcdefghijklmnopq";char mensagem[500]="";char Endereco[10]="065";short dispositivos=1;bit flagComando; // flag para enviar comando a um determinado slavebit flagTimer1;  // indica estouro de timer 1bit flagOneTime;unsigned char HidReadBuff[64]  absolute 0x500;unsigned char HidWriteBuff[64] ="teste USB" absolute 0x540;int teste=0;// Habilitar Software I2Csbit Soft_I2C_Scl           at RC0_bit;sbit Soft_I2C_Sda           at RC1_bit;sbit Soft_I2C_Scl_Direction at TRISC0_bit;sbit Soft_I2C_Sda_Direction at TRISC1_bit;// Lê um texto via Soft I2Cvoid SI2C_Slave_Read_Text(char *out){ bit flag_out;  char txt [10];  Soft_I2C_Start();  Soft_I2C_Write(ADDRESS_SLAVE);  Soft_I2C_Start();  Soft_I2C_Write(ADDRESS_SLAVE + 1);  flag_out=0;  do{*out=Soft_I2C_Read(1);     if(*out==0){Soft_I2C_Read(0);flag_out=1;}     out++;     }while(flag_out==0);   Soft_I2C_Stop();}// Escrever um texto no Soft I2Cvoid SI2C_Slave_Write_Text(char *texto){  Soft_I2C_Start();  Soft_I2C_Write(ADDRESS_SLAVE);  do  { Soft_I2C_Write(*texto);    texto++;    delay_us(100);  } while(*texto != 0);  Soft_I2C_Write(0);  Soft_I2C_Stop();}// Escrever um byte no Soft I2Cvoid SI2C_Slave_Write(){ Soft_I2C_Start();  Soft_I2C_Write(ADDRESS_SLAVE); //escreve endereco  Soft_I2C_Stop();}void interrupt()  {  // Habilita a comunicação USB   if(USBIF){Usb_Interrupt_Proc();}     // Configuracao do Timer 1  if (TMR1IF_bit)   {    TMR1IF_bit = 0;    TMR1H         = 0x0B; //1 segundo 8MHz    TMR1L         = 0xDC; //1 segundo 8MHz    flagTimer1=1;    Comando[xComando]=0; //Encerra a string.    xComando=0; //ocorrendo o estouro de timer, string comando estará fechada.     }  // Configuracao do UART  if(RCIF_bit)   {     RCIF_bit=0;     RCIE_bit=0; //desabilita interrupção no Rx       if(xComando>100){xComando=0;} //impede overflow do buffer       Comando[xComando]=UART1_Read(); // grava na posição xbuff o dado recebido       xcomando++; //passa uma posição adiante       flagComando=1;     RCIE_bit      = 1; //habilita interrupção no Rx     TMR1IE_bit    = 1; // habilita a interrupção no Timer 1     TMR1ON_bit    = 1; // habilita o Timer 1     TMR1H         = 0x0B; //reseta a contagem no timer 1     TMR1L         = 0xDC;   }} // fecha o interruptvoid main(){ Soft_I2C_Init();  //I2C1_Init(100000);  Uart1_Init(9600);  delay_ms(10);  TRISD = 0;  TRISB = 0xFF;  ADCON1 = 0xFF;   //Configuração dos timers. // InitTimer1()    T1CON         = 0x31;    TMR1IF_bit    = 0;    TMR1H         = 0x0B; //1 segundo 8MHz    TMR1L         = 0xDC; //1 segundo 8MHz    TMR1IE_bit    = 0; //será habilitado quando houver escrita no 232    TMR1ON_bit    = 0;    //TMR1H         = 0xB1;//10ms 8Mhz    //TMR1L         = 0xE0;//10ms 8Mhz    //Configuração do interrupção USART RX - RS-232.    RCIF_bit=0; //EUSART Receive Interrupt Flag bit    RCIE_bit=1; //EUSART Receive Interrupt Enable bit    RCIP_bit=1; //EUSART Receive Interrupt Priority bit (High)    TXIE_bit=0;  //EUSART Transmit Interrupt Enable bit //Habilitando interrupções    INTCON      = 0xC0;   // Zerando variaveis de controleComando[0]=0;xComando=0;flagComando=0;flagTimer1=0;flagOneTime=0;Comando[0]=97;// Envio para descarte//SI2C_Slave_Write_Text(Comando);   while(1)   {      SI2C_Slave_Read_Text(Mensagem);      if(flagComando)      {       endereco[0]=comando[0];       endereco[1]=comando[1];       endereco[2]=comando[2];       ADDRESS_SLAVE = atoi(endereco);       SI2C_Slave_Write_Text(Comando);       flagcomando=0;      }      Uart1_Write_Text("mensagem recebida");      Uart1_Write(13);      Uart1_Write_text(Mensagem);      Uart1_Write(13);      delay_ms(4000);   }}

Espero que ajude em alguma coisa.

 

Abs!

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...