Penjana Gelombang Sinus 3 Fasa Berdasarkan Arduino Due: 5 Langkah
Penjana Gelombang Sinus 3 Fasa Berdasarkan Arduino Due: 5 Langkah
Anonim
Penjana Gelombang Sinus 3 Fasa Berdasarkan Arduino Due
Penjana Gelombang Sinus 3 Fasa Berdasarkan Arduino Due

tujuan perkongsian ini adalah untuk membantu seseorang yang berusaha memanfaatkan prestasi yang lebih baik + kekurangan rujukan + lembar data yang tidak bermanfaat.

projek ini mampu menghasilkan gelombang sinus hingga 3 fasa @ 256 sampel / kitaran pada frekuensi rendah (<1kHz) dan 16 sampel / kitaran @ frekuensi tinggi (hingga 20kHz), yang cukup baik untuk dilancarkan oleh LPF sederhana dan output hampir sempurna.

fail yang dilampirkan bukan versi terakhir saya kerana saya menambah beberapa ciri tambahan tetapi intinya sama dengan itu. Perhatikan sampel / kitaran ditetapkan lebih rendah daripada pernyataan di atas.

kerana kapasiti CPU dimaksimumkan melalui pendekatan yang ditunjukkan dalam file terlampir, saya menggunakan Arduino Uno sebagai unit kontrol, yang menggunakan gangguan luaran Arduino Due untuk menyampaikan nilai frekuensi ke Arduino Due. Sebagai tambahan kepada kawalan frekuensi, Arduino Uno juga mengawal amplitud (melalui digital-meter + OpAmp) serta I / O --- akan ada banyak ruang untuk dimainkan.

Langkah 1: Hasilkan Array Data Sine

Oleh kerana pengiraan masa nyata memerlukan CPU, susunan data sinus diperlukan untuk prestasi yang lebih baik

uint32_t sin768 PROGMEM =…. sementara x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * atau beberapa # yang anda sukai bergantung pada keperluan * /))

Langkah 2: Mengaktifkan Hasil Selari

Tidak seperti Uno, Due mempunyai rujukan terhad. Walau bagaimanapun untuk menghasilkan gelombang sinus 3 fasa berdasarkan Arduino Uno, pertama, prestasi tidak dapat diterima kerana MCLK yang rendah (16MHz sementara Due adalah 84MHz), ke-2, GPIO terhad dapat menghasilkan output 2 fasa maksimum dan anda memerlukan tambahan litar analog untuk menghasilkan fasa ke-3 (C = -AB).

Mengikuti pengaktifan GPIO kebanyakannya berdasarkan percubaan dan lembaran data SAM3X yang tidak berguna

PIOC-> PIO_PER = 0xFFFFFFFE; // Pengawal PIO PIO Aktifkan daftar (rujuk 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; // Output pengawal PIO membolehkan daftar, rujuk p657 lembar data ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Daftar status output pengawal PIO, rujuk p658 lembaran data ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO output write allow register, rujuk p670 ATMEL SAM3X datasheet

// PIOA-> PIO_PDR = 0x30000000; // pilihan sebagai insurans, nampaknya tidak mempengaruhi prestasi, pin digital 10 menyambung ke kedua PC29 dan PA28, pin digital 4 bersambung ke kedua PC29 dan PA28, di sini untuk melumpuhkan PIOA # 28 & 29

Langkah 3: Mengaktifkan Gangguan

Untuk memaksimumkan kinerjanya, beban CPU harus serendah mungkin. Tetapi kerana korespondensi bukan 1to1 antara pin CPU dan pin Due, operasi bit diperlukan.

Anda boleh mengoptimumkan algoritma lebih lanjut tetapi ruangannya sangat terhad.

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

t = t% sampel; // gunakan t% sampel dan bukannya 'if' untuk mengelakkan limpahan t

phaseAInc = (pratetap * t)% 5376; // gunakan% 5376 untuk mengelakkan limpahan indeks array

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // rujuk PIOC: PC1 ke PC8, pin Arduino Due yang sesuai: pin 33-40, oleh itu beralih ke kiri selama 1 digit

p_B = sin768 [phaseBInc] << 12; // rujuk PIOC: PC12 ke PC19, pin Arduino Due yang sesuai: pin 51-44, oleh itu beralih ke kiri 12 digit

p_C = sin768 [phaseCInc]; // keluaran fasa C menggunakan 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 selari fasa C

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

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

t ++; }

Langkah 4: R / 2R DAC

membina 3x8bit R / 2R DAC, banyak ref di google.

Langkah 5: Kod Penuh

#tentukan _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; // fasa A fasa B fasa C - walaupun output hanya 8 bit, nilai p_A dan p_B akan dikendalikan untuk menghasilkan nilai 32 bit baru untuk mengatasi output PIOC 32bit

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; selang uint32_t; uint16_t sampel, pratetap; uint32_t t = 0;

batal persediaan () {

// output selari PIOC setup: Arduino Due pin33-40 digunakan sebagai output fasa A sementara pin 44-51 berfungsi untuk output fasa B

PIOC-> PIO_PER = 0xFFFFFFFE; // Pengawal PIO PIO Aktifkan daftar (rujuk 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; // Keluaran pengawal PIO membolehkan daftar, rujuk p657 lembaran data ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Daftar status output pengawal PIO, rujuk p658 lembaran data ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO output write allow register, rujuk p670 lembaran data ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // pilihan sebagai insurans, nampaknya tidak mempengaruhi prestasi, pin digital 10 menyambung ke kedua PC29 dan PA28, pin digital 4 menyambung ke kedua PC29 dan PA28, di sini untuk melumpuhkan penyahaktifan penyediaan pemasa PIOA # 28 & 29 //, rujuk https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (palsu); // lumpuhkan perlindungan tulis daftar Kawalan Pengurusan Kuasa

pmc_enable_periph_clk (ID_TC7); // aktifkan pembilang masa jam persisian 7

TC_Configure (/ * clock * / TC2, / * channel * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Jam TC 42MHz (jam, saluran, tetapan mod perbandingan) TC_SetRC (TC2, 1, selang); TC_Start (TC2, 1);

// aktifkan gangguan pemasa pada pemasa TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = interrupt aktifkan register TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = gangguan mematikan daftar

NVIC_EnableIRQ (TC7_IRQn); // Aktifkan gangguan dalam pengendali interrupt vektor bersarang freq = 60; // mulakan frekuensi sebagai pratetap 60Hz = 21; // indeks array meningkat sebanyak 21 sampel = 256; // sampel output 256 / selang kitaran = 42000000 / (freq * sampel); // bilangan gangguan TC_SetRC (TC2, 1, selang); // mulakan TC Serial.begin (9600); // untuk tujuan ujian}

semakan tidak sahFreq ()

{freqNew = 20000;

jika (freq == freqBaru) {} yang lain

{freq = freqBaru;

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

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

jika (freq> 999) {pratetap = 384; sampel = 14;} // untuk frekuensi> = 1kHz, 14 sampel untuk setiap kitaran

lain jika (freq> 499) {pratetap = 84; sampel = 64;} // untuk 500 <= frekuensi99) {pratetap = 42; sampel = 128;} // untuk 100Hz <= frekuensi <500Hz, 128 sampel / kitaran

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

selang = 42000000 / (freq * sampel); t = 0; TC_SetRC (TC2, 1, selang); }}

gelung kosong () {

semakFreq (); kelewatan (100); }

batal TC7_Handler (tidak sah)

{TC_GetStatus (TC2, 1);

t = t% sampel; // gunakan sampel t% untuk mengelakkan limpahan t phaseAInc = (pratetap * t)% 5376; // gunakan% 5376 untuk mengelakkan limpahan indeks array

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // rujuk PIOC: PC1 ke PC8, pin Arduino Due yang sesuai: pin 33-40, oleh itu beralih ke kiri selama 1 digit

p_B = sin768 [phaseBInc] << 12; // rujuk PIOC: PC12 ke PC19, pin Arduino Due yang sesuai: pin 51-44, oleh itu beralih ke kiri 12 digit

p_C = sin768 [phaseCInc]; // keluaran fasa C menggunakan PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 dan PC29, sepadan dengan pin Arduino Due: 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 selari fasa C

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

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

Disyorkan: