Kazalo:

3 -fazni generator sinusnih valov, ki temelji na Arduino Due: 5 korakov
3 -fazni generator sinusnih valov, ki temelji na Arduino Due: 5 korakov

Video: 3 -fazni generator sinusnih valov, ki temelji na Arduino Due: 5 korakov

Video: 3 -fazni generator sinusnih valov, ki temelji na Arduino Due: 5 korakov
Video: Introduction to Harmonia - Oscillator Basics | Cherry Audio 2024, November
Anonim
3 -fazni generator sinusnih valov, ki temelji na Arduino Due
3 -fazni generator sinusnih valov, ki temelji na Arduino Due

namen te skupne rabe je pomagati nekomu, ki poskuša izkoristiti Dueovo večjo zmogljivost + pomanjkanje referenc + neuporaben podatkovni list.

ta projekt lahko ustvari do 3 fazne sinusne valove @ 256 vzorcev / cikel pri nizkih frekvencah (<1 kHz) in 16 vzorcev / cikel pri visokih frekvencah (do 20 kHz), kar je dovolj dobro, da jih lahko zgladijo preprosti LPF -ji in izhod je skoraj popoln.

priložena datoteka ni bila moja zadnja različica, saj sem dodal še eno dodatno funkcijo, vendar je jedro temu enako. Upoštevajte, da so bili vzorci/cikel nastavljeni nižje od zgornje izjave.

ker je zmogljivost procesorja maksimizirana s pristopom, prikazanim v priloženi datoteki, sem kot krmilno enoto uporabil Arduino Uno, ki uporablja zunanjo prekinitev Arduino Due za prenos frekvence na Arduino Due. Poleg nadzora frekvence Arduino Uno nadzoruje tudi amplitudo (preko digitalnega merilnika potenciala + OpAmp) in V/I --- veliko prostora bo za igranje.

1. korak: Ustvarite niz podatkovnih sinusov

Ker je izračun v realnem času zahteven za procesor, je za boljše delovanje potreben niz podatkovnih sinusov

uint32_t sin768 PROGMEM =…. medtem ko je x = [0: 5375]; y = 127+127*(sin (2*pi/5376/*ali nekaj #, ki vam je ljubše, je odvisno od zahteve*/))

2. korak: Omogočanje vzporednega izhoda

Za razliko od Uno, imajo Due omejene reference. Vendar pa za ustvarjanje 3 -faznega sinusnega vala, ki temelji na Arduino Uno, prvič, zmogljivosti niso hvalevredne zaradi nizkega MCLK (16 MHz, medtem ko je Due 84MHz), drugič, omejen GPIO lahko proizvede največ 2 fazna izhoda in potrebujete dodatne analogno vezje za proizvodnjo 3. faze (C = -AB).

Omogočanje GPIO je večinoma temeljilo na podatkovnem listu SAM3X, ki je bil preizkušen+neuporaben

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO krmilnik PIO Enable register (glejte p656 podatkovnega lista ATMEL SAM3X) in https://arduino.cc/en/Hacking/PinMappingSAM3X, pin 33-41 in 44-51 Arduino Due sta bila omogočena

PIOC-> PIO_OER = 0xFFFFFFFE; // register za omogočanje izhoda krmilnika PIO, glejte p657 podatkovnega lista ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Register stanja izhoda krmilnika PIO, glejte p658 podatkovnega lista ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Register za omogočanje zapisovanja izhodov PIO, glejte p670 podatkovnega lista ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // izbirno kot zavarovanje, ne vpliva na zmogljivost, digitalni pin 10 se poveže tako z PC29 kot s PA28, digitalni pin 4 se poveže z PC29 in PA28, tukaj onemogočite onemogočanje PIOA #28 & 29

3. korak: Omogočanje prekinitve

Da bi povečali svojo zmogljivost, mora biti obremenitev procesorja čim nižja. Vendar pa je zaradi ujemanja, ki ni med 1to1 med pin CPU in Due pin, potrebna bitna operacija.

Algoritem lahko še dodatno optimizirate, vendar je prostor zelo omejen.

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

t = t%vzorcev; // uporabite t%vzorcev namesto 'if', da se izognete prelivu t

phaseAInc = (prednastavljeno*t)%5376; // uporabite %5376, da se izognete prelivanju indeksa matrike

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // glej PIOC: PC1 do PC8, ustrezen zatič Arduino Due: pin 33-40, zato pomaknite levo za eno številko

p_B = sin768 [phaseBInc] << 12; // glej PIOC: PC12 do PC19, ustrezen zatič Arduino Due: pin 51-44, zato pomaknite 12-mestno levo

p_C = sin768 [phaseCInc]; // izhod faze C zaposleni PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 in PC29, ustrezen zatič Arduino Due: digitalni zatič: 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // s tem nastaneta PC28 in PC29

p_C3 = (p_C & B00111111) << 21; // s tem nastane PC21-PC26

p_C = p_C2 | p_C3; // to ustvarja vzporedni izhod faze C

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

PIOC-> PIO_ODSR = p_A; // izhodni register = p_A

t ++; }

4. korak: R/2R DAC

zgradite 3x8bit R/2R DAC, veliko ref na Googlu.

5. korak: Celotna koda

#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 Vrednost faze C faze B-čeprav so izhodi samo 8 bitov, bo vrednost p_A in p_B delovala za ustvarjanje nove 32-bitne vrednosti, da bi se spopadli z 32-bitnim izhodom PIOC

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t interval; uint16_t vzorci, prednastavljeni; uint32_t t = 0;

void setup () {

// vzporedni izhod Nastavitev PIOC: Arduino Due pin33-40 se uporablja kot izhod faze A, medtem ko pin 44-51 deluje za izhod faze B

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO krmilnik PIO Enable register (glejte p656 podatkovnega lista ATMEL SAM3X) in https://arduino.cc/en/Hacking/PinMappingSAM3X, pin 33-41 in 44-51 Arduino Due sta bila omogočena

PIOC-> PIO_OER = 0xFFFFFFFE; // Register za omogočanje izhoda krmilnika PIO, glejte p657 podatkovnega lista ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Register stanja izhoda krmilnika PIO, glejte p658 podatkovnega lista ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Register za omogočanje zapisovanja izhodov PIO, glejte p670 podatkovnega lista ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // izbirno kot zavarovanje, ne vpliva na zmogljivost, digitalni pin 10 se poveže z računalnikom PC29 in PA28, digitalni pin 4 se poveže z računalnikom PC29 in PA28, tukaj za onemogočanje onemogočanja nastavitev časovnika PIOA #28 in 29 // glejte https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (napačno); // onemogoči zaščito pred pisanjem registrov za upravljanje porabe energije

pmc_enable_periph_clk (ID_TC7); // omogočimo števec časa periferne ure 7

TC_Configure (/ * ura */TC2,/ * kanal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC ura 42MHz (ura, kanal, nastavitev načina primerjave) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// omogočimo časovne prekinitve na časovniku TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = register za omogočanje prekinitev TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = register za prekinitev prekinitve

NVIC_EnableIRQ (TC7_IRQn); // Omogoči prekinitev v ugnezdenem vektorskem krmilniku prekinitev freq = 60; // inicializiramo frekvenco kot prednastavljeno 60Hz = 21; // povečanje indeksa matrike za 21 vzorcev = 256; // izhodni vzorci 256/interval cikla = 42000000/(frekvenčni*vzorci); // štetje prekinitev TC_SetRC (TC2, 1, interval); // zagon TC Serial.begin (9600); // za namene preizkusa}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} drugače

{freq = freqNew;

če (freq> 20000) {freq = 20000; /*največja frekvenca 20kHz*/};

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

if (freq> 999) {preset = 384; vzorci = 14;} // za frekvenco> = 1kHz, 14 vzorcev za vsak cikel

else if (freq> 499) {preset = 84; vzorci = 64;} // za 500 <= frekvenca99) {prednastavitev = 42; vzorci = 128;} // za 100Hz <= frekvenca <500Hz, 128 vzorcev/cikel

else {prednastavljena = 21; vzorci = 256;}; // za frekvenco <100Hz, 256 vzorcev za vsak cikel

interval = 42000000/(frekv.*vzorci); t = 0; TC_SetRC (TC2, 1, interval); }}

void loop () {

checkFreq (); zamuda (100); }

void TC7_Handler (void)

{TC_GetStatus (TC2, 1);

t = t%vzorcev; // uporabite t%vzorcev, da preprečite prelivanje t phaseAInc = (prednastavljeno*t)%5376; // uporabite %5376, da se izognete prelivanju indeksa matrike

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // glej PIOC: PC1 do PC8, ustrezen Arduino Due pin: pin 33-40, zato pomaknite levo za eno številko

p_B = sin768 [phaseBInc] << 12; // glej PIOC: PC12 do PC19, ustrezen zatič Arduino Due: pin 51-44, zato pomaknite 12-mestno levo

p_C = sin768 [phaseCInc]; // izhod faze C zaposleni PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 in PC29, ustrezen zatič Arduino Due: digitalni zatič: 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // s tem nastaneta PC28 in PC29

p_C3 = (p_C & B00111111) << 21; // to generira PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // to ustvarja vzporedni izhod faze C

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

PIOC-> PIO_ODSR = p_A; // izhodni register = p_A t ++; }

Priporočena: