Obsah:

3fázový generátor sinusových vln na základě Arduino: 5 kroků
3fázový generátor sinusových vln na základě Arduino: 5 kroků

Video: 3fázový generátor sinusových vln na základě Arduino: 5 kroků

Video: 3fázový generátor sinusových vln na základě Arduino: 5 kroků
Video: Vznik střídavého proudu 2024, Červenec
Anonim
3fázový generátor sinusových vln založený na splatnosti Arduino
3fázový generátor sinusových vln založený na splatnosti Arduino

účelem tohoto sdílení je pomoci někomu, kdo se snaží využít vyšší výkon Due + nedostatek reference + neužitečný list.

tento projekt je schopen generovat až 3 fázové sinusové vlny při 256 vzorcích / cyklus při nízké frekvenci (<1 kHz) a 16 vzorcích / cyklus při vysoké frekvenci (až 20 kHz), což je dost dobré na to, aby to bylo možné vyhladit jednoduchými LPF a výstup je téměř dokonalý.

připojený soubor nebyl mojí konečnou verzí, protože jsem přidal nějakou další funkci, ale jádro je stejné. Všimněte si, že vzorky/cyklus byly nastaveny níže než výše.

protože kapacita procesoru je maximalizována prostřednictvím přístupu zobrazeného v přiloženém souboru, použil jsem jako řídicí jednotku Arduino Uno, který využívá externí přerušení Arduino Due k předání hodnoty frekvence Arduino Due. Kromě ovládání frekvence Arduino Uno také ovládá amplitudu (prostřednictvím digitálního měřiče potenciálu + OpAmp) a I/O --- bude zde spousta prostoru pro hraní.

Krok 1: Vygenerujte sinusové datové pole

Vzhledem k tomu, že výpočet v reálném čase je náročný na CPU, je pro lepší výkon vyžadováno sinusové datové pole

uint32_t sin768 PROGMEM =…. zatímco x = [0: 5375]; y = 127+127*(sin (2*pi/5376/*nebo nějaké # preferujete, závisí na požadavku*/))

Krok 2: Povolení paralelního výstupu

Na rozdíl od Uno mají Due omezenou referenci. Aby však bylo možné generovat 3fázovou sinusovou vlnu na základě Arduino Uno, 1. výkon není kvůli nízkému MCLK (16MHz, zatímco Due je 84MHz) potleskem, za druhé, GPIO s omezeným výkonem může produkovat max. 2fázový výstup a potřebujete další analogový obvod k výrobě 3. fáze (C = -AB).

Následující povolení GPIO bylo většinou založeno na pokusu a pokusu+neužitečný datový list SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO řadič PIO Povolit registr (viz str. 656 datového listu ATMEL SAM3X) a byly povoleny https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 a 44-51

PIOC-> PIO_OER = 0xFFFFFFFE; // Registrace povolení výstupu výstupu PIO, viz p657 datového listu ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Register stavu výstupu PIO ovladače, viz str. 658 datového listu ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Register PIO output write register, see p670 of ATMEL SAM3X datasheet

// PIOA-> PIO_PDR = 0x30000000; // volitelně jako pojištění, nezdá se, že by to mělo vliv na výkon, digitální pin 10 připojte k PC29 i PA28, digitální pin 4 připojte k PC29 i PA28, zde deaktivujte deaktivaci PIOA #28 & 29

Krok 3: Povolení přerušení

Aby se maximalizoval jeho výkon, mělo by být zatížení procesoru co nejnižší. Nicméně vzhledem k tomu, že mezi pinem CPU a pinem Due není korespondence 1to1, je bitová operace nutná.

Algoritmus můžete dále optimalizovat, ale místnost je velmi omezená.

neplatný TC7_Handler (neplatný) {TC_GetStatus (TC2, 1);

t = t%vzorků; // použijte místo 'if' vzorky t%, aby nedošlo k přetečení t

phaseAInc = (přednastaveno*t)%5376; // použijte %5376, abyste se vyhnuli přetečení indexu pole

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // viz PIOC: PC1 až PC8, odpovídající Arduino Due pin: pin 33-40, proto posun doleva o 1 číslici

p_B = sin768 [phaseBInc] << 12; // viz PIOC: PC12 až PC19, odpovídající pin Arduino Due: pin 51-44, proto posun doleva o 12 číslic

p_C = sin768 [phaseCInc]; // výstup fáze C zaměstnanci PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 a PC29, odpovídající pin Arduino Due: digitální pin: 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // toto generuje PC28 a PC29

p_C3 = (p_C & B00111111) << 21; // toto generuje PC21-PC26

p_C = p_C2 | p_C3; // toto generuje paralelní výstup fáze C

p_A = p_A | p_B | p_C; // 32bitový výstup = fáze A (8bit) | fáze B | fáze C

PIOC-> PIO_ODSR = p_A; // výstupní registr = p_A

t ++; }

Krok 4: R/2R DAC

stavět 3x8bit R/2R DAC, spousta odkazů na google.

Krok 5: Úplný kód

#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; // fáze A fáze B hodnota C-přestože výstup je pouze 8bitový, budou použity hodnoty p_A a p_B ke generování nové 32bitové hodnoty za účelem kopírování s 32bitovým výstupem PIOC

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t interval; uint16_t vzorky, přednastavené; uint32_t t = 0;

neplatné nastavení () {

// Nastavení PIOC paralelního výstupu: Arduino Due pin33-40 jsou použity jako výstup fáze A, zatímco pin 44-51 pracuje pro výstup fáze B

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO řadič PIO Povolit registr (viz str. 656 datového listu ATMEL SAM3X) a byly povoleny https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 a 44-51

PIOC-> PIO_OER = 0xFFFFFFFE; // Registrace povolení výstupu výstupu PIO, viz p657 datového listu ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Register stavu výstupu PIO ovladače, viz str. 658 datového listu ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registrace umožňující zápis výstupu PIO, viz p670 datového listu ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // volitelně jako pojištění, nezdá se, že by to mělo vliv na výkon, digitální pin 10 připojte k PC29 i PA28, digitální pin 4 připojte k PC29 i PA28, zde deaktivujte deaktivaci PIOA #28 & 29 // nastavení časovače, viz https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (false); // deaktivujte ochranu proti zápisu registrů Power Management Control

pmc_enable_periph_clk (ID_TC7); // povolit počítadlo času periferních hodin 7

TC_Configure (/ * hodiny */TC2,/ * kanál */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC hodiny 42MHz (hodiny, kanál, nastavení režimu porovnání) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// povolení časovačů na časovači TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = povolit přerušení registr TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = přerušení zakázat registr

NVIC_EnableIRQ (TC7_IRQn); // Povolení přerušení ve vnořeném vektorovém řadiči přerušení freq = 60; // inicializace frekvence jako 60Hz přednastaveno = 21; // zvýšení indexu pole o 21 vzorků = 256; // výstupní vzorky 256/interval cyklu = 42000000/(frekv*vzorky); // počet přerušení TC_SetRC (TC2, 1, interval); // spuštění TC Serial.begin (9600); // pro testovací účely}

zrušit checkFreq ()

{freqNew = 20 000;

if (freq == freqNew) {} else

{freq = freqNew;

if (freq> 20000) {freq = 20000; /*maximální frekvence 20kHz*/};

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

if (freq> 999) {preset = 384; vzorky = 14;} // pro frekvenci> = 1 kHz, 14 vzorků pro každý cyklus

else if (freq> 499) {preset = 84; vzorky = 64;} // pro 500 <= frekvence99) {preset = 42; vzorky = 128;} // pro 100 Hz <= frekvence <500 Hz, 128 vzorků/cyklus

else {preset = 21; vzorky = 256;}; // pro frekvenci <100 Hz 256 vzorků pro každý cyklus

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

prázdná smyčka () {

checkFreq (); zpoždění (100); }

neplatné TC7_Handler (neplatné)

{TC_GetStatus (TC2, 1);

t = t%vzorků; // pomocí t%vzorků se vyhnete přetečení t phaseAInc = (přednastaveno*t)%5376; // použijte %5376, abyste se vyhnuli přetečení indexu pole

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // viz PIOC: PC1 až PC8, odpovídající Arduino Due pin: pin 33-40, proto posun doleva o 1 číslici

p_B = sin768 [phaseBInc] << 12; // viz PIOC: PC12 až PC19, odpovídající pin Arduino Due: pin 51-44, proto posun doleva o 12 číslic

p_C = sin768 [phaseCInc]; // výstup fáze C zaměstnanci PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 a PC29, odpovídající pin Arduino Due: digitální pin: 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // toto generuje PC28 a PC29

p_C3 = (p_C & B00111111) << 21; // toto generuje PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // toto generuje paralelní výstup fáze C

p_A = p_A | p_B | p_C; // 32bitový výstup = fáze A (8bit) | fáze B | fáze C //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // výstupní registr = p_A t ++; }

Doporučuje: