Përmbajtje:

3 Faza Gjenerator Vala Sinus Bazuar në Arduino Për shkak: 5 Hapa
3 Faza Gjenerator Vala Sinus Bazuar në Arduino Për shkak: 5 Hapa

Video: 3 Faza Gjenerator Vala Sinus Bazuar në Arduino Për shkak: 5 Hapa

Video: 3 Faza Gjenerator Vala Sinus Bazuar në Arduino Për shkak: 5 Hapa
Video: Прямой запуск инверторного компрессора холодильника и тестирование UVW 2024, Nëntor
Anonim
3 Faza Gjenerator Vala Sinus Bazuar në Arduino Due
3 Faza Gjenerator Vala Sinus Bazuar në Arduino Due

qëllimi i këtij aksioni është të ndihmojë dikë që po përpiqet të përdorë performancën më të madhe të Due + mungesën e referencës + fletën e të dhënave jo të dobishme.

ky projekt është në gjendje të gjenerojë deri në 3 faza sinusale @ 256 mostra / cikël me frekuencë të ulët (<1kHz) dhe 16 mostra / cikël @ frekuencë të lartë (deri në 20kHz), e cila është mjaft e mirë për t'u zbutur nga LPF -të e thjeshta dhe prodhimi është pothuajse i përsosur.

skedari i bashkangjitur nuk ishte versioni im përfundimtar, sepse shtova disa veçori shtesë, por thelbi është i njëjtë me të. Vini re se mostrat/cikli u vendosën më poshtë se deklarata e mësipërme.

meqenëse kapaciteti i CPU -së është maksimizuar përmes qasjes së treguar në skedarin e bashkangjitur, kam përdorur një njësi kontrolli Arduino Uno, të cilët përdorin ndërprerjen e jashtme të Arduino Due për të kaluar vlerën e frekuencës në Arduino Due. Përveç kontrollit të frekuencës, Arduino Uno gjithashtu kontrollon amplitudën (përmes njehsorit potencial dixhital + OpAmp) si dhe I/O --- do të ketë shumë hapësirë për të luajtur.

Hapi 1: Gjeneroni grupin e të dhënave Sine

Meqenëse llogaritja në kohë reale kërkon CPU, kërkohet një grup i të dhënave sinus për performancë më të mirë

uint32_t sin768 PROGMEM =…. ndërsa x = [0: 5375]; y = 127+127*(mëkati (2*pi/5376/*ose disa # që preferoni varet nga kërkesa*/))

Hapi 2: Aktivizimi i daljes paralele

Ndryshe nga Uno, Due kanë referencë të kufizuar. Sidoqoftë, për të gjeneruar valë sinus 3 fazore bazuar në Arduino Uno, së pari, performanca nuk është e pëlqyeshme për shkak të MCLK -së së ulët (16MHz ndërsa Due është 84MHz), e dyta, GPIO -ja e saj e kufizuar mund të prodhojë max 2 dalje fazore dhe keni nevojë për shtesë qark analog për të prodhuar fazën e 3-të (C = -AB).

Pas aktivizimit të GPIO u bazua kryesisht në provën dhe provën+fletën e të dhënave jo të dobishme të SAM3X

PIOC-> PIO_PER = 0xFFFFFFE; // Kontrolluesi PIO PIO Aktivizo regjistrin (referoju p656 të fletës së të dhënave ATMEL SAM3X) dhe https://arduino.cc/en/Hacking/PinMappingSAM3X, kunjat Arduino Due 33-41 dhe 44-51 u aktivizuan

PIOC-> PIO_OER = 0xFFFFFFE; // Dalja e regjistrit të aktivizimit të kontrolluesit PIO, referojuni p657 të fletës së të dhënave ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Regjistri i statusit të daljes së kontrolluesit PIO, referojuni p658 të fletës së të dhënave ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFE; // Regjistri i aktivizimit të shkrimit PIO output, referojuni p670 të fletës së të dhënave ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opsionale si sigurim, nuk duket se ndikon në performancën, kunja dixhitale 10 lidhet me PC29 dhe PA28, kodi dixhital 4 lidhet me PC29 dhe PA28, këtu për të çaktivizuar çaktivizoni PIOA #28 & 29

Hapi 3: Aktivizimi i ndërprerjes

Për të maksimizuar performancën e tij, ngarkesa e CPU duhet të jetë sa më e ulët. Megjithatë për shkak të korrespondencës jo-1to1 midis kunjit të CPU-së dhe kunjës Due, funksionimi i bitit është i nevojshëm.

Ju mund të optimizoni më tej algoritmin, por dhoma është shumë e kufizuar.

i pavlefshëm TC7_Handler (i pavlefshëm) {TC_GetStatus (TC2, 1);

t = t%mostra; // përdorni mostrat t%në vend të 'nëse' për të shmangur tejmbushjen e t

fazaAInc = (e paracaktuar*t)%5376; // përdorni %5376 për të shmangur tejmbushjen e indeksit të grupit

fazaBInc = (fazaAInc+1792)%5376;

fazaCInc = (fazaAInc+3584)%5376;

p_A = sin768 [fazaAInc] << 1; // referojuni PIOC: PC1 në PC8, kodi përkatës Arduino Due: pin 33-40, kështu që zhvendoseni majtas për 1 shifër

p_B = sin768 [fazaBInc] << 12; // referojuni PIOC: PC12 në PC19, kodi përkatës Arduino Due: pin 51-44, pra zhvendoseni majtas me 12 shifra

p_C = sin768 [fazaCInc]; // dalja në fazën C punonjës PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 dhe PC29, kunja përkatëse Arduino Due: kodi digjital: 9, 8, 7, 6, 5, 4, 3, 10, respektivisht

p_C2 = (p_C & B11000000) << 22; // kjo gjeneron PC28 dhe PC29

p_C3 = (p_C & B00111111) << 21; // kjo gjeneron PC21-PC26

p_C = p_C2 | p_C3; // kjo gjeneron dalje paralele të fazës C

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

PIOC-> PIO_ODSR = p_A; // regjistri i daljes = p_A

t ++; }

Hapi 4: R/2R DAC

ndërtuar 3x8bit R/2R DAC, ngarkesa ref në google.

Hapi 5: Kodi i plotë

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

uint32_t p_A, p_B, p_C, p_C2, p_C3; // faza A faza B vlera e fazës C-edhe pse dalja është vetëm 8 bit, vlera p_A dhe p_B do të operohet për të gjeneruar një vlerë të re 32 bit për të përballuar daljen PIOC 32bit

uint16_t fazaAInc, fazaBInc, fazaCInc, frekuencë, frekuencë e re; intervali uint32_t; mostra uint16_t, të paravendosura; uint32_t t = 0;

void setup () {

// Konfigurimi PIOC i daljes paralele: Arduino Due pin33-40 janë përdorur si dalje e fazës A ndërsa kunja 44-51 punon për daljen e fazës B

PIOC-> PIO_PER = 0xFFFFFFE; // Kontrolluesi PIO PIO Aktivizo regjistrin (referoju p656 të fletës së të dhënave ATMEL SAM3X) dhe https://arduino.cc/en/Hacking/PinMappingSAM3X, kunjat Arduino Due 33-41 dhe 44-51 u aktivizuan

PIOC-> PIO_OER = 0xFFFFFFE; // Regjistri i aktivizimit të daljes së kontrolluesit PIO, referojuni p657 të fletës së të dhënave ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFE; // Regjistri i statusit të daljes së kontrolluesit PIO, referojuni p658 të fletës së të dhënave ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFE; // Regjistri i aktivizimit të shkrimit PIO output, referojuni p670 të fletës së të dhënave ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opsionale si sigurim, nuk duket se ndikon në performancën, kunja dixhitale 10 lidhet si me PC29 ashtu edhe me PA28, kunja dixhitale 4 lidhet me PC29 dhe PA28, këtu për të çaktivizuar çaktivizoni konfigurimin e kohëmatësit PIOA #28 & 29 // referojuni https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (false); // çaktivizoni mbrojtjen e shkrimit të regjistrave të Kontrollit të Menaxhimit të Fuqisë

pmc_enable_periph_clk (ID_TC7); // aktivizoni numëruesin e orës periferike të kohës 7

TC_Konfiguro (/ * ora */TC2,/ * kanali */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Ora TC 42MHz (ora, kanali, krahasoni cilësimin e modalitetit) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// aktivizoni ndërprerjet e kohëmatësit në kohëmatësin TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = ndërprerja e regjistrit të aktivizimit TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = ndërpres regjistrin çaktivizo

NVIC_EnableIRQ (TC7_IRQn); // Aktivizo ndërprerjen në frekuencën e kontrolluesit të ndërprerë të vektorit të ndërprerë = 60; // filloni frekuencën si 60Hz të paravendosur = 21; // indeksi i grupit rritet me 21 mostra = 256; // mostra dalëse 256/interval cikli = 42000000/(frekuenca*mostra); // numëron ndërprerjen TC_SetRC (TC2, 1, interval); // fillo TC Serial.begin (9600); // për qëllim testimi}

void checkFreq ()

{frekuNjë = 20000;

if (freq == freqNew) {} tjetër

{freq = freqNjë e re;

nëse (frekuenca> 20000) {freq = 20000; /*frekuenca maksimale 20kHz*/};

nëse (freq <1) {freq = 1; /*frekuenca min 1Hz*/};

nëse (frekuenca> 999) {paravendosur = 384; mostra = 14;} // për frekuencën> = 1kHz, 14 mostra për çdo cikël

tjetër nëse (frekuenca> 499) {paravendosur = 84; mostra = 64;} // për 500 <= frekuenca99) {paravendosur = 42; mostrat = 128;} // për 100Hz <= frekuenca <500Hz, 128 mostra/cikël

tjetër {paravendosur = 21; mostra = 256;}; // për frekuencën <100hz, 256 mostra për çdo cikël

intervali = 42000000/(frekuenca*mostra); t = 0; TC_SetRC (TC2, 1, interval); }}

lak void () {

checkFreq (); vonesë (100); }

i pavlefshëm TC7_Handler (i pavlefshëm)

{TC_GetStatus (TC2, 1);

t = t%mostra; // përdorni t%mostra për të shmangur tejmbushjen e t fazësAInc = (paravendosur*t)%5376; // përdorni %5376 për të shmangur tejmbushjen e indeksit të grupit

fazaBInc = (fazaAInc+1792)%5376;

fazaCInc = (fazaAInc+3584)%5376;

p_A = sin768 [fazaAInc] << 1; // referojuni PIOC: PC1 në PC8, kodi përkatës Arduino Due: pin 33-40, pra zhvendoseni majtas për 1 shifër

p_B = sin768 [fazaBInc] << 12; // referojuni PIOC: PC12 në PC19, kodi përkatës Arduino Due: pin 51-44, pra zhvendoseni majtas me 12 shifra

p_C = sin768 [fazaCInc]; // dalja e fazës C punonjës PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 dhe PC29, kunja përkatëse Arduino Due: kodi digjital: 9, 8, 7, 6, 5, 4, 3, 10, respektivisht

p_C2 = (p_C & B11000000) << 22; // kjo gjeneron PC28 dhe PC29

p_C3 = (p_C & B00111111) << 21; // kjo gjeneron PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // kjo gjeneron dalje paralele të fazës C

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

PIOC-> PIO_ODSR = p_A; // regjistri i daljes = p_A t ++; }

Recommended: