TRASMISSIONE ONE WIRE TRA MICROCONTROLLORI

Schema e Codici per Realizzare una Comunicazione tra Microcontrollori con Protocollo One Wire…

 

 

 
 



 

INTRO

Nel seguente articolo viene presentato lo schema e i codici necessari per programmare un microcontrollore che funge da trasmettitore e uno che funge da ricevitore per avviare una comunicazione One Wire. Questo tipo di comunicazione è molto efficace nel caso si vuole un numero ridotto di conduttori, infatti ne bastano solo due, uno per il segnale e uno per la massa se si trasmette in tensione oppure uno per l’andata e una per il ritorno della corrente nel caso di trasmissione in corrente 4-20mA.

Lo schema come esempio di trasmissione utilizza 4 interruttori e trasmette il loro indirizzo, il ricevitore riceve un codice per ogni interruttore e accende o spegne due LED. La trasmissione One wire può arrivare fino a 20 metri utilizzando solo gli ingressi e uscite dei microcontrollori, mentre con un trasmettitore e ricevitore in corrente con standard 4-20mA può arrivare fino a 20Km.

 





 
CODICE

clicca qui per la guida alla scrittura dell’articolo!!!

Il codice del trasmettitore è il seguente:

#define B1      PORTB.F0              //Definizione dei pulsanti
#define B2      PORTB.F1
#define B3      PORTB.F2
#define B4      PORTB.F3
#define TX      PORTB.F7              //Definizione uscita di comunicazione


void send_preamble_and_sync(){        //Sottoprogramma Invia 16 bit sincr
  unsigned char tx = 0;
  for(tx = 0; tx < 15; tx++){          //Invia i primi 15 bit con periodo 600us
    delay_us(300);
    TX = 1;
    delay_us(300);
    TX = 0;
  }
  delay_us(170);                      //Ultimo bit di sincronizzazione
  TX = 1;                             //Con periodo 230us (170us 0, 80us 1)
  delay_us(80);
  TX = 0;
  delay_us(100);
}


void data_TX(unsigned char value){    //Sottoprogramma invio dati
  unsigned char s = 0;
  send_preamble_and_sync();           //Invia la sincronizzazione
  for(s = 0; s < 8; s++){             //Ripeti 8 volte (invia un byte)
    delay_us(20);
    TX = 1;                           //Tx a livello alto

    if((value & 0x80) != 0){          //Se il bit da inviare = 1 TX = 1 per 50us
      delay_us(50);
    }
    delay_us(100);                    //Se invece bit = 0 100us
    TX = 0;
    value <<= 1;                      //Scorri il vettore di byte
  }
}


void main(){                          //Programma principale
TRISB = 0b00001111;                   //Configura pulsanti come input e Tx come uscita

  while(1){                           //Ciclo infinito
    if(B1==1){                        //Se premo B1
      while(B1==1);                   //Aspetta che B1 venga rilasciato
      data_TX(10);                    //Invia il codice 00001010
    }
    if(B2==1){                        //Uguale a sopra con codice e tasto diversi
      while(B2==1);
      data_TX(20);
    }
      
    if(B3==1){                        //Se premo B1
      while(B1==1);                   //Aspetta che B1 venga rilasciato
      data_TX(30);                    //Invia il codice 00001010
    }
    if(B4==1){                        //Uguale a sopra con codice e tasto diversi
      while(B2==1);
      data_TX(40);
    }
  }
}

Prima di tutto si vanno a definire le connessioni dei pulsanti con il microcontrollore, e poi si va a scrivere il primo sottoprogramma, ovvero quello per inviare il preamble. Il reamble (preambolo) è un segnale che comunica l’inizio della comunicazione. Vengono inviati 15 periodi da 600uS ad onda quadra con duty cycle 50% e infine si invia un unico periodo con durata alta di 80uS e basso di 100uS.

Il secondo sottoprogramma è quello per inviare i dati; si invia il preamble richiamando il sottoprogramma visto prima, poi si invia il dato utilizzando un periodo di 50uS per un bit alto e 100uS per un bit basso, quindi si usa una modulazione di tempo, distinguendo i bit in base alla durata del periodo alto del segnale inviato mentre il segnale basso è sempre 20uS.

Nel programma principale si inizializzano ingressi e uscite e poi si vanno a controllare i pulsanti. Per ogni pulsante si invia un numero, primo pulsante 10, poi 20, poi 30 e alla fine per l’ultimo pulsante 40.

Il ricevitore riceve il numero associato al pulsante e in base a quale pulsante viene premuto accende o spegne un LED; primo pulsante accende LED1 e il secondo pulsante lo spegne, terzo pulsante accende LED2 e il quarto lo spegne. Il codice del ricevitore è:

#define  Load1          PORTB.F0            //Connessione carico
#define  Load2          PORTB.F1
#define  RX             PORTB.F7            //Connessione RX

unsigned char val;

  unsigned char data_RX(){                 //Sottoprogramma ricevitore
  unsigned char dato, period, bits;        //Inizializzazione variabili
  dato=0;
  
  if(RX){                                 //Se Rx=1
     while(period > 50){                  //Se il periodo è >50 rimani nel ciclo
       while(!RX){                        //Se RX=0 azzera la variabile
         Period = 0;
       }
       while(RX){                         //Altrimenti incrementala
         period++;                        //Incrementa la variabile
       }
     }
     bits = 8;
     dato = 0;

     while(bits){                         //Finchè bits non è 0
       while(!RX){                        //Conta il periodo
         Period = 0;
       }
       while(RX){
         period++;
       }
       if(period >= 50) break;            //Se il periodo è 50 esci dalla routine
       if(period < 25) dato |= 0;         //Se il periodo è minore di 25 allora ricevo 0
       else dato |= 1;                    //Altrimenti ho ricevuto un 1
       dato <<= 1;                        //shifto il vettore
       bits--;                            //Decremento la variabile bits
     }
                        
    dato = dato >> 1;
  }                                       //Ritorno il dato
  return (dato);
}


void main(){
  TRISB = 0b10000000;                     //Configura RX input e altri uscite

  while(1){                               //ciclo infinito
    val = data_RX();                      //Leggi valore ricevuto
    if(val == 10){                        //Se ricevo (10) accendi il carico 1
      Load1 = 1;                          //Accendi carico 1
      delay_ms(100);
    }
    if(val == 20){                        //Se ricevo (20) Spegni carico 1
      Load1 = 0;                          //Spegni carico 1
      delay_ms(100);
    }
    if(val == 30){                        //Se ricevo (10) accendi il carico 1
      Load2 = 1;                          //Accendi carico 1
      delay_ms(100);
    }
    if(val == 40){                        //Se ricevo (20) Spegni carico 1
      Load2 = 0;                          //Spegni carico 1
      delay_ms(100);
    }
  }
}

Prima vengono inizializzati i LED e l’ingresso dell’RX, poi una variabile che verrà usata successivamente. Il primo sottoprogramma è necessario per la ricezione dei dati. Nel programma per la ricezione si va a misurare il tempo del segnale alto ricevuto e se il conteggio che avviene durante il periodo alto è maggiore di 50 vuol dire che il preample è finito. Se il preamble è finito allora, finché la variabile bit non è 0, allora viene misurato per 8 volte il periodo alto del segnale e se il conteggio è minore di 25 vuol dire che è un 1 logico, se invece maggiore di 50 è uno 0 logico. I valori di 0 e 1 vengono inseriti in un vettore.

Nel programma principale si inizializzano ingressi e uscite e poi nel ciclo infinito si va a leggere il dato ricevuto e si controllano i LED in base ad esso.

La frequenza è per entrambi a 4MHz e i fuses sono così configurati:

 

SCHEMA

Lo schema del trasmettitore è il seguente:

La tensione di ingresso è a 5V continui, e il microcontrollore viene alimentato con la tensione positiva al pin 20 e quella negativa ai pin 19 e 8. Il circuito di oscillazione è composto da un quarzo a 4MHz e due condensatori da 22pF.

I 4 pulsanti sono connessi alle PORTB e vi sono 4 resistori di pull-down. R3 serve per mantenere in funzione il microcontrollore e il segnale di uscita viene trasmesso dal pin RB7. Bisogna inviare al ricevitore due fili, il prima con il segnale e il secondo con la massa del circuito.

Lo schema del ricevitore è:

Alimentazione e circuito risonante sono uguali come nel caso precedente.

I LED sono connessi all’uscita PB0 e PB1 mentre il segnale ricevuto giunge all’ingresso PB7.

Lo schema montato su breadboard ha il seguente aspetto:

 

DOWNLOAD

Potete scaricare la simulazione del circuito con PROTEUS e il codice scritto con MIKROC al seguente LINK!!!



 

[Voti Totali: 1 Media Voti: 5]
Segui la Nostra Pagina Facebook: Facebook

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *