Sadržaj:

Generator trofaznih sinusnih valova temeljen na Arduinu Due: 5 koraka
Generator trofaznih sinusnih valova temeljen na Arduinu Due: 5 koraka

Video: Generator trofaznih sinusnih valova temeljen na Arduinu Due: 5 koraka

Video: Generator trofaznih sinusnih valova temeljen na Arduinu Due: 5 koraka
Video: [Мусор] Отремонтируйте и оживите генератор Denyo. YAMAHA EF-1600 OEM 2024, Srpanj
Anonim
Generator trofaznih sinusnih valova temeljen na Arduino Due
Generator trofaznih sinusnih valova temeljen na Arduino Due

svrha ovog udjela je pomoći nekome tko pokušava iskoristiti Due-ove bolje performanse + nedostatak referenci + nepotrebne podatkovne tablice.

ovaj projekt može generirati do 3 fazna sinusna vala @ 256 uzoraka / ciklus pri niskim frekvencijama (<1kHz) i 16 uzoraka / ciklus pri visokim frekvencijama (do 20 kHz), što je dovoljno dobro da se izgladi jednostavnim LPF -ovima i izlaz je gotovo savršen.

priložena datoteka nije bila moja konačna verzija jer sam dodao neku dodatnu značajku, ali jezgra je ista. Imajte na umu da su uzorci/ciklus postavljeni niže od gornje izjave.

budući da je kapacitet procesora maksimiziran pristupom prikazanim u priloženoj datoteci, kao upravljačku jedinicu koristio sam Arduino Uno, koji koristi vanjski prekid Arduino Due za prosljeđivanje vrijednosti frekvencije na Arduino Due. Osim kontrole frekvencije, Arduino Uno također kontrolira amplitudu (putem digitalnog mjerača potencijala + OpAmp), kao i I/O --- bit će puno prostora za igru.

Korak 1: Generirajte niz podataka s sinusima

Budući da je izračun u stvarnom vremenu zahtjevan za CPU, za bolje performanse potreban je sinusni niz podataka

uint32_t sin768 PROGRAM =….dok x = [0: 5375]; y = 127+127*(sin (2*pi/5376/*ili neki # koji više volite ovisi o zahtjevu*/))

Korak 2: Omogućavanje paralelnog izlaza

Za razliku od Una, Due imaju ograničene reference. Međutim, kako bi se generirao trofazni sinusni val temeljen na Arduino Uno, prvo, performanse se ne mogu pohvaliti zbog niskog MCLK -a (16 MHz dok je Due 84 MHz), drugo, ograničen je GPIO koji može proizvesti maksimalno 2 fazni izlaz i trebate dodatni analogni krug za proizvodnju 3. faze (C = -AB).

Nakon omogućavanja GPIO -a, uglavnom se temeljilo na pokušaju i probi+nepotrebna podatkovna tablica SAM3X -a

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO kontroler Registar za omogućavanje PIO (pogledajte p656 podatkovne tablice ATMEL SAM3X) i https://arduino.cc/en/Hacking/PinMappingSAM3X, omogućeni pin 33-41 i 44-51 Arduino Due

PIOC-> PIO_OER = 0xFFFFFFFE; // Registar za omogućavanje izlaza PIO kontrolera, pogledajte p657 tablice podataka ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Registar statusa izlaza PIO kontrolera, pogledajte p658 podatkovne tablice ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registar za omogućavanje upisivanja PIO izlaza, pogledajte p670 podatkovne tablice ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opcionalno kao osiguranje, čini se da ne utječe na performanse, digitalni pin 10 povežite i na PC29 i na PA28, digitalni pin 4 na PC29 i PA28, ovdje za onemogućavanje onemogućavanja PIOA #28 & 29

Korak 3: Omogućavanje prekida

Kako bi se povećale njegove performanse, opterećenje procesora trebalo bi biti što je moguće manje. Međutim, zbog korespondencije koja nije 1to1 između pina CPU-a i pina Due, bitna operacija je neophodna.

Možete dodatno optimizirati algoritam, ali je prostor vrlo ograničen.

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

t = t%uzoraka; // koristiti t%uzoraka umjesto 'if' kako bi se izbjeglo prelijevanje t

phaseAInc = (unaprijed*t)%5376; // upotrijebite %5376 kako biste izbjegli prelijevanje indeksa polja

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // odnosi se na PIOC: PC1 do PC8, odgovarajući Arduino Due pin: pin 33-40, stoga pomaknite lijevo za 1 znamenku

p_B = sin768 [phaseBInc] << 12; // obratite se PIOC-u: PC12 do PC19, odgovarajući Arduino Due pin: pin 51-44, stoga pomaknite lijevo 12 znamenki

p_C = sin768 [phaseCInc]; // izlaz C faze zaposlenik PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 i PC29, odgovarajući Arduino Due pin: digitalni pin: 9, 8, 7, 6, 5, 4, 3, 10, respektivno

p_C2 = (p_C & B11000000) << 22; // ovo generira PC28 i PC29

p_C3 = (p_C & B00111111) << 21; // ovo generira PC21-PC26

p_C = p_C2 | p_C3; // ovo generira paralelni izlaz faze C

p_A = p_A | p_B | p_C; // 32 bitni izlaz = faza A (8bit) | faza B | faza C

PIOC-> PIO_ODSR = p_A; // izlazni registar = p_A

t ++; }

Korak 4: R/2R DAC

izradite 3x8bit R/2R DAC, hrpa preporuka na google -u.

Korak 5: Potpuni kôd

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

uint32_t p_A, p_B, p_C, p_C2, p_C3; // faza A vrijednost B faze C-iako su izlazi samo 8 bita, vrijednosti p_A i p_B će se koristiti za generiranje nove 32-bitne vrijednosti kako bi se kopiralo s 32-bitnim izlazom PIOC

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t interval; uint16_t uzorci, unaprijed; uint32_t t = 0;

void setup () {

// paralelni izlaz PIOC postavka: Arduino Due pin33-40 se koristi kao izlaz faze A, dok pin 44-51 radi za izlaz faze B

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO kontroler Registar za omogućavanje PIO (pogledajte p656 podatkovne tablice ATMEL SAM3X) i https://arduino.cc/en/Hacking/PinMappingSAM3X, omogućeni pin 33-41 i 44-51 Arduino Due

PIOC-> PIO_OER = 0xFFFFFFFE; // Registar za omogućavanje izlaza PIO kontrolera, pogledajte p657 podatkovne tablice ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Registar statusa izlaza PIO kontrolera, pogledajte p658 podatkovne tablice ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registar za omogućavanje upisivanja PIO izlaza, pogledajte p670 podatkovne tablice ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opcionalno kao osiguranje, čini se da ne utječe na performanse, digitalni pin 10 povežite i na PC29 i na PA28, digitalni pin 4 na PC29 i PA28, ovdje za onemogućavanje onemogućavanja PIOA #28 & 29 // postavljanje timera, pogledajte https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (lažno); // onemogućujemo zaštitu od upisa registara za upravljanje napajanjem

pmc_enable_periph_clk (ID_TC7); // omogućujemo brojač vremena perifernog sata 7

TC_Configure (/ * sat */TC2,/ * kanal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC sat 42MHz (sat, kanal, postavka načina uspoređivanja) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// omogućavanje vremenskih prekida na mjeraču vremena TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = registar za omogućavanje prekida TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = registar za onemogućavanje prekida

NVIC_EnableIRQ (TC7_IRQn); // Omogućuje prekid u ugniježđenom vektorskom kontroleru prekida freq = 60; // inicijalizirati frekvenciju kao 60Hz unaprijed = 21; // povećanje indeksa niza za 21 uzorak = 256; // izlazni uzorci 256/interval ciklusa = 42000000/(frekv.*uzorci); // brojevi prekida TC_SetRC (TC2, 1, interval); // pokretanje TC Serial.begin (9600); // u svrhu ispitivanja}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} else

{freq = freqNew;

if (freq> 20000) {freq = 20000; /*maksimalna frekvencija 20kHz*/};

if (freq <1) {freq = 1; /*min frekvencija 1Hz*/};

if (frekv.> 999) {unaprijed = 384; uzorci = 14;} // za frekvenciju> = 1 kHz, 14 uzoraka za svaki ciklus

else if (freq> 499) {preset = 84; uzorci = 64;} // za 500 <= frekvencija99) {unaprijed = 42; uzorci = 128;} // za 100Hz <= frekvencija <500Hz, 128 uzoraka/ciklus

else {unaprijed = 21; uzorci = 256;}; // za frekvenciju <100Hz, 256 uzoraka za svaki ciklus

interval = 42000000/(učestali*uzorci); t = 0; TC_SetRC (TC2, 1, interval); }}

void loop () {{100} {101}

checkFreq (); kašnjenje (100); }

void TC7_Handler (void)

{TC_GetStatus (TC2, 1);

t = t%uzoraka; // koristiti t%uzoraka za izbjegavanje prelijevanja t phaseAInc = (unaprijed*t)%5376; // upotrijebite %5376 kako biste izbjegli prelijevanje indeksa polja

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // odnosi se na PIOC: PC1 do PC8, odgovarajući Arduino Due pin: pin 33-40, stoga pomaknite lijevo za 1 znamenku

p_B = sin768 [phaseBInc] << 12; // obratite se PIOC-u: PC12 do PC19, odgovarajući Arduino Due pin: pin 51-44, stoga pomaknite lijevo 12 znamenki

p_C = sin768 [phaseCInc]; // izlaz C faze zaposlenik PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 i PC29, odgovarajući Arduino Due pin: digitalni pin: 9, 8, 7, 6, 5, 4, 3, 10, respektivno

p_C2 = (p_C & B11000000) << 22; // ovo generira PC28 i PC29

p_C3 = (p_C & B00111111) << 21; // ovo generira PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // ovo generira paralelni izlaz faze C

p_A = p_A | p_B | p_C; // 32 bitni izlaz = faza A (8bit) | faza B | faza C //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // izlazni registar = p_A t ++; }

Preporučeni: