Cuprins:

Generator de unde sinusoidale cu 3 faze bazat pe Arduino Due: 5 pași
Generator de unde sinusoidale cu 3 faze bazat pe Arduino Due: 5 pași

Video: Generator de unde sinusoidale cu 3 faze bazat pe Arduino Due: 5 pași

Video: Generator de unde sinusoidale cu 3 faze bazat pe Arduino Due: 5 pași
Video: Does it suck? Chinese DIY Pure Sine Wave Inverter || Sinusoidal PWM (SPWM) Tutorial 2024, Iulie
Anonim
Generator de unde sinusoidale cu 3 faze bazat pe Arduino Due
Generator de unde sinusoidale cu 3 faze bazat pe Arduino Due

Scopul acestei cote este de a ajuta pe cineva care încearcă să utilizeze performanța mai mare a lui Due + lipsa de referință + foaie tehnică neutilizabilă.

acest proiect este capabil să genereze până la 3 faze unde sinusoidale @ 256 de probe / ciclu la frecvență redusă (<1kHz) și 16 probe / ciclu @ frecvență ridicată (până la 20kHz), care este suficient de bun pentru a fi netezit de LPF-uri simple și ieșirea este aproape perfectă.

fișierul atașat nu a fost versiunea mea finală, deoarece am adăugat o caracteristică suplimentară, dar nucleul este același cu acela. Rețineți că probele / ciclul au fost setate mai jos decât declarația de mai sus.

deoarece capacitatea procesorului este maximizată prin abordarea prezentată în fișierul atașat, am folosit un Arduino Uno ca unitate de control, care utilizează întreruperea externă a Arduino Due pentru a transmite valoarea frecvenței către Arduino Due. În plus față de controlul frecvenței, Arduino Uno controlează și amplitudinea (prin metru digital de potențial + OpAmp), precum și I / O --- va fi mult spațiu cu care să te joci.

Pasul 1: Generați matricea de date sinusoidale

Deoarece calculul în timp real solicită CPU, este necesară o matrice de date sinusoidale pentru o performanță mai bună

uint32_t sin768 PROGMEM = …. while x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * sau unele # preferați depinde de cerință * /))

Pasul 2: Activarea ieșirii paralele

Spre deosebire de Uno, Due au o referință limitată. Cu toate acestea, pentru a genera o undă sinusoidală 3 faze bazată pe Arduino Uno, în primul rând, performanța nu este aplaudabilă datorită MCLK-ului său scăzut (16MHz în timp ce Due este 84MHz), în al doilea rând, GPIO este limitat, poate produce o ieșire de maxim 2 faze și aveți nevoie de circuit analogic pentru a produce a treia fază (C = -AB).

Urmărirea activării GPIO s-a bazat în cea mai mare parte pe încercare și încercare + nu foaia de date utilă a SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO controller PIO Enable register (consultați p656 din foaia tehnică ATMEL SAM3X) și https://arduino.cc/en/Hacking/PinMappingSAM3X, pinul Arduino Due 33-41 și 44-51 au fost activate

PIOC-> PIO_OER = 0xFFFFFFFE; // Registrul de activare a ieșirii controlerului PIO, consultați p657 din fișa tehnică ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Registrul de stare a ieșirii controlerului PIO, consultați p658 din foaia tehnică ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registrul activare scriere ieșire PIO, consultați p670 din foaia tehnică ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opțional ca asigurare, nu pare să afecteze performanța, pinul digital 10 se conectează atât la PC29 cât și la PA28, pinul digital 4 se conectează atât la PC29 cât și la PA28, aici pentru a dezactiva dezactivarea PIOA # 28 și 29

Pasul 3: Activarea întreruperii

Pentru a-și maximiza performanțele, sarcina procesorului trebuie să fie cât mai redusă. Cu toate acestea, datorită corespondenței non-1to1 între pinul CPU și pinul Due, este necesară funcționarea bitului.

Puteți optimiza în continuare algoritmul, dar camera este foarte limitată.

void TC7_Handler (void) {TC_GetStatus (TC2, 1);

t = t% eșantioane; // utilizați t% eșantioane în loc de „dacă” pentru a evita depășirea t

phaseAInc = (preset * t)% 5376; // utilizați% 5376 pentru a evita depășirea indexului matricei

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // consultați PIOC: PC1 la PC8, pinul Arduino Due corespunzător: pinul 33-40, deci deplasați la stânga pentru 1 cifră

p_B = sin768 [phaseBInc] << 12; // consultați PIOC: PC12 la PC19, pinul Arduino Due corespunzător: pinul 51-44, deci deplasați la 12 cifre la stânga

p_C = sin768 [phaseCInc]; // ieșirea fazei C utilizează PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 și PC29, pinul Arduino Due corespunzător: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, respectiv

p_C2 = (p_C & B11000000) << 22; // aceasta generează PC28 și PC29

p_C3 = (p_C & B00111111) << 21; // aceasta generează PC21-PC26

p_C = p_C2 | p_C3; // aceasta generează ieșire paralelă a fazei C

p_A = p_A | p_B | p_C; // ieșire pe 32 biți = faza A (8 biți) | faza B | faza C

PIOC-> PIO_ODSR = p_A; // registru de ieșire = p_A

t ++; }

Pasul 4: R / 2R DAC

construiți 3x8bit R / 2R DAC, o mulțime de ref pe google.

Pasul 5: Cod complet

#define _BV (x) (1 << (x)); uint32_t sin768 PROGMEM = / * x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376)) * /

uint32_t p_A, p_B, p_C, p_C2, p_C3; // faza A faza B valoarea fazei C - deși ieșirea este doar 8 biți, valoarea p_A și p_B vor fi operate pentru a genera o nouă valoare pe 32 biți pentru a face față ieșirii PIOC pe 32 biți

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; interval uint32_t; uint16_t mostre, presetate; uint32_t t = 0;

configurare nulă () {

// configurare PIOC de ieșire paralelă: pinul Arduino Due33-40 este utilizat ca ieșire de fază A în timp ce pinul 44-51 funcționează pentru ieșirea de fază B

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO controller PIO Enable register (consultați p656 din foaia tehnică ATMEL SAM3X) și https://arduino.cc/en/Hacking/PinMappingSAM3X, pinul Arduino Due 33-41 și 44-51 au fost activate

PIOC-> PIO_OER = 0xFFFFFFFE; // Registrul de activare a ieșirii controlerului PIO, consultați p657 din foaia tehnică ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Registrul de stare a ieșirii controlerului PIO, consultați p658 din foaia tehnică ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registrul de activare scriere ieșire PIO, consultați p670 din foaia tehnică ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opțional ca asigurare, nu pare să afecteze performanța, pinul digital 10 se conectează atât la PC29 cât și la PA28, pinul digital 4 se conectează atât la PC29 cât și la PA28, aici pentru a dezactiva dezactivarea PIOA # 28 și 29 // configurarea temporizatorului, consultați https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (fals); // dezactivați protecția la scriere a registrelor de control al gestionării energiei

pmc_enable_periph_clk (ID_TC7); // activați contorul de timp al ceasului periferic 7

TC_Configure (/ * clock * / TC2, / * channel * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC clock 42MHz (ceas, canal, setare mod comparare) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// activați întreruperile temporizatorului pe temporizatorul TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = registru activare întrerupere TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = registru dezactivare întrerupere

NVIC_EnableIRQ (TC7_IRQn); // Activați întreruperea în controlerul de întrerupere vector imbricat freq = 60; // inițializați frecvența ca presetare 60Hz = 21; // creșterea indicelui matricei cu 21 de eșantioane = 256; // ieșire probe 256 / interval ciclu = 42000000 / (frecvențe * probe); // număr de întreruperi TC_SetRC (TC2, 1, interval); // porniți TC Serial.begin (9600); // în scopul testării}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} else

{freq = freqNou;

if (frecvență> 20000) {frecvență = 20000; / * frecvență maximă 20kHz * /};

if (freq <1) {freq = 1; / * frecvență min 1Hz * /};

if (frecv> 999) {preset = 384; mostre = 14;} // pentru frecvență> = 1kHz, 14 eșantioane pentru fiecare ciclu

else if (frecv> 499) {preset = 84; mostre = 64;} // pentru 500 <= frecvență99) {preset = 42; probe = 128;} // pentru 100Hz <= frecvență <500Hz, 128 probe / ciclu

else {preset = 21; mostre = 256;}; // pentru frecvență <100hz, 256 de probe pentru fiecare ciclu

interval = 42000000 / (probe frecv *); t = 0; TC_SetRC (TC2, 1, interval); }}

bucla nulă () {

checkFreq (); întârziere (100); }

nul TC7_Handler (nul)

{TC_GetStatus (TC2, 1);

t = t% eșantioane; // utilizați t% eșantioane pentru a evita depășirea fazei tAInc = (preset * t)% 5376; // utilizați% 5376 pentru a evita depășirea indexului matricei

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // consultați PIOC: PC1 la PC8, pinul Arduino Due corespunzător: pinul 33-40, deci deplasați la stânga pentru 1 cifră

p_B = sin768 [phaseBInc] << 12; // consultați PIOC: PC12 la PC19, pinul Arduino Due corespunzător: pinul 51-44, deci deplasați la 12 cifre la stânga

p_C = sin768 [phaseCInc]; // ieșirea fazei C utilizează PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 și PC29, pinul Arduino Due corespunzător: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, respectiv

p_C2 = (p_C & B11000000) << 22; // generează PC28 și PC29

p_C3 = (p_C & B00111111) << 21; // generează PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // aceasta generează ieșire paralelă a fazei C

p_A = p_A | p_B | p_C; // ieșire pe 32 biți = faza A (8 biți) | faza B | faza C //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // registru de ieșire = p_A t ++; }

Recomandat: