Talaan ng mga Nilalaman:

3 Phase Sine Wave Generator Batay sa Arduino Dahil: 5 Mga Hakbang
3 Phase Sine Wave Generator Batay sa Arduino Dahil: 5 Mga Hakbang

Video: 3 Phase Sine Wave Generator Batay sa Arduino Dahil: 5 Mga Hakbang

Video: 3 Phase Sine Wave Generator Batay sa Arduino Dahil: 5 Mga Hakbang
Video: Using 28BYJ-48 Stepper Motor Push button Speed with 8 projects: Ultimate Video Tutorial Lesson 107 2024, Hulyo
Anonim
3 Phase Sine Wave Generator Batay sa Arduino Dahil
3 Phase Sine Wave Generator Batay sa Arduino Dahil

ang layunin ng pagbabahagi na ito ay upang matulungan ang isang tao na sumusubok na magamit ang mas mahusay na pagganap ng Dahil + kawalan ng sanggunian + hindi kapaki-pakinabang na datasheet.

ang proyektong ito ay nakakabuo ng hanggang sa 3 yugto ng sine wave @ 256 na mga sample / cycle sa mababang freq (<1kHz) at 16 na mga sample / cycle @ high freq (hanggang sa 20kHz), na sapat na mahusay upang mapakinis ng mga simpleng LPF at ng ang output ay halos perpekto.

ang naka-attach na file ay hindi ang aking huling bersyon para sa nagdagdag ako ng ilang karagdagang tampok ngunit ang core ay pareho sa na. Tandaan na ang mga sample / ikot ay itinakda mas mababa kaysa sa itaas na pahayag.

dahil ang kapasidad ng CPU ay na-maximize sa pamamagitan ng diskarte na ipinapakita sa naka-attach na file, ginamit ko ang isang Arduino Uno bilang control unit, na gumagamit ng panlabas na abala ng Arduino Dahil upang maipasa ang halaga ng dalas sa Arduino Dahil. Bilang karagdagan sa kontrol sa dalas, kinokontrol din ng Arduino Uno ang amplitude (sa pamamagitan ng digital potensyal na meter + OpAmp) pati na rin ang I / O --- magkakaroon ng maraming silid upang mapaglaro.

Hakbang 1: Bumuo ng Sine Data Array

Dahil ang pagkalkula ng real-time ay hinihingi ng CPU, kinakailangan ang isang array ng data para sa mas mahusay na pagganap

uint32_t sin768 PROGMEM =….habang x = [0: 5375]; y = 127 + 127 * (kasalanan (2 * pi / 5376 / * o ilang # na gusto mong depende sa kinakailangan * /))

Hakbang 2: Pagpapagana ng Parallel Output

Hindi tulad ng Uno, Dahil ay may limitadong sanggunian. Gayunpaman upang makabuo ng 3 phase sine wave batay sa Arduino Uno, una sa lahat, ang pagganap ay hindi maipapakita dahil sa mababang MCLK (16MHz habang Dahil ay 84MHz), ika-2, limitado ang GPIO ay maaaring makabuo ng max 2 phase output at kailangan mo ng karagdagang analogue circuit upang makabuo ng ika-3 yugto (C = -AB).

Ang pagsunod sa pagpapagana ng GPIO ay halos batay sa pagsubok at pagsubok + hindi kapaki-pakinabang na datasheet ng SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO controller PIO Paganahin ang pagrehistro (sumangguni sa p656 ng ATMEL SAM3X datasheet) at https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Dahil pin 33-41 at 44-51 ay pinagana

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO output output paganahin ang magparehistro, sumangguni sa p657 ng ATMEL SAM3X datasheet PIOC-> PIO_OSR = 0xFFFFFFFE; // Rehistro ng katayuan ng output ng PIO controller, mag-refer sa p658 ng ATMEL SAM3X datasheet

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO output magsulat paganahin ang magparehistro, sumangguni sa p670 ng ATMEL SAM3X datasheet

// PIOA-> PIO_PDR = 0x30000000; // opsyonal bilang seguro, tila hindi makakaapekto sa pagganap, digital pin 10 kumonekta sa parehong PC29 at PA28, digital pin 4 kumonekta sa parehong PC29 at PA28, dito upang hindi paganahin ang disable PIOA # 28 & 29

Hakbang 3: Paganahin ang Makagambala

Upang ma-maximize ang pagganap nito, ang CPU load ay dapat na mas mababa hangga't maaari. Gayunpaman dahil sa hindi pagsulat ng di-1to1 sa pagitan ng CPU pin at ng Dahil pin, kinakailangan ang kaunting operasyon.

Maaari mo pang i-optimize ang algorithm ngunit ang silid ay napaka-limitado.

walang bisa TC7_Handler (walang bisa) {TC_GetStatus (TC2, 1);

t = t% mga sample; // use t% sample instead of 'if' upang maiwasan ang overflow ng t

phaseAInc = (preset * t)% 5376; // use% 5376 upang maiwasan ang pag-overflow ng array index

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // refer to PIOC: PC1 to PC8, nararapat na Arduino Dahil pin: pin 33-40, samakatuwid shift kaliwa para sa 1 digit

p_B = sin768 [phaseBInc] << 12; // refer to PIOC: PC12 to PC19, nararapat na Arduino Dahil pin: pin 51-44, samakatuwid shift kaliwa 12 digit

p_C = sin768 [phaseCInc]; // phase C output gamitin ang PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 at PC29, kaukulang Arduino Dahil pin: digital pin: 9, 8, 7, 6, 5, 4, 3, 10, ayon sa pagkakabanggit

p_C2 = (p_C & B11000000) << 22; // bumubuo ito ng PC28 at PC29

p_C3 = (p_C & B00111111) << 21; // bumubuo ito ng PC21-PC26

p_C = p_C2 | p_C3; // nagbubuo ito ng parallel output ng phase C

p_A = p_A | p_B | p_C; // 32 bit output = phase A (8bit) | phase B | phase C

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

t ++; }

Hakbang 4: R / 2R DAC

bumuo ng 3x8bit R / 2R DAC, maraming mga ref sa google.

Hakbang 5: Buong Code

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

uint32_t p_A, p_B, p_C, p_C2, p_C3; // phase A phase B phase C phase C - kahit na ang output ay 8bits lamang, ang p_A at p_B na halaga ay tatakbo upang makabuo ng isang bagong 32 bit na halaga upang makaya ang output ng 32bit PIOC

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; agwat ng uint32_t; mga sample na uint16_t, preset; uint32_t t = 0;

walang bisa ang pag-setup () {

// parallel output PIOC setup: Arduino Dahil pin33-40 ay nagtatrabaho bilang phase A output habang ang pin 44-51 ay gumagana para sa phase B output

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO controller PIO Paganahin ang pagrehistro (sumangguni sa p656 ng ATMEL SAM3X datasheet) at https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Dahil pin 33-41 at 44-51 ay pinagana

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO output output paganahin ang magparehistro, sumangguni sa p657 ng ATMEL SAM3X datasheet

PIOC-> PIO_OSR = 0xFFFFFFFE; // Rehistro ng katayuan ng output ng PIO controller, mag-refer sa p658 ng ATMEL SAM3X datasheet

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO output magsulat paganahin ang magparehistro, sumangguni sa p670 ng ATMEL SAM3X datasheet

// PIOA-> PIO_PDR = 0x30000000; // opsyonal bilang seguro, tila hindi nakakaapekto sa pagganap, digital pin 10 kumonekta sa parehong PC29 at PA28, digital pin 4 kumonekta sa parehong PC29 at PA28, dito upang hindi paganahin ang hindi paganahin ng PIOA # 28 & 29 // timer setup, sumangguni sa https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (false); // huwag paganahin ang proteksyon ng pagsusulat ng mga rehistro ng Power Management Control

pmc_enable_periph_clk (ID_TC7); // paganahin ang paligid ng orasan ng oras counter 7

TC_Configure (/ * orasan * / TC2, / * channel * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC relo 42MHz (orasan, channel, ihambing ang setting ng mode) TC_SetRC (TC2, 1, agwat); TC_Start (TC2, 1);

// paganahin ang nakakagambala ng timer sa timer TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = makagambala paganahin ang pagrehistro TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = makagambala disable register

NVIC_EnableIRQ (TC7_IRQn); // Paganahin ang abala sa naka-punong vector makagambala controller freq = 60; // initialize frequency as 60Hz preset = 21; // pagtaas ng index ng array ng 21 mga sample = 256; // output sample 256 / cycle interval = 42000000 / (freq * sample); // interrupt count TC_SetRC (TC2, 1, interval); // start TC Serial.begin (9600); // para sa layunin ng pagsubok}

walang bisa ang checkFreq ()

{freqNew = 20000;

kung (freq == freqNew) {} iba pa

{freq = freqNew;

kung (freq> 20000) {freq = 20000; / * max dalas 20kHz * /};

kung (freq <1) {freq = 1; / * min na dalas ng 1Hz * /};

kung (freq> 999) {preset = 384; mga sample = 14;} // para sa dalas> = 1kHz, 14 na mga sample para sa bawat pag-ikot

kung hindi man (freq> 499) {preset = 84; mga sample = 64;} // para sa 500 <= frequency99) {preset = 42; mga sample = 128;} // para sa 100Hz <= dalas <500Hz, 128 mga sample / ikot

kung hindi man {preset = 21; mga sample = 256;}; // para sa dalas <100hz, 256 na mga sample para sa bawat pag-ikot

agwat = 42000000 / (mga freq * na sample); t = 0; TC_SetRC (TC2, 1, agwat); }}

void loop () {

checkFreq (); pagkaantala (100); }

walang bisa TC7_Handler (walang bisa)

{TC_GetStatus (TC2, 1);

t = t% mga sample; // use t% sample to avoild overflow of t phaseAInc = (preset * t)% 5376; // use% 5376 upang maiwasan ang pag-overflow ng array index

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // refer to PIOC: PC1 to PC8, nararapat na Arduino Dahil pin: pin 33-40, samakatuwid shift kaliwa para sa 1 digit

p_B = sin768 [phaseBInc] << 12; // refer to PIOC: PC12 to PC19, nararapat na Arduino Dahil pin: pin 51-44, samakatuwid shift kaliwa 12 digit

p_C = sin768 [phaseCInc]; // phase C output gamitin ang PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 at PC29, kaukulang Arduino Dahil pin: digital pin: 9, 8, 7, 6, 5, 4, 3, 10, ayon sa pagkakabanggit

p_C2 = (p_C & B11000000) << 22; // bumubuo ito ng PC28 at PC29

p_C3 = (p_C & B00111111) << 21; // ito ay bumubuo ng PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // nagbubuo ito ng parallel output ng phase C

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

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

Inirerekumendang: