INHOUDSOPGAWE:

3 -fase sinusgolfgenerator gebaseer op Arduino Due: 5 stappe
3 -fase sinusgolfgenerator gebaseer op Arduino Due: 5 stappe

Video: 3 -fase sinusgolfgenerator gebaseer op Arduino Due: 5 stappe

Video: 3 -fase sinusgolfgenerator gebaseer op Arduino Due: 5 stappe
Video: Mit dem Shunt-Widerstand mit Arduino bis zu 500 A Gleichstrom messen 2024, Julie
Anonim
Driefase sinusgolfgenerator gebaseer op Arduino Due
Driefase sinusgolfgenerator gebaseer op Arduino Due

die doel van hierdie aandeel is om iemand te help wat Due se groter prestasie + gebrek aan verwysing + nie-nuttige datablad probeer gebruik.

hierdie projek kan tot 3 -fase sinusgolf @ 256 monsters / siklus genereer teen lae frekwensie (<1kHz) en 16 monsters / siklus @ hoë frekwensie (tot 20kHz), wat goed genoeg is om glad gemaak te word deur eenvoudige LPF's en die uitset is amper perfek.

die aangehegte lêer was nie my finale weergawe nie, want ek het 'n ekstra funksie bygevoeg, maar die kern daarvan is dieselfde. Let op die monsters/siklus is laer gestel as die stelling hierbo.

Aangesien die SVE -kapasiteit maksimaliseer deur die benadering wat in die aangehegte lêer getoon word, het ek 'n Arduino Uno as beheer -eenheid gebruik, wat die eksterne onderbreking van Arduino Due gebruik om die frekwensiewaarde aan Arduino Due oor te dra. Benewens frekwensiebeheer, beheer die Arduino Uno ook amplitude (deur middel van digitale potensiaalmeter + OpAmp) sowel as I/O --- daar is baie ruimte om mee te speel.

Stap 1: Genereer Sine Data Array

Aangesien real-time berekening CPU-veeleisend is, is 'n sinus-data-skikking nodig vir beter prestasie

uint32_t sin768 PROGMEEM =…. terwyl x = [0: 5375]; y = 127+127*(sin (2*pi/5376/*of 'n paar # wat u verkies hang af van vereiste*/))

Stap 2: Aktiveer parallelle uitvoer

Anders as Uno, het Due beperkte verwysing. Om 'n 3 -fase sinusgolf te genereer, gebaseer op Arduino Uno, is die prestasie egter nie van toepassing nie, vanweë die lae MCLK (16MHz terwyl Due 84MHz), 2de, dit is beperk GPIO kan maksimum 2 -fase -uitset lewer en benodig u ekstra analoog kring om die 3de fase (C = -AB) te produseer.

Die navolging van GPIO was meestal gebaseer op probeer en probeer+nie 'n nuttige datablad van SAM3X nie

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO-beheerder PIO Aktiveer register (verwys na p656 van ATMEL SAM3X-datablad) en https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 en 44-51 is geaktiveer

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO-kontroleerder se uitset-inskakelregister, verwys na p657 van die ATMEL SAM3X-datablad PIOC-> PIO_OSR = 0xFFFFFFFE; // Uitvoerstatusregister van die PIO -beheerder, verwys na p658 van die ATMEL SAM3X -datablad

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO -uitvoer skryf aktiveer register, verwys na p670 van ATMEL SAM3X datablad

// PIOA-> PIO_PDR = 0x30000000; // opsioneel as versekering, dit lyk nie of dit die prestasie beïnvloed nie; digitale pen 10 maak verbinding met beide PC29 en PA28, digitale pen 4 sluit aan op beide PC29 en PA28, hier om PIOA #28 & 29 uit te skakel

Stap 3: Aktiveer onderbreking

Om die werkverrigting te maksimeer, moet die CPU -laai so laag as moontlik wees. As gevolg van die nie-1 tot 1 korrespondensie tussen die CPU-pen en die Due-pen, is dit egter nodig om bietjie te werk.

U kan die algoritme verder optimaliseer, maar die ruimte is baie beperk.

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

t = t%monsters; // gebruik t%monsters in plaas van 'if' om oorloop van t te voorkom

phaseAInc = (vooraf*t)%5376; // gebruik %5376 om oorloop van skikkingindeks te voorkom

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // verwys na PIOC: PC1 tot PC8, ooreenstemmende Arduino Due-pen: pen 33-40, skuif dus links vir 1 syfer

p_B = sin768 [phaseBInc] << 12; // verwys na PIOC: PC12 na PC19, ooreenstemmende Arduino Due-pen: pen 51-44, skuif dus 12-syfer links

p_C = sin768 [phaseCInc]; // fase C -uitvoer gebruik PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 en PC29, ooreenstemmende Arduino Due pin: digitale pen: 9, 8, 7, 6, 5, 4, 3, 10, onderskeidelik

p_C2 = (p_C & B11000000) << 22; // dit genereer PC28 en PC29

p_C3 = (p_C & B00111111) << 21; // dit genereer PC21-PC26

p_C = p_C2 | p_C3; // dit genereer parallelle uitset van fase C

p_A = p_A | p_B | p_C; // 32 bit uitset = fase A (8bit) | fase B | fase C

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

t ++; }

Stap 4: R/2R DAC

bou 3x8bit R/2R DAC, baie ref op Google.

Stap 5: Volledige kode

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

uint32_t p_A, p_B, p_C, p_C2, p_C3; // fase A fase B fase C-waarde-alhoewel uitset slegs 8-bits is, sal p_A- en p_B-waarde gebruik word om 'n nuwe 32-biswaarde te genereer om die 32bit PIOC-uitset te hanteer

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t interval; uint16_t monsters, vooraf ingestel; uint32_t t = 0;

ongeldige opstelling () {

// parallelle uitset PIOC-opstelling: Arduino Due pin33-40 word gebruik as fase A-uitset terwyl pen 44-51 werk vir fase B-uitset

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO-beheerder PIO Aktiveer register (verwys na p656 van ATMEL SAM3X-datablad) en https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 en 44-51 is geaktiveer

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO -kontroleerder se uitvoeruitsetregister, verwys na p657 van die ATMEL SAM3X -datablad

PIOC-> PIO_OSR = 0xFFFFFFFE; // Uitvoerstatusregister van PIO -beheerder, verwys na p658 van die ATMEL SAM3X -datablad

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO -uitvoer skryfregister aktiveer, verwys na p670 van die ATMEL SAM3X -datablad

// PIOA-> PIO_PDR = 0x30000000; // opsioneel as versekering, dit lyk nie of dit die prestasie beïnvloed nie; digitale pen 10 maak verbinding met beide PC29 en PA28, digitale pen 4 sluit aan op beide PC29 en PA28, hier om PIOA #28 & 29 // timer -opstelling uit te skakel, verwys na https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (vals); // skakel skryfbeskerming van Power Management Control -registers uit

pmc_enable_periph_clk (ID_TC7); // skakel tydteller vir perifere klok in 7

TC_Configure (/ * klok */TC2,/ * kanaal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC -klok 42MHz (klok, kanaal, vergelyking van modus) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// skakel tydonderbrekings in op die timer TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = onderbreek aktiveer register TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = onderbreek deaktiveer register

NVIC_EnableIRQ (TC7_IRQn); // Aktiveer die onderbreking in die geneste vektoronderbrekingsbeheerder -frekwensie = 60; // initialiseer frekwensie as vooraf ingestelde 60Hz = 21; // skikkingindeks verhoog met 21 monsters = 256; // uitsetmonsters 256/siklusinterval = 42000000/(frekwensie*monsters); // onderbreek tellings TC_SetRC (TC2, 1, interval); // begin TC Serial.begin (9600); // vir toetsdoeleindes}

leemte checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} anders

{freq = freqNuus;

as (freq> 20000) {freq = 20000; /*maksimum frekwensie 20kHz*/};

as (freq <1) {freq = 1; /*min frekwensie 1Hz*/};

as (frekwensie> 999) {vooraf ingestel = 384; monsters = 14;} // vir frekwensie> = 1kHz, 14 monsters vir elke siklus

anders as (freq> 499) {vooraf ingestel = 84; monsters = 64;} // vir 500 <= frequensie99) {vooraf ingestelde = 42; monsters = 128;} // vir 100Hz <= frekwensie <500Hz, 128 monsters/siklus

anders {vooraf ingestel = 21; monsters = 256;}; // vir frekwensie <100 Hz, 256 monsters vir elke siklus

interval = 42000000/(frekwensie*monsters); t = 0; TC_SetRC (TC2, 1, interval); }}

leemte -lus () {

checkFreq (); vertraging (100); }

leegte TC7_Handler (nietig)

{TC_GetStatus (TC2, 1);

t = t%monsters; // gebruik t%monsters om oorloop van t phaseAInc = (vooraf*t)%5376 te vermy; // gebruik %5376 om oorloop van skikkingindeks te voorkom

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // verwys na PIOC: PC1 tot PC8, ooreenstemmende Arduino Due-pen: pen 33-40, skuif dus links vir 1 syfer

p_B = sin768 [phaseBInc] << 12; // verwys na PIOC: PC12 na PC19, ooreenstemmende Arduino Due-pen: pen 51-44, skuif dus 12-syfer links

p_C = sin768 [phaseCInc]; // fase C -uitvoer gebruik PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 en PC29, ooreenstemmende Arduino Due pin: digitale pen: 9, 8, 7, 6, 5, 4, 3, 10, onderskeidelik

p_C2 = (p_C & B11000000) << 22; // dit genereer PC28 en PC29

p_C3 = (p_C & B00111111) << 21; // dit genereer PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // dit genereer parallelle uitset van fase C

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

PIOC-> PIO_ODSR = p_A; // uitsetregister = p_A t ++; }

Aanbeveel: