Sommario:
- Passaggio 1: genera un array di dati sinusoidali
- Passaggio 2: abilitazione dell'uscita parallela
- Passaggio 3: abilitazione dell'interruzione
- Passaggio 4: DAC R/2R
- Passaggio 5: codice completo
Video: Generatore di onda sinusoidale trifase basato su Arduino Due: 5 passaggi
2024 Autore: John Day | [email protected]. Ultima modifica: 2024-01-30 10:02
lo scopo di questa condivisione è aiutare qualcuno che sta cercando di utilizzare le maggiori prestazioni di Due + mancanza di riferimento + scheda tecnica non utile.
questo progetto è in grado di generare fino a 3 fasi sinusoidali @ 256 campioni/ciclo a bassa frequenza (<1kHz) e 16 campioni/ciclo ad alta frequenza (fino a 20kHz), che è abbastanza buono da essere livellato da semplici LPF e dal l'uscita è quasi perfetta.
il file allegato non era la mia versione finale perché ho aggiunto alcune funzionalità aggiuntive ma il nucleo è lo stesso. Notare che i campioni/ciclo è stato impostato su un valore inferiore rispetto a quanto indicato sopra.
poiché la capacità della CPU è massimizzata attraverso l'approccio mostrato nel file allegato, ho usato un Arduino Uno come unità di controllo, che utilizza l'interrupt esterno di Arduino Due per passare il valore di frequenza ad Arduino Due. Oltre al controllo della frequenza, Arduino Uno controlla anche l'ampiezza (tramite il misuratore di potenziale digitale + OpAmp) e l'I/O --- ci sarà molto spazio con cui giocare.
Passaggio 1: genera un array di dati sinusoidali
Poiché il calcolo in tempo reale richiede CPU, è necessario un array di dati sinusoidali per prestazioni migliori
uint32_t sin768 PROGMEM= ….while x=[0:5375]; y = 127+127*(sin(2*pi/5376/*o qualche # che preferisci dipende dal requisito*/))
Passaggio 2: abilitazione dell'uscita parallela
A differenza di Uno, Due hanno riferimenti limitati. Tuttavia, per generare un'onda sinusoidale trifase basata su Arduino Uno, prima di tutto, le prestazioni non sono applaudibili a causa del suo basso MCLK (16 MHz mentre Due è 84 MHz), in secondo luogo, il GPIO limitato può produrre un massimo di 2 fasi e hai bisogno di ulteriori circuito analogico per produrre la 3° fase (C=-AB).
Dopo l'abilitazione GPIO si basava principalmente su prova e prova + scheda tecnica non utile di SAM3X
PIOC->PIO_PER = 0xFFFFFFFE; //PIO controller PIO Enable register (fare riferimento a p656 del datasheet di ATMEL SAM3X) e https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 e 44-51 sono stati abilitati
PIOC->PIO_OER = 0xFFFFFFFE; //Registro di abilitazione uscita controller PIO, vedere p657 del foglio dati ATMEL SAM3X PIOC->PIO_OSR = 0xFFFFFFFE; //Registro di stato dell'uscita del controller PIO, fare riferimento a p658 del foglio dati ATMEL SAM3X
PIOC->PIO_OWER = 0xFFFFFFFE; //Registro di abilitazione scrittura uscita PIO, fare riferimento a p670 del foglio dati ATMEL SAM3X
//PIOA->PIO_PDR = 0x30000000; //opzionale come assicurazione, non sembra influire sulle prestazioni, il pin digitale 10 si collega a PC29 e PA28, il pin digitale 4 si collega sia a PC29 che a PA28, qui per disabilitare disabilitare PIOA #28 e 29
Passaggio 3: abilitazione dell'interruzione
Per massimizzare le sue prestazioni, il carico della CPU dovrebbe essere il più basso possibile. Tuttavia, a causa della corrispondenza non-1to1 tra il pin della CPU e il pin Due, è necessaria l'operazione a bit.
Puoi ottimizzare ulteriormente l'algoritmo ma la stanza è molto limitata.
void TC7_Handler(void){ TC_GetStatus(TC2, 1);
t = t%campioni; // usa t%samples invece di 'if' per evitare l'overflow di t
phaseAInc = (preset*t)%5376; // usa %5376 per evitare l'overflow dell'indice dell'array
faseBInc = (faseAInc+1792)%5376;
faseCInc = (faseAInc+3584)%5376;
p_A = sin768[phaseAInc]<<1; //fare riferimento a PIOC: da PC1 a PC8, corrispondente pin Arduino Due: pin 33-40, quindi spostare a sinistra per 1 cifra
p_B = sin768[phaseBInc]<<12; //fare riferimento a PIOC: da PC12 a PC19, corrispondente pin Arduino Due: pin 51-44, quindi spostare a sinistra di 12 cifre
p_C = sin768[phaseCInc]; //uscita fase C impiega PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 e PC29, pin Arduino Due corrispondente: pin digitale: 9, 8, 7, 6, 5, 4, 3, 10, rispettivamente
p_C2 = (p_C&B11000000)<<22; //questo genera PC28 e PC29
p_C3 = (p_C&B00111111)<<21; //questo genera PC21-PC26
p_C = p_C2|p_C3; //questo genera un'uscita parallela della fase C
p_A = p_A|p_B|p_C; //Uscita 32 bit = fase A (8bit)|fase B|fase C
PIOC->PIO_ODSR = p_A; //registro di uscita =p_A
t++; }
Passaggio 4: DAC R/2R
costruire 3x8bit R/2R DAC, un sacco di ref su google.
Passaggio 5: codice completo
#define _BV(x) (1<<(x)); uint32_t sin768 PROGMEM= /* x=[0:5375]; y = 127+127*(peccato(2*pi/5376)) */
uint32_t p_A, p_B, p_C, p_C2, p_C3; // valore fase A fase B fase C - sebbene l'uscita sia solo a 8 bit, il valore p_A e p_B verrà utilizzato per generare un nuovo valore a 32 bit per far fronte all'uscita PIOC a 32 bit
uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t intervallo; uint16_t campioni, preset; uint32_t t = 0;
void setup() {
//configurazione PIOC dell'uscita parallela: i pin33-40 di Arduino Due sono utilizzati come uscita di fase A mentre i pin 44-51 funzionano per l'uscita di fase B
PIOC->PIO_PER = 0xFFFFFFFE; //PIO controller PIO Enable register (fare riferimento a p656 del datasheet di ATMEL SAM3X) e https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 e 44-51 sono stati abilitati
PIOC->PIO_OER = 0xFFFFFFFE; //Registro di abilitazione uscita controller PIO, fare riferimento a p657 del foglio dati ATMEL SAM3X
PIOC->PIO_OSR = 0xFFFFFFFE; //Registro di stato dell'uscita del controller PIO, fare riferimento a p658 del foglio dati ATMEL SAM3X
PIOC->PIO_OWER = 0xFFFFFFFE; //Registro di abilitazione scrittura uscita PIO, fare riferimento a p670 del foglio dati ATMEL SAM3X
//PIOA->PIO_PDR = 0x30000000; //opzionale come assicurazione, non sembra influire sulle prestazioni, il pin digitale 10 si collega sia a PC29 che a PA28, il pin digitale 4 si collega a PC29 e PA28, qui per disabilitare disabilitare PIOA #28 e 29 // setup timer, fare riferimento a https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect(false); // disabilita la protezione da scrittura dei registri di Power Management Control
pmc_enable_periph_clk(ID_TC7); // abilita il contatore del tempo dell'orologio periferico 7
TC_Configure(/* orologio */TC2, /* canale */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); //TC clock 42MHz (clock, canale, impostazione modalità confronto) TC_SetRC(TC2, 1, interval); TC_Start(TC2, 1);
// abilita gli interrupt del timer sul timer TC2->TC_CHANNEL[1]. TC_IER=TC_IER_CPCS; // IER = registro abilitazione interrupt TC2->TC_CHANNEL[1]. TC_IDR=~TC_IER_CPCS; // IDR = registro di disabilitazione degli interrupt
NVIC_EnableIRQ(TC7_IRQn); // Abilita l'interrupt nel controller di interrupt del vettore annidato freq = 60; //inizializza la frequenza come preset 60Hz = 21; //incremento dell'indice dell'array di 21 campioni = 256; //campioni di output 256/intervallo di ciclo = 42000000/(freq*samples); //interrupt conta TC_SetRC(TC2, 1, intervallo); //avvia TC Serial.begin(9600); //a scopo di test }
void checkFreq()
{freqNuova = 20000;
if (freq == freqNew) {} else
{ freq = freqNew;
if (freq>20000) {freq = 20000; /*frequenza massima 20kHz*/};
if (freq<1) {freq=1; /*frequenza minima 1Hz*/};
if (freq>999) {preimpostato = 384; campioni = 14;} //per frequenza >=1kHz, 14 campioni per ogni ciclo
else if (freq>499) {preset = 84; campioni = 64;} //per 500<=frequenza99) {preimpostato = 42; campioni = 128;} //per 100Hz<=frequenza<500Hz, 128 campioni/ciclo
else {preimpostato = 21; campioni = 256;}; //per frequenza<100hz, 256 campioni per ogni ciclo
intervallo = 42000000/(freq*campioni); t = 0; TC_SetRC(TC2, 1, intervallo); } }
ciclo vuoto() {
checkFreq(); ritardo(100); }
void TC7_Handler(void)
{ TC_GetStatus(TC2, 1);
t = t%campioni; //usa t%samples per evitare l'overflow di t phaseAInc = (preset*t)%5376; // usa %5376 per evitare l'overflow dell'indice dell'array
faseBInc = (faseAInc+1792)%5376;
faseCInc = (faseAInc+3584)%5376;
p_A = sin768[phaseAInc]<<1; //fare riferimento a PIOC: da PC1 a PC8, corrispondente pin Arduino Due: pin 33-40, quindi spostare a sinistra per 1 cifra
p_B = sin768[phaseBInc]<<12; //fare riferimento a PIOC: da PC12 a PC19, corrispondente pin Arduino Due: pin 51-44, quindi spostare a sinistra di 12 cifre
p_C = sin768[phaseCInc]; //uscita fase C impiega PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 e PC29, pin Arduino Due corrispondente: pin digitale: 9, 8, 7, 6, 5, 4, 3, 10, rispettivamente
p_C2 = (p_C&B11000000)<<22; //questo genera PC28 e PC29
p_C3 = (p_C&B00111111)<<21; //questo genera PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2|p_C3; //questo genera un'uscita parallela della fase C
p_A = p_A|p_B|p_C; //Uscita 32 bit = fase A (8bit)|fase B|fase C //Serial.println(p_A>>21, BIN); //PIOC->PIO_ODSR = 0x37E00000;
PIOC->PIO_ODSR = p_A; //registro di uscita =p_A t++; }
Consigliato:
Inverter a onda sinusoidale pura: 8 passaggi
Inverter a onda sinusoidale pura: la mia ricerca
Produzione della scheda di controllo dell'onda sinusoidale: 5 passaggi
Produzione della scheda di controllo dell'onda sinusoidale: questa volta si tratta di una scheda di controllo off-grid a onda sinusoidale monofase, seguita da una scheda di controllo off-grid a onda sinusoidale monofase, quindi una scheda di controllo off-grid a onda sinusoidale trifase, e infine una scheda di controllo off-grid a onda sinusoidale trifase. Speriamo che
Generatore di forme d'onda Arduino: 5 passaggi (con immagini)
Arduino Waveform Generator: aggiornamento febbraio 2021: dai un'occhiata alla nuova versione con 300 volte la frequenza di campionamento, basata sul Raspberry Pi Pico. In laboratorio, spesso è necessario un segnale ripetitivo di una certa frequenza, forma e ampiezza. Potrebbe essere quello di testare un amplificatore, controllare un circuito
Generatore musicale basato sulle condizioni meteorologiche (generatore MIDI basato su ESP8266): 4 passaggi (con immagini)
Generatore di musica basato sul tempo (Generatore MIDI basato su ESP8266): Ciao, oggi spiegherò come creare il tuo piccolo generatore di musica basato sul tempo. È basato su un ESP8266, che è un po' come un Arduino, e risponde alla temperatura, alla pioggia e l'intensità della luce. Non aspettarti che produca intere canzoni o programmi di accordi
Fai da te un circuito NE555 per generare un'onda sinusoidale: 6 passaggi
Fai da te un circuito NE555 per generare un'onda sinusoidale: questo tutorial ti insegna come creare un circuito NE555 fai-da-te per generare un'onda sinusoidale. Questo conveniente kit fai-da-te è molto utile per capire come possono funzionare i condensatori con i resistori per controllare il tempo di carica e scarica che per generare