Πίνακας περιεχομένων:

3 Phase Sine Wave Generator Βασισμένο στο Arduino due: 5 βήματα
3 Phase Sine Wave Generator Βασισμένο στο Arduino due: 5 βήματα

Βίντεο: 3 Phase Sine Wave Generator Βασισμένο στο Arduino due: 5 βήματα

Βίντεο: 3 Phase Sine Wave Generator Βασισμένο στο Arduino due: 5 βήματα
Βίντεο: How Three Phase Electricity works - The basics explained 2024, Ιούλιος
Anonim
3 Phase Sine Wave Generator Βασισμένο στο Arduino Due
3 Phase Sine Wave Generator Βασισμένο στο Arduino Due

ο σκοπός αυτού του μεριδίου είναι να βοηθήσει κάποιον που προσπαθεί να χρησιμοποιήσει τη μεγαλύτερη απόδοση του Due + έλλειψη αναφοράς + μη βοηθητικό φύλλο δεδομένων.

αυτό το έργο είναι σε θέση να παράγει έως 3 φάσεις ημιτονοειδές κύμα @ 256 δείγματα / κύκλο σε χαμηλή συχνότητα (<1kHz) και 16 δείγματα / κύκλο @ υψηλή συχνότητα (έως 20kHz), το οποίο είναι αρκετά καλό για να εξομαλυνθεί με απλά LPF και η έξοδος είναι σχεδόν τέλεια.

το συνημμένο αρχείο δεν ήταν η τελική μου έκδοση γιατί πρόσθεσα κάποια επιπλέον δυνατότητα αλλά ο πυρήνας είναι ο ίδιος σε αυτό. Σημειώστε ότι τα δείγματα/κύκλος ορίστηκαν χαμηλότερα από την παραπάνω δήλωση.

δεδομένου ότι η χωρητικότητα της CPU μεγιστοποιείται μέσω της προσέγγισης που φαίνεται στο συνημμένο αρχείο, χρησιμοποίησα ένα Arduino Uno ως μονάδα ελέγχου, το οποίο χρησιμοποιεί την εξωτερική διακοπή του Arduino Due για να περάσει την τιμή συχνότητας στο Arduino Due. Εκτός από τον έλεγχο συχνότητας, το Arduino Uno ελέγχει επίσης το εύρος (μέσω ψηφιακού μετρητή δυναμικού + OpAmp) καθώς και I/O --- θα υπάρχει πολύς χώρος για παιχνίδι.

Βήμα 1: Δημιουργήστε πίνακα δεδομένων Sine Data

Δεδομένου ότι ο υπολογισμός σε πραγματικό χρόνο απαιτεί CPU, απαιτείται μια συστοιχία δεδομένων για καλύτερη απόδοση

uint32_t sin768 PROGMEM =…. ενω x = [0: 5375]; y = 127+127*(αμαρτία (2*pi/5376/*ή κάποια # που προτιμάτε εξαρτάται από την απαίτηση*/))

Βήμα 2: Ενεργοποίηση παράλληλης εξόδου

Σε αντίθεση με το Uno, το Due έχει περιορισμένη αναφορά. Ωστόσο, για να δημιουργήσει ημιτονοειδές κύμα 3 φάσεων με βάση το Arduino Uno, πρώτον, η απόδοση δεν είναι επιδοκιμαστική λόγω του χαμηλού MCLK (16MHz ενώ το Due είναι 84MHz), δεύτερον, ο περιορισμένος GPIO μπορεί να παράγει έως 2 φάσεις εξόδου και χρειάζεστε επιπλέον αναλογικό κύκλωμα για την παραγωγή της 3ης φάσης (C = -AB).

Η ενεργοποίηση του GPIO βασίστηκε κυρίως σε δοκιμή και δοκιμή+μη χρήσιμο φύλλο δεδομένων του SAM3X

PIOC-> PIO_PER = 0xFFFFFFE; // PIO controller PIO Enable register (ανατρέξτε στο p656 του φύλλου δεδομένων ATMEL SAM3X) και https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 και 44-51 ήταν ενεργοποιημένα

PIOC-> PIO_OER = 0xFFFFFFE; // Έλεγχος εξόδου ελεγκτή PIO καταχωρητής, ανατρέξτε στο p657 του φύλλου δεδομένων ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Καταχωρητής κατάστασης εξόδου ελεγκτή PIO, ανατρέξτε στο p658 του φύλλου δεδομένων ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFE; // Έξοδος PIO εγγραφής εγγραφής ενεργοποίησης, ανατρέξτε στο p670 του φύλλου δεδομένων ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // προαιρετικά ως ασφάλιση, δεν φαίνεται να επηρεάζει την απόδοση, ο ψηφιακός ακροδέκτης 10 συνδέεται τόσο με το PC29 όσο και με το PA28, ο ψηφιακός ακροδέκτης 4 συνδέεται τόσο με το PC29 όσο και με το PA28, εδώ για να απενεργοποιήσετε την απενεργοποίηση του PIOA #28 & 29

Βήμα 3: Ενεργοποίηση διακοπής

Για να μεγιστοποιήσετε την απόδοσή του, το φορτίο της CPU πρέπει να είναι όσο το δυνατόν χαμηλότερο. Ωστόσο, λόγω της αντιστοιχίας μεταξύ 1 και 1 μεταξύ του ακροδέκτη CPU και του πείρου Due, είναι απαραίτητη η λειτουργία bit.

Μπορείτε να βελτιστοποιήσετε περαιτέρω τον αλγόριθμο, αλλά ο χώρος είναι πολύ περιορισμένος.

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

t = t%δείγματα. // χρησιμοποιήστε δείγματα t%αντί για "εάν" για να αποφύγετε την υπερχείλιση του t

phaseAInc = (προεπιλογή*t)%5376; // χρησιμοποιήστε το %5376 για να αποφύγετε την υπερχείλιση του δείκτη πίνακα

φάσηBInc = (φάσηAInc+1792)%5376;

φάσηCInc = (φάσηAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // ανατρέξτε στο PIOC: PC1 σε PC8, αντίστοιχο Arduino Due pin: pin 33-40, επομένως μετατοπίστε αριστερά για 1 ψηφίο

p_B = sin768 [phaseBInc] << 12; // ανατρέξτε στο PIOC: PC12 σε PC19, αντίστοιχο Arduino Due pin: pin 51-44, επομένως μετατοπίστε αριστερά 12 ψηφία

p_C = sin768 [phaseCInc]; // έξοδος φάσης Γ υπάλληλος 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; // αυτό παράγει παράλληλη έξοδο της φάσης Γ

p_A = p_A | p_B | p_C; // Έξοδος 32 bit = φάση A (8bit) | φάση B | φάση C

PIOC-> PIO_ODSR = p_A; // καταχωρητής εξόδου = p_A

t ++; }

Βήμα 4: R/2R DAC

δημιουργία 3x8bit R/2R DAC, πολλά φορτία στο google.

Βήμα 5: Πλήρης κωδικός

#define _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; // φάση Α φάση Β τιμή φάσης Γ-αν και η έξοδος είναι μόνο 8 bit, η τιμή p_A και p_B θα λειτουργήσει για να δημιουργήσει μια νέα τιμή 32 bit για να αντιμετωπίσει την έξοδο PIOC 32bit

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; διάστημα uint32_t; δείγματα uint16_t, προκαθορισμένα. uint32_t t = 0;

void setup () {

// παράλληλη έξοδος ρύθμισης PIOC: Το Arduino Due pin33-40 χρησιμοποιείται ως έξοδος φάσης Α ενώ ο πείρος 44-51 λειτουργεί για έξοδο φάσης Β

PIOC-> PIO_PER = 0xFFFFFFE; // PIO controller PIO Enable register (ανατρέξτε στο p656 του φύλλου δεδομένων ATMEL SAM3X) και https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 και 44-51 ήταν ενεργοποιημένα

PIOC-> PIO_OER = 0xFFFFFFE; // Καταχωρητής ενεργοποίησης εξόδου ελεγκτή PIO, ανατρέξτε στο p657 του φύλλου δεδομένων ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFE; // Καταχωρητής κατάστασης εξόδου ελεγκτή PIO, ανατρέξτε στο p658 του φύλλου δεδομένων ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFE; // Έξοδος PIO εγγραφής εγγραφής ενεργοποίησης, ανατρέξτε στο p670 του φύλλου δεδομένων ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // προαιρετικά ως ασφάλιση, δεν φαίνεται να επηρεάζει την απόδοση, ο ψηφιακός ακροδέκτης 10 συνδέεται τόσο με το PC29 όσο και με το PA28, ο ψηφιακός ακροδέκτης 4 συνδέεται τόσο με το PC29 όσο και με το PA28, εδώ για να απενεργοποιήσετε την απενεργοποίηση της ρύθμισης του χρονοδιακόπτη PIOA #28 & 29 //, ανατρέξτε στο https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (false); // απενεργοποίηση προστασίας εγγραφής μητρώων ελέγχου διαχείρισης ενέργειας

pmc_enable_periph_clk (ID_TC7); // ενεργοποίηση μετρητή χρόνου περιφερειακού ρολογιού 7

TC_Configure (/ * clock */TC2,/ * channel */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Ρολόι TC 42MHz (ρολόι, κανάλι, ρύθμιση λειτουργίας σύγκρισης) 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); // Ενεργοποιήστε τη διακοπή στον ένθετο φορέα ελεγκτή διακοπής freq = 60; // αρχικοποιήστε τη συχνότητα ως προεπιλογή 60Hz = 21; // δείκτης πίνακα αύξηση κατά 21 δείγματα = 256; // δείγματα εξόδου 256/διάστημα κύκλου = 42000000/(δείγματα συχνότητας*). // μετράει διακοπή TC_SetRC (TC2, 1, διάστημα); // εκκίνηση TC Serial.begin (9600); // για δοκιμαστικό σκοπό}

void checkFreq ()

{freqNew = 20000;

εάν (freq == freqNew) {} άλλο

{freq = freqNew;

εάν (συχνότητα> 20000) {freq = 20000; /*μέγιστη συχνότητα 20kHz*/};

if (freq <1) {freq = 1; /*min συχνότητα 1Hz*/};

εάν (συχνότητα> 999) {προεπιλογή = 384; δείγματα = 14;} // για συχνότητα> = 1kHz, 14 δείγματα για κάθε κύκλο

αλλιώς εάν (συχνότητα> 499) {προεπιλογή = 84; δείγματα = 64;} // για 500 <= συχνότητα99) {προεπιλογή = 42; δείγματα = 128;} // για 100Hz <= συχνότητα <500Hz, 128 δείγματα/κύκλος

else {preset = 21; δείγματα = 256;}; // για συχνότητα <100hz, 256 δείγματα για κάθε κύκλο

διάστημα = 42000000/(συχνότητα*δείγματα); t = 0; TC_SetRC (TC2, 1, διάστημα); }}

void loop () {

checkFreq (); καθυστέρηση (100)? }

κενό TC7_Handler (άκυρο)

{TC_GetStatus (TC2, 1);

t = t%δείγματα. // χρησιμοποιήστε δείγματα t%για την αποφυγή υπερχείλισης της φάσης tAInc = (προεπιλογή*t)%5376; // χρησιμοποιήστε το %5376 για να αποφύγετε την υπερχείλιση του δείκτη πίνακα

φάσηBInc = (φάσηAInc+1792)%5376;

φάσηCInc = (φάσηAInc+3584)%5376;

p_A = sin768 [phaseAInc] << 1; // ανατρέξτε στο PIOC: PC1 σε PC8, αντίστοιχο Arduino Due pin: pin 33-40, επομένως μετατοπίστε αριστερά για 1 ψηφίο

p_B = sin768 [phaseBInc] << 12; // ανατρέξτε στο PIOC: PC12 σε PC19, αντίστοιχο Arduino Due pin: pin 51-44, επομένως μετατοπίστε αριστερά 12 ψηφία

p_C = sin768 [phaseCInc]; // έξοδος φάσης Γ υπάλληλος 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; // αυτό παράγει παράλληλη έξοδο της φάσης Γ

p_A = p_A | p_B | p_C; // Έξοδος 32 bit = φάση A (8bit) | φάση B | φάση C //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // καταχωρητής εξόδου = p_A t ++; }

Συνιστάται: