SINTETIZZATORE DI FORME D’ONDA CON PIC18F

Schema per Realizzare un Sintetizzatore di Segnale Sinusoidale, Triangolare e a Dente di Sega grazie ad un Microcontrollore e un Convertitore DAC…

 

 

 

 




 

INTRO

Il seguente schema sfrutta un microcontrollore per generare un segnale da fornire ad un convertitore digitale analogico in modo tale da sintetizzare segnali di tipo sinusoidale, triangolare e a dente di sega. Tramite un selettore a tre posizioni è possibile selezionare quale forma d’onda generare e il microcontrollore tramite questa informazione va a selezionare l’appropriata funzione matematica. Per ogni tipo di segnale vi è una funzione matematica e in particolare per generare il segnale sinusoidale si utilizza la libreria della funzione seno presente in MikroC.

Il segnale generato dal microcontrollore viene trasformato in segnale analogico grazie ad un convertitore digitale che permette di avere un filtro LC di minore dimensione o assente rispetto al caso della sintetizzazione con segnale PWM. Lo schema è quindi indicato per basse frequenze, da 1KHz fino a valori di 0.01Hz. Il litro LC in uscita va inserito solo se si vuole un segnale più lineare e non con i classici gradini presenti nel segnale di uscita di un DAC.

Il seguente schema non presenta nessuna regolazione della frequenza, semplicemente genera le forme con la frequenza indicata dal codice, il tutto grazie ad un semplice calcolo. Con una semplice modifica si potrebbe includere un controllo.

 




 

CODICE

Il codice  il seguente:

int sinusoide;                        //variabile segnale sinusoidale
int i;                                //Variabile triangolo e sega
bit rising;                           //Fronte di salita o discesa triangolo

void main() {
  TRISB = 0x00;                       //PORTB uscite
  TRISC = 0xff;                       //PORTC ingressi
  
  while(1){                           //ciclo infinito
  
    i=0;                              //Azzera i
    while(PORTC.F0 == 1){             //se PC0 = 1 genera segnale triangolare 725Hz   //0.4us
      if(i == 254) rising = 0;        //Se i=254 cambia fronte                        //1.4us
      if(i == 0) rising = 1;          //Se i=0 cambia fronte                          //1.4us
      PORTB = i;                      //invia al DAC il valore di i                   //0.4us
      if(rising == 0) i = i - 2;      //Decrementa i se fronte di discesa             //0.6us
      if (rising == 1) i = i + 2;     //Incrementa i se fronte di salita              //1.2us
    }

    i=0;                              //Azzera i   (dente di sega invertito)
    while(PORTC.F1 == 1){             //Se PC1 = 1 genera dente di sega               //0.4us
      if(i==0)i=255;                  //Se i = 0 azzera i per portare Vout a 0        //1.2us
      PORTB = i;                      //Manda in uscita il valore di i                //0.4us
      i--;                            //incrementa di 1 il vlore di i                 //0.4us
      Delay_us(2);                    //Ritardo per avere lo stesso periodo dell'onda triangolare
    }

    i=0;                              //Azzera i
    while(PORTC.F2 == 1){             //Se PC2 = 1 genera sinusoide                   //0.4us
      if(i > 361) i=0;                //Se i maggiore di 361 azzera i                 //1.2us
      sinusoide = sinE3(i)+1005;      //genera sinuoide traslata a valori positivi    //92.8us
      sinusoide = sinusoide >> 3;     //dividi /8 il valore adattandolo a 0-255       //8us
      i = i + 3;                      //incrementa i di 3                             //0.4us
      PORTB = sinusoide;              //invia al DAC il valore della sinusoide        //0.4us
      Delay_us(63);                   //ritardo per generare un segnale di 50Hz
    }
  }
}

Prima di tutto si inizializzano tre variabili, la prima per il segnale sinusoidale, la seconda per la forma d’onda triangolare e a dente di sega e infine una variabile ad un bit che indica se si ha il fronte di salita o discesa del segnale triangolare. Nel programma principale le PORTB sono inizializza come uscite per il DAC e le PORTC come ingressi per il selettore.

Nel ciclo infinito si va a verificare la posizione del selettore controllando PORTC.F0, PORTC.F1 e PORTC.F2. Se si ha PORTC.F0 a livello alto si va ad incrementare i se si ha il fronte di discesa e si va a decrementare se si ha il fronte di salita e in particolare si incrementa e decrementa di due in modo tale da velocizzare l’onda. Si ha il fronte di salita quando i raggiunge lo 0 e il fronte di discesa quando i raggiunge il valore massimo. Infine i viene inviato alle PORTB.

Per il segnale a dente di sega i viene decrementato fino a zero e poi ri-inizializzato a 255 aggiornando i ogni volta PORTB. Il segnale a dente di sega è invertito visto che l’amplificatore operazionale a valle del DAC è in configurazione invertente.

Per il segnale sinusoidale si usa la funzione “sinE3()” che genera un segnale sinusoidale tra 1000 e -1000, e si usa la variabile i come argomento del seno, infatti esso va da 0 a 360 essendo gli angoli in gradi in questa funzione. Il segnale sinusoidale viene shiftato per valori positivi e poi viene diviso per 8 ottenendo valori da 0 a 255, range che rispetta i char da inviare a PORTB.  “i” viene incrementato ogni ciclo di 3 per rendere più veloce il ciclo e visto che piccole variazioni di i non creano variazioni di PORTB. Il delay da 63uS fa si che la sinusoide abbia una frequenza di 50Hz.

 

SCHEMA

Lo schema è il seguente:

La tensione di alimentazione è 5V a basso ripple per il microcontrollore e per il DAC mentre serve una tensione duale di 5V/-5V per l’amplificatore operazionale. Si può usare una tensione di 5V e un inverter per generare i -5V oppure usare un alimentatore duale a 5V (realizzato con due regolatori 7805 e 7905 oppure con un alimentatore ATX) e utilizzare il canale positivo per microcontrollore e il DAC e invece solo il canale negativo per l’amplificatore operazionale.

La frequenza di oscillazione del microcontrollore è 20MHz generata con un cristallo di quarzo e due condensatori da 22pF. R1 fa si che si ha un livello logico alto sul pin di reset. Il deviatore a re posizioni è connesso a VCC dal contatto comune e i tre contatti invece sono connessi ai primi 3 pin di PORTC con le resistenze R4, R2 e R3 usate per tenere i pin a livello logico basso quando il selezionatore non porta un livello logico alto.

Il DAC è direttamente connesso al microcontrollore e i pin di controllo sono connessi in modo che esso converta ogni volta che varia il dato in ingresso, senza segnale di controllo. La tensione di riferimento del DAC è 5V e il segnale di uscita viene amplificato grazie all’amplificatore operazionale U3 e alla resistenza di feedback interna del DAC.

Il segnale in uscita ha la seguente forma ed oscilla interno allo 0 assumendo valori positivi e negativi:

Lo schema usato come test è stato montato su breadboard e ha il seguente aspetto:

 

DOWNLOAD

Potete scaricare la simulazione del circuito con MULTISIM14 al seguente LINK!!!




 

[Voti Totali: 0 Media Voti: 0]
Segui la Nostra Pagina Facebook: Facebook

Lascia un commento

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