Innholdsfortegnelse:

3 -faset sinusbølge -generator basert på Arduino Due: 5 trinn
3 -faset sinusbølge -generator basert på Arduino Due: 5 trinn

Video: 3 -faset sinusbølge -generator basert på Arduino Due: 5 trinn

Video: 3 -faset sinusbølge -generator basert på Arduino Due: 5 trinn
Video: Moleman 2 - Demoscene - The Art of the Algorithms (2012) 2024, November
Anonim
3 -faset sinusbølge -generator basert på Arduino Due
3 -faset sinusbølge -generator basert på Arduino Due

Formålet med denne aksjen er å hjelpe noen som prøver å bruke Due større ytelse + mangel på referanse + ikke-nyttig datablad.

dette prosjektet er i stand til å generere opptil 3 -faset sinusbølge @ 256 prøver / syklus ved lav frekvens (<1 kHz) og 16 prøver / syklus @ høy frekvens (opptil 20 kHz), noe som er godt nok til å bli jevnet med enkle LPFer og utgangen er nesten perfekt.

den vedlagte filen var ikke min siste versjon, for jeg la til en ekstra funksjon, men kjernen er den samme. Vær oppmerksom på at prøvene/syklusen ble satt lavere enn utsagnet ovenfor.

siden CPU -kapasiteten er maksimert gjennom tilnærmingen vist i den vedlagte filen, brukte jeg en Arduino Uno som kontrollenhet, som bruker Arduino Due eksterne avbrudd for å sende frekvensverdi til Arduino Due. I tillegg til frekvenskontroll, styrer Arduino Uno også amplitude (gjennom digital potensialmåler + OpAmp) samt I/O --- det vil være mye plass å leke med.

Trinn 1: Generer Sine Data Array

Siden sanntidsberegning er CPU-krevende, kreves en sinusdatamatrise for bedre ytelse

uint32_t sin768 PROGMEM =….imens x = [0: 5375]; y = 127+127*(sin (2*pi/5376/*eller noen # du foretrekker avhenger av kravet*/))

Trinn 2: Aktivering av parallellutgang

I motsetning til Uno har Due begrenset referanse. For å generere en 3 -faset sinusbølge basert på Arduino Uno, for det første, er ytelsen ikke applausable på grunn av den lave MCLK (16MHz mens Due er 84MHz), andre, den er begrenset GPIO kan produsere maks 2 -faset utgang, og du trenger ekstra analog krets for å produsere den tredje fasen (C = -AB).

Å følge GPIO -aktivering var hovedsakelig basert på prøve og prøve+ikke nyttig datablad for SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO-kontroller PIO Aktiver register (se p656 i ATMEL SAM3X-datablad) og https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 og 44-51 ble aktivert

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO-kontroller utgangsaktiveringsregister, se p657 i ATMEL SAM3X datablad PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO -kontroller utgangsstatusregister, se p658 i ATMEL SAM3X -databladet

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO -utgang skrive aktiveringsregister, se p670 i ATMEL SAM3X datablad

// PIOA-> PIO_PDR = 0x30000000; // valgfri som forsikring, ser ikke ut til å påvirke ytelsen, digital pin 10 kobles til både PC29 og PA28, digital pin 4 kobles til både PC29 og PA28, her for å deaktivere deaktiver PIOA #28 & 29

Trinn 3: Aktivering av avbrudd

For å maksimere ytelsen, bør CPU -belastningen være så lav som mulig. På grunn av ikke-1 til 1-korrespondansen mellom CPU-pinnen og Due-pinnen, er bitoperasjon imidlertid nødvendig.

Du kan ytterligere optimalisere algoritmen, men rommet er svært begrenset.

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

t = t%prøver; // bruk t%prøver i stedet for 'hvis' for å unngå overløp av t

phaseAInc = (forhåndsinnstilt*t)%5376; // bruk %5376 for å unngå overgang av matriseindeks

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // referer til PIOC: PC1 til PC8, tilsvarende Arduino Due pin: pin 33-40, derfor skift til venstre for 1 siffer

p_B = sin768 [phaseBInc] << 12; // referer til PIOC: PC12 til PC19, tilsvarende Arduino Due pin: pin 51-44, derfor skift venstre 12 siffer

p_C = sin768 [phaseCInc]; // fase C -utgang bruker PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 og PC29, tilsvarende Arduino Due pin: digital pin: 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // dette genererer PC28 og PC29

p_C3 = (p_C & B00111111) << 21; // dette genererer PC21-PC26

p_C = p_C2 | p_C3; // dette genererer parallell utgang fra fase C

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

PIOC-> PIO_ODSR = p_A; // utdataregister = p_A

t ++; }

Trinn 4: R/2R DAC

bygge 3x8bit R/2R DAC, masse ref på google.

Trinn 5: Full kode

#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; // fase A fase B fase C-verdi-selv om utdata bare er 8bits, vil p_A og p_B-verdien bli operert for å generere en ny 32-biters verdi for å klare 32-biters PIOC-utgang

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t intervall; uint16_t prøver, forhåndsinnstilte; uint32_t t = 0;

ugyldig oppsett () {

// parallell utgang PIOC-oppsett: Arduino Due pin33-40 brukes som fase A-utgang mens pin 44-51 fungerer for fase B-utgang

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO-kontroller PIO Aktiver register (se p656 i ATMEL SAM3X-datablad) og https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 og 44-51 ble aktivert

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO -kontroller utgangsaktiveringsregister, se p657 i ATMEL SAM3X -databladet

PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO -kontroller utgangsstatusregister, se p658 i ATMEL SAM3X -databladet

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO -utgang skrive aktiveringsregister, se p670 i ATMEL SAM3X datablad

// PIOA-> PIO_PDR = 0x30000000; // valgfri som forsikring, ser ikke ut til å påvirke ytelsen, digital pin 10 kobles til både PC29 og PA28, digital pin 4 kobles til både PC29 og PA28, her for å deaktivere deaktiver PIOA #28 & 29 // timeroppsett, se https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (false); // deaktiver skrivebeskyttelse av Power Management Control -registre

pmc_enable_periph_clk (ID_TC7); // aktivere perifer klokke tidsteller 7

TC_Configure (/ * clock */TC2,/ * channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC -klokke 42MHz (klokke, kanal, sammenligningsmodusinnstilling) TC_SetRC (TC2, 1, intervall); TC_Start (TC2, 1);

// aktiver timeravbrudd på timeren TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = avbryt aktiveringsregister TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = avbryt deaktiver register

NVIC_EnableIRQ (TC7_IRQn); // Aktiver avbruddet i den nestede vektoravbryterkontrollfrekvensen = 60; // initialiser frekvensen som 60Hz forhåndsinnstilt = 21; // arrayindeksøkning med 21 prøver = 256; // utdataprøver 256/syklusintervall = 42000000/(frekv*prøver); // avbryt teller TC_SetRC (TC2, 1, intervall); // start TC Serial.begin (9600); // for testformål}

ugid checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} annet

{freq = freqNy;

hvis (freq> 20000) {freq = 20000; /*maksfrekvens 20kHz*/};

hvis (freq <1) {freq = 1; /*min frekvens 1Hz*/};

hvis (frekv.> 999) {forhåndsinnstilt = 384; samples = 14;} // for frekvens> = 1kHz, 14 prøver for hver syklus

ellers hvis (frekv.> 499) {forhåndsinnstilt = 84; samples = 64;} // for 500 <= frekvens99) {forhåndsinnstilt = 42; samples = 128;} // for 100Hz <= frekvens <500Hz, 128 prøver/syklus

annet {forhåndsinnstilt = 21; prøver = 256;}; // for frekvens <100 Hz, 256 prøver for hver syklus

intervall = 42000000/(frekvens*prøver); t = 0; TC_SetRC (TC2, 1, intervall); }}

void loop () {

checkFreq (); forsinkelse (100); }

ugyldig TC7_Handler (ugyldig)

{TC_GetStatus (TC2, 1);

t = t%prøver; // bruk t%prøver for å unngå overløp av t phaseAInc = (forhåndsinnstilt*t)%5376; // bruk %5376 for å unngå overgang av matriseindeks

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // referer til PIOC: PC1 til PC8, tilsvarende Arduino Due pin: pin 33-40, derfor skift til venstre for 1 siffer

p_B = sin768 [phaseBInc] << 12; // referer til PIOC: PC12 til PC19, tilsvarende Arduino Due pin: pin 51-44, derfor skift venstre 12 siffer

p_C = sin768 [phaseCInc]; // fase C -utgang bruker PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 og PC29, tilsvarende Arduino Due pin: digital pin: 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // dette genererer PC28 og PC29

p_C3 = (p_C & B00111111) << 21; // dette genererer PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // dette genererer parallell utgang fra fase C

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

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

Anbefalt: