Mündəricat:

Arduino Due əsasında 3 fazalı sinus dalğa generatoru: 5 addım
Arduino Due əsasında 3 fazalı sinus dalğa generatoru: 5 addım

Video: Arduino Due əsasında 3 fazalı sinus dalğa generatoru: 5 addım

Video: Arduino Due əsasında 3 fazalı sinus dalğa generatoru: 5 addım
Video: Output DC or AC Voltage using MCP4725 DAC with LCD and PWM to Voltage Converter with Arduino 2024, Noyabr
Anonim
Arduino Due əsasında 3 fazalı sinus dalğa generatoru
Arduino Due əsasında 3 fazalı sinus dalğa generatoru

Bu paylaşımın məqsədi, Due-nin daha yüksək performansı + istinadın olmaması + faydalı olmayan məlumat cədvəlindən istifadə etməyə çalışan birinə kömək etməkdir.

Bu layihə, sadə LPF və çıxış demək olar ki, mükəmməldir.

əlavə fayl əlavə etdiyim üçün son versiyam deyildi, amma nüvəsi buna bənzəyir. Nümunələrin/dövrünün yuxarıdakı ifadədən daha aşağı olduğunu unutmayın.

Əlavə edilmiş faylda göstərilən yanaşma ilə CPU tutumu maksimuma çatdığından, Arduino Due -yə tezlik dəyərini ötürmək üçün Arduino Due xarici kəsilməsindən istifadə edən bir idarəetmə vahidi olaraq bir Arduino Uno istifadə etdim. Arduino Uno tezlik nəzarətinə əlavə olaraq amplitüdünü (rəqəmsal potensial sayğac + OpAmp vasitəsilə) və I/O ilə də idarə edir-oynamaq üçün çox yer olacaq.

Addım 1: Sinüs Məlumat Dizisi yaradın

Real vaxt hesablaması CPU tələb etdiyi üçün daha yaxşı performans üçün bir sinüs məlumat dizisi tələb olunur

uint32_t sin768 PROGMEM =….xam x = [0: 5375]; y = 127+127*(günah (2*pi/5376/*və ya istədiyiniz # # tələbdən asılıdır)/))

Addım 2: Paralel Çıxışın Aktivləşdirilməsi

Uno -dan fərqli olaraq Due məhdud istinadlara malikdir. Ancaq Arduino Uno -ya əsaslanan 3 fazalı sinus dalğası yaratmaq üçün, ilk növbədə, aşağı MCLK (16 MHz, 84 MHz ikən) səbəbiylə performans alqışlanmır, 2 -ci, məhdud GPIO maksimum 2 fazlı çıxış istehsal edə bilər və əlavə ehtiyacınız var 3-cü fazanı istehsal etmək üçün analoq dövrə (C = -AB).

GPIO -nun aktivləşdirilməsi əsasən SAM3X -in faydalı məlumat cədvəlinə+yoxlanılmasına əsaslanır

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO nəzarətçisi PIO Aktivləşdirmə reyestri (ATMEL SAM3X məlumat cədvəlinin p656-ya baxın) və https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 və 44-51 aktiv edildi

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO nəzarətçi çıxışı aktivləşdirmə reyestri, ATMEL SAM3X məlumat cədvəlinin p657-ə baxın PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO nəzarətçi çıxış vəziyyəti reyestri, ATMEL SAM3X məlumat cədvəlinin p658 -ə baxın

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO çıxışı yazma aktivləşdirmə reyestri, ATMEL SAM3X məlumat cədvəlinin p670 -ə baxın

// PIOA-> PIO_PDR = 0x30000000; // sığorta olaraq isteğe bağlı, performansa təsir göstərmir, rəqəmsal pin 10 həm PC29, həm də PA28 -ə, rəqəmsal pin 4 həm PC29, həm də PA28 -ə qoşulur, burada PIOA #28 və 29 -u deaktiv etmək üçün

Addım 3: Kəsmə funksiyasını aktivləşdirin

Performansını artırmaq üçün CPU yükü mümkün qədər aşağı olmalıdır. Ancaq CPU pin və Due pin arasındakı 1to1 olmayan yazışmalara görə bit əməliyyatı lazımdır.

Alqoritmi daha da optimallaşdıra bilərsiniz, ancaq otaq çox məhduddur.

boş TC7_Handler (boş) {TC_GetStatus (TC2, 1);

t = t%nümunələr; // t -nin daşmaması üçün 'if' yerinə t%nümunələrindən istifadə edin

fazAInc = (əvvəlcədən təyin edilmiş*t)%5376; // sıra indeksinin daşmasının qarşısını almaq üçün %5376 istifadə edin

PhaseBInc = (PhaseAInc+1792)%5376;

PhaseCInc = (PhaseAInc+3584)%5376;

p_A = sin768 [fazAAnc] << 1; // PIOC-a baxın: PC1-dən PC8-ə, uyğun Arduino Due pin: pin 33-40, buna görə sola 1 rəqəmə keçin

p_B = sin768 [PhaseBInc] << 12; // PIOC-a baxın: PC12-dən PC19-a, uyğun Arduino Due pin: pin 51-44, buna görə sola 12 rəqəm

p_C = sin768 [fazaCInc]; // faza C çıxışı PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 və PC29, müvafiq Arduino Due pin: rəqəmsal pin: müvafiq olaraq 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // bu PC28 və PC29 yaradır

p_C3 = (p_C & B00111111) << 21; // bu PC21-PC26 yaradır

p_C = p_C2 | p_C3; // bu, C fazının paralel çıxışı yaradır

p_A = p_A | p_B | p_C; // 32 bit çıxış = faza A (8bit) | faza B | faza

PIOC-> PIO_ODSR = p_A; // çıxış reyestri = p_A

t ++; }

Addım 4: R/2R DAC

3x8bit R/2R DAC qurun, google -da çoxlu ref.

Addım 5: Tam Kod

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

uint32_t p_A, p_B, p_C, p_C2, p_C3; // faza A fazası B fazası C dəyəri-çıxış yalnız 8 bit olsa da, 32 bit PIOC çıxışı ilə mübarizə aparmaq üçün yeni 32 bitlik dəyər yaratmaq üçün p_A və p_B dəyəri işlədiləcək.

uint16_t PhaseAInc, PhaseBInc, PhaseCInc, Freq, FreqNew; uint32_t aralığı; uint16_t nümunələri, əvvəlcədən təyin edilmiş; uint32_t t = 0;

boş quraşdırma () {

// paralel çıxış PIOC qurğusu: Arduino Due pin33-40, faza çıxışı olaraq, pin 44-51 isə B fazası üçün işləyir

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO nəzarətçisi PIO Aktivləşdirmə reyestri (ATMEL SAM3X məlumat cədvəlinin p656-ya baxın) və https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 və 44-51 aktiv edildi

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO nəzarətçi çıxışı aktivləşdirmə reyestri, ATMEL SAM3X məlumat cədvəlinin p657 -ə baxın

PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO nəzarətçi çıxış vəziyyəti reyestri, ATMEL SAM3X məlumat cədvəlinin p658 -ə baxın

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO çıxışı yazma aktivləşdirmə reyestri, ATMEL SAM3X məlumat cədvəlinin p670 -ə baxın

// PIOA-> PIO_PDR = 0x30000000; // sığorta olaraq isteğe bağlı, performansa təsir etmədiyi görünür, rəqəmsal pin 10 həm PC29, həm də PA28 -ə qoşulur, rəqəmsal pin 4 həm PC29, həm də PA28 -ə qoşulur, burada PIOA #28 və 29 -u deaktiv etmək üçün https://www.: //arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (yanlış); // Güc İdarəetmə İdarəetmə qeydlərinin yazma qorunmasını deaktiv edin

pmc_enable_periph_clk (ID_TC7); // periferik saat sayğacını aktivləşdir 7

TC_Configure (/ * saat */TC2,/ * kanal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC saatı 42MHz (saat, kanal, müqayisə rejimi ayarı) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// timer TC2-> TC_CHANNEL [1] üzərində timer fasilələrini aktivləşdirin. TC_IER = TC_IER_CPCS; // IER = kəsmə aktivləşdirmə reyestri TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = reyestri kəsmək

NVIC_EnableIRQ (TC7_IRQn); // Daxili vektor kəsmə nəzarətçisindəki kəsilməni aktiv edin freq = 60; // tezliyi 60Hz əvvəlcədən təyin edilmiş = 21 olaraq işə salın; // sıra indeksi 21 nümunə artımı = 256; // çıxış nümunələri 256/dövr aralığı = 42000000/(freq*nümunələr); // kəsmə sayları TC_SetRC (TC2, 1, interval); // start TC Serial.begin (9600); // test məqsədi ilə}

void checkFreq ()

{freqNew = 20000;

əgər (freq == freqYeni) {} başqa

{freq = freqNew;

əgər (freq> 20000) {freq = 20000; /*maksimum tezlik 20kHz*/};

əgər (freq <1) {freq = 1; /*dəq tezliyi 1Hz*/};

əgər (freq> 999) {əvvəlcədən təyin edilmiş = 384; nümunələr = 14;} // tezlik üçün> = 1kHz, hər dövr üçün 14 nümunə

else if (freq> 499) {preset = 84; nümunələr = 64;} // 500 üçün <= tezlik99) {əvvəlcədən təyin edilmiş = 42; nümunələr = 128;} // 100Hz üçün <= tezlik <500Hz, 128 nümunə/dövr

başqa {əvvəlcədən təyin edilmiş = 21; nümunələr = 256;}; // 100 hz tezlik üçün, hər dövr üçün 256 nümunə

interval = 42000000/(tezlik*nümunələri); t = 0; TC_SetRC (TC2, 1, interval); }}

boşluq döngəsi () {

checkFreq (); gecikmə (100); }

boş TC7_Handler (boş)

{TC_GetStatus (TC2, 1);

t = t%nümunələr; // t fazAInc = (əvvəlcədən təyin edilmiş*t)%5376 -nın daşmasının qarşısını almaq üçün t%nümunələrindən istifadə edin; // sıra indeksinin daşmasının qarşısını almaq üçün %5376 istifadə edin

PhaseBInc = (PhaseAInc+1792)%5376;

PhaseCInc = (PhaseAInc+3584)%5376;

p_A = sin768 [fazAAnc] << 1; // PIOC-a baxın: PC1-dən PC8-ə, müvafiq Arduino Due pin: pin 33-40, buna görə də 1 rəqəm üçün sola keçin

p_B = sin768 [PhaseBInc] << 12; // PIOC-a baxın: PC12-dən PC19-a, uyğun Arduino Due pin: pin 51-44, buna görə sola 12 rəqəm

p_C = sin768 [fazaCInc]; // faza C çıxışı PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 və PC29, müvafiq Arduino Due pin: rəqəmsal pin: müvafiq olaraq 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C & B11000000) << 22; // bu PC28 və PC29 yaradır

p_C3 = (p_C & B00111111) << 21; // bu PC21-PC26 //Serial.println(p_C3, BIN) yaradır; p_C = p_C2 | p_C3; // bu, C fazının paralel çıxışı yaradır

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

PIOC-> PIO_ODSR = p_A; // çıxış reyestri = p_A t ++; }

Tövsiyə: