Daftar Isi:

Generator Gelombang Sinus 3 Fasa Berbasis Arduino Karena: 5 Langkah
Generator Gelombang Sinus 3 Fasa Berbasis Arduino Karena: 5 Langkah

Video: Generator Gelombang Sinus 3 Fasa Berbasis Arduino Karena: 5 Langkah

Video: Generator Gelombang Sinus 3 Fasa Berbasis Arduino Karena: 5 Langkah
Video: DIY Arduino inverter 3 Phase. part 2 2024, Juli
Anonim
Generator Gelombang Sinus 3 Fasa Berbasis Arduino Due
Generator Gelombang Sinus 3 Fasa Berbasis Arduino Due

tujuan pembagian ini adalah untuk membantu seseorang yang mencoba memanfaatkan kinerja Due yang lebih baik + kurangnya referensi + lembar data yang tidak membantu.

proyek ini mampu menghasilkan hingga 3 fase gelombang sinus @ 256 sampel / siklus pada frekuensi rendah (<1kHz) dan 16 sampel/siklus @ frekuensi tinggi (hingga 20kHz), yang cukup baik untuk dihaluskan oleh LPF sederhana dan keluarannya hampir sempurna.

file terlampir bukan versi final saya karena saya menambahkan beberapa fitur tambahan tetapi intinya sama dengan itu. Perhatikan sampel/siklus ditetapkan lebih rendah dari pernyataan di atas.

karena kapasitas CPU dimaksimalkan melalui pendekatan yang ditunjukkan pada file terlampir, saya menggunakan Arduino Uno sebagai unit kontrol, yang memanfaatkan interupsi eksternal Arduino Due untuk meneruskan nilai frekuensi ke Arduino Due. Selain kontrol frekuensi, Arduino Uno juga mengontrol amplitudo (melalui pengukur potensial digital + OpAmp) serta I/O --- akan ada banyak ruang untuk dimainkan.

Langkah 1: Hasilkan Array Data Sinus

Karena perhitungan waktu nyata menuntut CPU, array data sinus diperlukan untuk kinerja yang lebih baik

uint32_t sin768 PROGMEM= ….sementara x=[0:5375]; y = 127+127*(sin(2*pi/5376/*atau # yang Anda inginkan tergantung pada kebutuhan*/))

Langkah 2: Mengaktifkan Output Paralel

Tidak seperti Uno, Due memiliki referensi terbatas. Namun untuk menghasilkan gelombang sinus 3 fase berdasarkan Arduino Uno, pertama-tama, kinerjanya tidak bagus karena MCLK-nya yang rendah (16MHz sedangkan Due adalah 84MHz), kedua, GPIO terbatas dapat menghasilkan output maksimal 2 fase dan Anda memerlukan tambahan rangkaian analog untuk menghasilkan fasa ke-3 (C=-AB).

Mengikuti pengaktifan GPIO sebagian besar didasarkan pada coba dan coba + lembar data SAM3X yang tidak membantu

PIOC->PIO_PER = 0xFFFFFFFE; // Kontroler PIO PIO Aktifkan register (lihat p656 lembar data ATMEL SAM3X) dan https://arduino.cc/en/Hacking/PinMappingSAM3X, pin Arduino Due 33-41 dan 44-51 diaktifkan

PIOC->PIO_OER = 0xFFFFFFFE; // register aktifkan keluaran pengontrol PIO, lihat p657 lembar data ATMEL SAM3X PIOC->PIO_OSR = 0xFFFFFFFE; // register status keluaran pengontrol PIO, lihat p658 lembar data ATMEL SAM3X

PIOC->PIO_OWER = 0xFFFFFFFE; // register aktifkan penulisan keluaran PIO, lihat p670 lembar data ATMEL SAM3X

//PIOA->PIO_PDR = 0x30000000; // opsional sebagai asuransi, tampaknya tidak mempengaruhi kinerja, pin digital 10 terhubung ke PC29 dan PA28, pin digital 4 terhubung ke PC29 dan PA28, di sini untuk menonaktifkan menonaktifkan PIOA #28 & 29

Langkah 3: Mengaktifkan Interupsi

Untuk memaksimalkan kinerjanya, beban CPU harus serendah mungkin. Namun karena korespondensi non-1to1 antara pin CPU dan pin Due, operasi bit diperlukan.

Anda dapat lebih mengoptimalkan algoritme tetapi ruangannya sangat terbatas.

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

t = t%sampel; //gunakan t%sampel alih-alih 'jika' untuk menghindari luapan t

phaseAInc = (preset*t)%5376; //gunakan %5376 untuk menghindari indeks array meluap

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768[phaseAInc]<<1; // lihat PIOC: PC1 ke PC8, sesuai Arduino Due pin: pin 33-40, maka geser ke kiri untuk 1 digit

p_B = sin768[phaseBInc]<<12; // lihat PIOC: PC12 ke PC19, sesuai Arduino Due pin: pin 51-44, maka geser ke kiri 12 digit

p_C = sin768[phaseCInc]; //fase C output karyawan PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 dan PC29, sesuai Arduino Due pin: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, masing-masing

p_C2 = (p_C&B11000000)<<22; //ini menghasilkan PC28 dan PC29

p_C3 = (p_C&B00111111)<<21; //ini menghasilkan PC21-PC26

p_C = p_C2|p_C3; //ini menghasilkan output paralel fase C

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

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

t++; }

Langkah 4: R/2R DAC

membangun 3x8bit R/2R DAC, banyak referensi di google.

Langkah 5: Kode Lengkap

#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 nilai fase B fase C--meskipun output hanya 8bit, nilai p_A dan p_B akan dioperasikan untuk menghasilkan nilai 32 bit baru untuk mengatasi output PIOC 32bit

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; interval uint32_t; sampel uint16_t, prasetel; uint32_t t = 0;

batalkan pengaturan() {

// pengaturan PIOC output paralel: Arduino Due pin33-40 digunakan sebagai output fase A sementara pin 44-51 berfungsi untuk output fase B

PIOC->PIO_PER = 0xFFFFFFFE; // Kontroler PIO PIO Aktifkan register (lihat p656 lembar data ATMEL SAM3X) dan https://arduino.cc/en/Hacking/PinMappingSAM3X, pin Arduino Due 33-41 dan 44-51 diaktifkan

PIOC->PIO_OER = 0xFFFFFFFE; // register aktifkan keluaran pengontrol PIO, lihat p657 lembar data ATMEL SAM3X

PIOC->PIO_OSR = 0xFFFFFFFE; // register status keluaran pengontrol PIO, lihat p658 lembar data ATMEL SAM3X

PIOC->PIO_OWER = 0xFFFFFFFE; // register aktifkan penulisan keluaran PIO, lihat p670 lembar data ATMEL SAM3X

//PIOA->PIO_PDR = 0x30000000; // opsional sebagai asuransi, tampaknya tidak mempengaruhi kinerja, pin digital 10 terhubung ke PC29 dan PA28, pin digital 4 terhubung ke PC29 dan PA28, di sini untuk menonaktifkan menonaktifkan PIOA #28 & 29 // pengaturan timer, lihat https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect(salah); // nonaktifkan proteksi tulis register Kontrol Manajemen Daya

pmc_enable_periph_clk(ID_TC7); // aktifkan penghitung waktu jam periferal 7

TC_Configure(/* jam */TC2, /* saluran */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); //TC jam 42MHz (jam, saluran, bandingkan pengaturan mode) TC_SetRC(TC2, 1, interval); TC_Mulai(TC2, 1);

// mengaktifkan interupsi timer pada timer TC2->TC_CHANNEL[1]. TC_IER=TC_IER_CPCS; // IER = interupsi aktifkan register TC2->TC_CHANNEL[1]. TC_IDR=~TC_IER_CPCS; // IDR = interupsi nonaktifkan register

NVIC_EnableIRQ(TC7_IRQn); // Aktifkan interupsi di pengontrol interupsi vektor bersarang freq = 60; //inisialisasi frekuensi sebagai preset 60Hz = 21; //indeks array meningkat sebanyak 21 sampel = 256; //output sampel 256/siklus interval = 42000000/(freq*sampel); //interrupt menghitung TC_SetRC(TC2, 1, interval); //mulai TC Serial.begin(9600); //untuk tujuan tes }

batal checkFreq()

{ freqBaru = 20000;

if (freq == freqNew) {} else

{ frekuensi = frekuensiBaru;

if (frekuensi>20000) {frekuensi = 20000; /*frekuensi maksimum 20kHz*/};

if (frekuensi<1) {frekuensi = 1; /*frekuensi min 1Hz*/};

if (frekuensi>999) {preset = 384; sampel = 14;} //untuk frekuensi >=1kHz, 14 sampel untuk setiap siklus

else if (frekuensi>499) {preset = 84; sampel = 64;} //untuk 500<=frekuensi99) {preset = 42; sampel = 128;} //untuk 100Hz<=frekuensi<500Hz, 128 sampel/siklus

lain {preset = 21; sampel = 256;}; //untuk frekuensi<100hz, 256 sampel untuk setiap siklus

interval = 42000000/(frekuensi*sampel); t = 0; TC_SetRC(TC2, 1, interval); } }

lingkaran kosong() {

checkFreq(); penundaan(100); }

batal TC7_Handler(batal)

{ TC_GetStatus(TC2, 1);

t = t%sampel; //gunakan t%sampel untuk menghindari luapan t phaseAInc = (preset*t)%5376; //gunakan %5376 untuk menghindari indeks array meluap

phaseBInc = (phaseAInc+1792)%5376;

phaseCInc = (phaseAInc+3584)%5376;

p_A = sin768[phaseAInc]<<1; // lihat PIOC: PC1 ke PC8, sesuai Arduino Due pin: pin 33-40, maka geser ke kiri untuk 1 digit

p_B = sin768[phaseBInc]<<12; // lihat PIOC: PC12 ke PC19, sesuai Arduino Due pin: pin 51-44, maka geser ke kiri 12 digit

p_C = sin768[phaseCInc]; //fase C output karyawan PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 dan PC29, sesuai Arduino Due pin: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, masing-masing

p_C2 = (p_C&B11000000)<<22; //ini menghasilkan PC28 dan PC29

p_C3 = (p_C&B00111111)<<21; //ini menghasilkan PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2|p_C3; //ini menghasilkan output paralel fase C

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

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

Direkomendasikan: