Բովանդակություն:

3 փուլային սինուսային ալիքի գեներատոր `հիմնված Arduino պատճառով: 5 քայլ
3 փուլային սինուսային ալիքի գեներատոր `հիմնված Arduino պատճառով: 5 քայլ

Video: 3 փուլային սինուսային ալիքի գեներատոր `հիմնված Arduino պատճառով: 5 քայլ

Video: 3 փուլային սինուսային ալիքի գեներատոր `հիմնված Arduino պատճառով: 5 քայլ
Video: Как можно сдвигать напряжение и ток 2024, Նոյեմբեր
Anonim
3 փուլային սինուսային ալիքի գեներատոր `հիմնված Arduino Due- ի վրա
3 փուլային սինուսային ալիքի գեներատոր `հիմնված Arduino Due- ի վրա

Այս բաժնեմասի նպատակն է օգնել մեկին, ով փորձում է օգտագործել Due- ի ավելի մեծ կատարումը + տեղեկանքի բացակայությունը + ոչ օգտակար տվյալների թերթիկը:

այս նախագիծը կարող է առաջացնել մինչև 3 փուլային սինուսային ալիք @ 256 նմուշ / ցիկլ ցածր հաճախականությամբ (<1 կՀց) և 16 նմուշ / ցիկլ @ բարձր հաճախականությամբ (մինչև 20 կՀց), ինչը բավական լավ է պարզ LPF- երով հարթեցնելու և ելքը գրեթե կատարյալ է:

կցված ֆայլը իմ վերջնական տարբերակը չէր, քանի որ ես ավելացրել եմ լրացուցիչ գործառույթ, բայց դրա հիմնականը նույնն է: Նկատի ունեցեք, որ նմուշները/ցիկլը սահմանվել են վերը նշված հայտարարությունից ցածր:

քանի որ պրոցեսորի հզորությունը առավելագույնի է հասցվում կցված ֆայլում ցուցադրված մոտեցման միջոցով, ես որպես կառավարման միավոր օգտագործեցի Arduino Uno- ն, որն օգտագործում է Arduino Due- ի արտաքին ընդհատումը `Arduino Due- ին հաճախականության արժեքը փոխանցելու համար: Բացի հաճախականությունների վերահսկումից, Arduino Uno- ն նաև վերահսկում է ամպլիտուդը (թվային ներուժ-մետր + OpAmp- ի միջոցով), ինչպես նաև I/O --- խաղալու շատ տեղ կլինի:

Քայլ 1. Ստեղծեք Sine Data Array

Քանի որ իրական ժամանակի հաշվարկը պահանջում է պրոցեսոր, ավելի լավ աշխատանքի համար պահանջվում է տվյալների սինուս զանգված

uint32_t sin768 PROGMEM =…. մինչդեռ x = [0: 5375]; y = 127+127*(մեղքը (2*pi/5376/*կամ ձեր նախընտրած որոշ # կախված է պահանջից*/))

Քայլ 2: Միացնել զուգահեռ ելքը

Ի տարբերություն Uno- ի, Due- ն սահմանափակ տեղեկանք ունի: Այնուամենայնիվ, Arduino Uno- ի հիման վրա եռաֆազ սինուսային ալիք առաջացնելու համար, առաջին հերթին, կատարողականությունը ծափահարելի չէ ցածր MCLK- ի պատճառով (16 ՄՀց, մինչդեռ 84 ՄՀց հաճախականությամբ), 2 -րդ, սահմանափակ GPIO- ն կարող է արտադրել առավելագույնը 2 փուլային ելք, և ձեզ լրացուցիչ անհրաժեշտ է անալոգային միացում `3-րդ փուլ արտադրելու համար (C = -AB):

GPIO- ի միացմանը հետևելը հիմնականում հիմնված էր SAM3X- ի փորձարկման և փորձարկման+ոչ օգտակար տվյալների թերթիկի վրա

PIOC-> PIO_PER = 0xFFFFFFE; // PIO վերահսկիչ PIO Միացնել գրանցամատյանը (տե՛ս ATMEL SAM3X տվյալների թերթի p656) և https://arduino.cc/hy/Hacking/PinMappingSAM3X, Arduino Due կապը 33-41 և 44-51 միացված էին

PIOC-> PIO_OER = 0xFFFFFFE; // PIO վերահսկիչի ելքի միացման գրանցամատյան, հղում կատարեք ATMEL SAM3X տվյալների թերթի p657 PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO վերահսկիչի ելքային կարգավիճակի գրանցամատյան, հղում կատարեք ATMEL SAM3X տվյալների թերթի p658- ին

PIOC-> PIO_OWER = 0xFFFFFFE; // PIO ելքի գրելու միացման գրանցամատյան, հղում կատարեք ATMEL SAM3X տվյալների թերթին p670

// PIOA-> PIO_PDR = 0x30000000; // ըստ ցանկության, որպես ապահովագրություն, կարծես չի ազդում կատարողականի վրա, թվային կապը 10 -ը միանում է և՛ PC29- ին, և՛ PA28- ին, թվային կապը 4 -ը միանում է և՛ PC29- ին, և՛ PA28- ին, այստեղ անջատելու համար անջատել PIOA #28 և 29

Քայլ 3: Միացնել ընդհատումը

Գործողությունը առավելագույնի հասցնելու համար պրոցեսորի բեռը պետք է լինի հնարավորինս ցածր: Այնուամենայնիվ, CPU- ի և Due կապի միջև ոչ 1to1 համապատասխանության պատճառով բիթերի աշխատանքը անհրաժեշտ է:

Դուք կարող եք լրացուցիչ օպտիմալացնել ալգորիթմը, բայց սենյակը շատ սահմանափակ է:

դատարկ TC7_Handler (անվավեր) {TC_GetStatus (TC2, 1);

t = t%նմուշներ; // օգտագործեք t%նմուշներ «եթե» -ի փոխարեն `t- ի վարարումից խուսափելու համար

փուլ AInc = (նախադրված*տ)%5376; // օգտագործեք %5376 ՝ զանգվածների ինդեքսի արտահոսքից խուսափելու համար

PhaseBInc = (փուլ AInc+1792)%5376;

փուլ CInc = (փուլ AInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // վերաբերում է PIOC- ին `PC1- ից PC8- ին, համապատասխան Arduino Due- ի քորոցին` կապ 33-40, հետևաբար ձախ թվի տեղաշարժ

p_B = sin768 [phaseBInc] << 12; // վերաբերում է PIOC- ին: PC12- ից PC19- ին, համապատասխան Arduino Due- ի քորոցին ՝ pin 51-44, հետևաբար ՝ ձախ 12 նիշանոց տեղաշարժ

p_C = sin768 [phaseCInc]; // փուլ C ելքային աշխատող PIOC ՝ PC21, PC22, PC23, PC24, PC25, PC26, PC28 և PC29, համապատասխան Arduino Due քորոց ՝ թվային կապ. համապատասխանաբար ՝ 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // սա առաջացնում է PC28 և PC29

p_C3 = (p_C & B00111111) << 21; // սա առաջացնում է PC21-PC26

p_C = p_C2 | p_C3; // սա առաջացնում է C փուլի զուգահեռ ելք

p_A = p_A | p_B | p_C; // 32 բիթանոց ելք = փուլ Ա (8 բիթ) | փուլ Բ | փուլ Գ

PIOC-> PIO_ODSR = p_A; // ելքային գրանցամատյան = p_A

t ++; }

Քայլ 4: R/2R DAC

կառուցեք 3x8bit R/2R DAC, Google- ում կատարվող բազմաթիվ բեռներ:

Քայլ 5: Ամբողջական ծածկագիր

#սահմանել _BV (x) (1 << (x)); uint32_t sin768 PROGMEM = /* x = [0: 5375]; y = 127+127*(մեղք (2*pi/5376))*/

uint32_t p_A, p_B, p_C, p_C2, p_C3; // փուլ A փուլ B փուլ C արժեք-չնայած ելքը միայն 8 բիթ է, p_A և p_B արժեքները գործարկվելու են ՝ նոր 32 բիթանոց արժեք ստեղծելու համար, որպեսզի կարողանանք հաղթահարել 32 բիթ PIOC ելքը

uint16_t փուլAInc, փուլBInc, փուլCInc, հաճախականություն, հաճախությունՆոր; uint32_t ընդմիջում; uint16_t նմուշներ, նախադրված; uint32_t t = 0;

void setup () {

// զուգահեռ ելքային PIOC կարգավորում. Arduino Due pin33-40 օգտագործվում են որպես A փուլ ելք, իսկ 44-51 կապը աշխատում է B փուլի ելքի համար

PIOC-> PIO_PER = 0xFFFFFFE; // PIO վերահսկիչ PIO Միացնել գրանցամատյանը (տե՛ս ATMEL SAM3X տվյալների թերթի p656) և https://arduino.cc/hy/Hacking/PinMappingSAM3X, Arduino Due կապը 33-41 և 44-51 միացված էին

PIOC-> PIO_OER = 0xFFFFFFE; // PIO վերահսկիչի ելքի միացման գրանցամատյան, հղում կատարեք ATMEL SAM3X տվյալների թերթի p657- ին

PIOC-> PIO_OSR = 0xFFFFFFE; // PIO վերահսկիչի ելքային կարգավիճակի գրանցամատյան, հղում կատարեք ATMEL SAM3X տվյալների թերթի p658- ին

PIOC-> PIO_OWER = 0xFFFFFFE; // PIO ելքի գրելու միացման գրանցամատյան, հղում կատարեք ATMEL SAM3X տվյալների թերթին p670

// PIOA-> PIO_PDR = 0x30000000; // ըստ ցանկության ապահովագրություն, կարծես չի ազդում կատարողականի վրա, թվային կապը 10 միանում է ինչպես PC29- ին, այնպես էլ PA28- ին, թվային կապը 4 -ը միանում է երկու PC29- ին և PA28- ին, այստեղ PIOA #28 & 29 // ժմչփի կարգավորումը անջատելու համար դիմեք http ՝ //arduino.cc/hy/Hacking/PinMappingSAM3X, pmc_set_writeprotect (կեղծ); // անջատել Power Management Control ռեգիստրների գրելու պաշտպանությունը

pmc_enable_periph_clk (ID_TC7); // միացնել ծայրամասային ժամացույցի ժամաչափը 7

TC_Configure (/ * ժամացույց */TC2,/ * ալիք */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC ժամացույց 42 ՄՀց (ժամացույց, ալիք, համեմատել ռեժիմի կարգավորում) TC_SetRC (TC2, 1, ընդմիջում); TC_Start (TC2, 1);

// միացնել ժամաչափի ընդհատումները ժամաչափի վրա TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = ընդհատել միացնել գրանցամատյանը TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = ընդհատել անջատել գրանցամատյանը

NVIC_EnableIRQ (TC7_IRQn); // Միացնել ընդհատումը ներկառուցված վեկտորի ընդհատումների վերահսկիչում հաճախականություն = 60; // սկզբնավորեք հաճախականությունը որպես 60Hz կանխադրված = 21; // զանգվածների ինդեքսը ավելանում է 21 նմուշով = 256; // ելքային նմուշներ 256/ցիկլի միջակայք = 42000000/(հաճախականություն*նմուշներ); // ընդհատումների հաշվարկներ TC_SetRC (TC2, 1, ընդմիջում); // սկսել TC Serial.begin (9600); // փորձարկման նպատակով}

void checkFreq ()

{հաճախականություն = 20000;

if (freq == freqNew) {} այլ

{հաճախականություն = հաճախականություն Նոր;

եթե (հաճախականություն> 20000) {հաճախականություն = 20000; /*առավելագույն հաճախականությունը 20kHz*/};

եթե (հաճախականություն <1) {հաճախականություն = 1; /*րոպե հաճախականություն 1 Հց*/};

եթե (հաճախականություն> 999) {նախադրված = 384; նմուշներ = 14;} // հաճախականության համար> = 1 կՀց, յուրաքանչյուր ցիկլի համար `14 նմուշ

այլապես եթե (հաճախականություն> 499) {նախադրված = 84; նմուշներ = 64;} // 500 -ի համար <= հաճախականությունը99) {նախադրված = 42; նմուշներ = 128;} // 100Hz- ի համար <= հաճախականություն <500Hz, 128 նմուշ/ցիկլ

else {նախադրված = 21; նմուշներ = 256;}; // հաճախականությամբ <100Hz, յուրաքանչյուր ցիկլի համար 256 նմուշ

միջակայք = 42000000/(հաճախականություն*նմուշներ); t = 0; TC_SetRC (TC2, 1, ընդմիջում); }}

դատարկ շրջան () {

checkFreq (); ուշացում (100); }

դատարկ TC7_Handler (անվավեր)

{TC_GetStatus (TC2, 1);

t = t%նմուշներ; // օգտագործել t%նմուշներ `t փուլ AInc = (կանխադրված*t)%5376 -ի արտահոսքից խուսափելու համար; // օգտագործեք %5376 ՝ զանգվածների ինդեքսի արտահոսքից խուսափելու համար

PhaseBInc = (փուլ AInc+1792)%5376;

փուլ CInc = (փուլ AInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // վերաբերում է PIOC- ին `PC1- ից PC8- ին, համապատասխան Arduino Due- ի քորոցին` 33-3-40 փին, հետևաբար ձախ թվի տեղաշարժ

p_B = sin768 [phaseBInc] << 12; // վերաբերում է PIOC- ին `PC12- ից PC19- ին, համապատասխան Arduino Due- ի քորոցին` pin 51-44, հետևաբար `ձախից 12 նիշանոց տեղաշարժ

p_C = sin768 [phaseCInc]; // փուլ C ելքային աշխատող PIOC ՝ PC21, PC22, PC23, PC24, PC25, PC26, PC28 և PC29, համապատասխան Arduino Due քորոց ՝ թվային կապ. համապատասխանաբար ՝ 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // սա առաջացնում է PC28 և PC29

p_C3 = (p_C & B00111111) << 21; // սա առաջացնում է PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // սա առաջացնում է C փուլի զուգահեռ ելք

p_A = p_A | p_B | p_C; // 32 բիթանոց ելք = փուլ Ա (8 բիթ) | փուլ Բ | փուլ Գ //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // ելքային գրանցամատյան = p_A t ++; }

Խորհուրդ ենք տալիս: