Taula de continguts:

Generador d'ona sinusoïdal de 3 fases basat en Arduino Due: 5 passos
Generador d'ona sinusoïdal de 3 fases basat en Arduino Due: 5 passos

Vídeo: Generador d'ona sinusoïdal de 3 fases basat en Arduino Due: 5 passos

Vídeo: Generador d'ona sinusoïdal de 3 fases basat en Arduino Due: 5 passos
Vídeo: Output DC or AC Voltage using MCP4725 DAC with LCD and PWM to Voltage Converter with Arduino 2024, Juliol
Anonim
Generador d'ona sinusoïdal de 3 fases basat en Arduino Due
Generador d'ona sinusoïdal de 3 fases basat en Arduino Due

el propòsit d’aquest recurs és ajudar algú que intenta utilitzar el major rendiment de Due + manca de referència + full de dades poc útil.

aquest projecte és capaç de generar fins a ona sinusoïdal de 3 fases @ 256 mostres / cicle a freq baixa (<1 kHz) i 16 mostres / cicle @ freq alta (fins a 20 kHz), que és prou bo per ser suavitzat per LPF senzills i la sortida és gairebé perfecta.

l'arxiu adjunt no era la meva versió final, ja que vaig afegir alguna característica addicional, però el nucli és el mateix. Tingueu en compte que les mostres / cicle es van establir per sota de l’afirmació anterior.

ja que la capacitat de la CPU es maximitza mitjançant l'enfocament que es mostra al fitxer adjunt, he utilitzat un Arduino Uno com a unitat de control, que utilitza la interrupció externa d'Arduino Due per passar el valor de la freqüència a Arduino Due. A més del control de freqüència, l'Arduino Uno també controla l'amplitud (mitjançant un mesurador de potencial digital + OpAmp), així com les E / S --- hi haurà molt espai per jugar.

Pas 1: generar matriu de dades sinus

Atès que el càlcul en temps real requereix CPU, es necessita una matriu de dades sinusoïdals per obtenir un millor rendiment

uint32_t sin768 PROGMEM = …. mentre x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * o algun # que preferiu depèn del requisit * /))

Pas 2: habilitar la sortida paral·lela

A diferència de l’Uno, Due té una referència limitada. Tanmateix, per generar ona sinusoïdal de 3 fases basada en Arduino Uno, primer, el rendiment no és aplaudible a causa del seu baix MCLK (16 MHz mentre que Due és de 84 MHz); circuit analògic per produir la 3a fase (C = -AB).

El seguiment de l'activació de GPIO es va basar principalment en proves i proves i no en un full de dades útil de SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE; // Registre d’activació del controlador PIO (consulteu la p656 del full de dades ATMEL SAM3X) i https://arduino.cc/en/Hacking/PinMappingSAM3X, s’han habilitat els pins 33-41 i 44-51 d’Arduino Due

PIOC-> PIO_OER = 0xFFFFFFFE; // Registre d'activació de sortida del controlador PIO, consulteu la p657 del full de dades ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Registre d'estat de sortida del controlador PIO, consulteu la p658 del full de dades ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registre d’habilitació d’escriptura de sortida PIO, consulteu la p670 del full de dades ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opcional com a assegurança, sembla que no afecta el rendiment, el pin digital 10 es connecta tant a PC29 com a PA28, el pin digital 4 es connecta tant a PC29 com a PA28, aquí per desactivar desactivar PIOA # 28 i 29

Pas 3: habilitar la interrupció

Per maximitzar el seu rendiment, la càrrega de la CPU ha de ser el més baixa possible. Tanmateix, a causa de la correspondència no 1to1 entre el pin de la CPU i el pin Due, és necessària una operació de bits.

Podeu optimitzar encara més l'algorisme, però la sala és molt limitada.

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

t = t% mostres; // utilitzeu t% samples en lloc de "if" per evitar el desbordament de t

phaseAInc = (predefinit * t)% 5376; // utilitzeu% 5376 per evitar el desbordament d'índexs de matriu

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // Consulteu PIOC: PC1 a PC8, corresponent pin Arduino Due: pin 33-40, per tant, canvieu a l'esquerra per 1 dígit

p_B = sin768 [phaseBInc] << 12; // Consulteu PIOC: PC12 a PC19, corresponent pin Arduino Due: pin 51-44, per tant, canvieu 12 dígits a l'esquerra

p_C = sin768 [phaseCInc]; // sortida de fase C que utilitza PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 i PC29, corresponent pin Arduino Due: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, respectivament

p_C2 = (p_C & B11000000) << 22; // això genera PC28 i PC29

p_C3 = (p_C & B00111111) << 21; // això genera PC21-PC26

p_C = p_C2 | p_C3; // això genera una sortida paral·lela de la fase C.

p_A = p_A | p_B | p_C; // sortida de 32 bits = fase A (8 bits) | fase B | fase C

PIOC-> PIO_ODSR = p_A; // registre de sortida = p_A

t ++; }

Pas 4: R / 2R DAC

construir 3x8bit R / 2R DAC, un munt de ref a google.

Pas 5: codi complet

#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 valor de fase B de fase C - tot i que la sortida només és de 8 bits, el valor de p_A i p_B s’operarà per generar un nou valor de 32 bits per poder fer front a la sortida PIOC de 32 bits

uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNou; interval uint32_t; uint16_t mostres, predefinides; uint32_t t = 0;

configuració nul·la () {

// Configuració PIOC de sortida paral·lela: el pin33-40 d'Arduino Due s'utilitza com a sortida de fase A mentre el pin 44-51 funciona per a la sortida de fase B

PIOC-> PIO_PER = 0xFFFFFFFE; // Registre PIO Enable controlador PIO (consulteu la p656 del full de dades ATMEL SAM3X) i https://arduino.cc/en/Hacking/PinMappingSAM3X, s'han activat els pins 33-41 i 44-51 d'Arduino Due.

PIOC-> PIO_OER = 0xFFFFFFFE; // Registre d'activació de sortida del controlador PIO, consulteu la p657 del full de dades ATMEL SAM3X

PIOC-> PIO_OSR = 0xFFFFFFFE; // Registre d'estat de sortida del controlador PIO, consulteu la p658 del full de dades ATMEL SAM3X

PIOC-> PIO_OWER = 0xFFFFFFFE; // Registre d’habilitació d’escriptura de sortida PIO, consulteu la p670 del full de dades ATMEL SAM3X

// PIOA-> PIO_PDR = 0x30000000; // opcional com a assegurança, no sembla que afecti el rendiment, el pin digital 10 es connecta tant a PC29 com a PA28, el pin digital 4 es connecta tant a PC29 com a PA28, aquí per desactivar la configuració del temporitzador PIOA # 28 i 29 //, consulteu https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (fals); // desactiva la protecció d'escriptura dels registres de control de gestió d'energia

pmc_enable_periph_clk (ID_TC7); // habilitar el comptador de temps del rellotge perifèric 7

TC_Configure (/ * clock * / TC2, / * channel * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Rellotge TC de 42 MHz (rellotge, canal, configuració del mode de comparació) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);

// habilita les interrupcions del temporitzador al temporitzador TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = registre d'activació d'interrupcions TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = registre de desactivació de la interrupció

NVIC_EnableIRQ (TC7_IRQn); // Activeu la interrupció al controlador d’interrupcions vector niu freq = 60; // inicialitzar la freqüència com a 60Hz preset = 21; // augment de l’índex de matriu en 21 mostres = 256; // mostres de sortida 256 / interval de cicle = 42000000 / (mostres freq *); // compte d’interrupcions TC_SetRC (TC2, 1, interval); // iniciar TC Serial.begin (9600); // amb finalitats de prova}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNou) {} més

{freq = freqNou;

if (freq> 20000) {freq = 20000; / * freqüència màxima 20 kHz * /};

if (freq <1) {freq = 1; / * freqüència mínima 1Hz * /};

if (freq> 999) {preset = 384; mostres = 14;} // per freqüència> = 1 kHz, 14 mostres per cada cicle

else if (freq> 499) {preset = 84; samples = 64;} // per 500 <= freqüència99) {preset = 42; mostres = 128;} // per a 100Hz <= freqüència <500Hz, 128 mostres / cicle

else {preset = 21; mostres = 256;}; // per freqüència <100hz, 256 mostres per a cada cicle

interval = 42000000 / (freq * samples); t = 0; TC_SetRC (TC2, 1, interval); }}

bucle buit () {

checkFreq (); retard (100); }

buit TC7_Handler (buit)

{TC_GetStatus (TC2, 1);

t = t% mostres; // utilitzeu t% samples per evitar el desbordament de t phaseAInc = (preestablert * t)% 5376; // utilitzeu% 5376 per evitar el desbordament d'índexs de matriu

phaseBInc = (phaseAInc + 1792)% 5376;

phaseCInc = (phaseAInc + 3584)% 5376;

p_A = sin768 [phaseAInc] << 1; // Consulteu PIOC: PC1 a PC8, corresponent pin Arduino Due: pin 33-40, per tant, canvieu a l'esquerra per 1 dígit

p_B = sin768 [phaseBInc] << 12; // Consulteu PIOC: PC12 a PC19, corresponent pin Arduino Due: pin 51-44, per tant, canvieu 12 dígits a l'esquerra

p_C = sin768 [phaseCInc]; // sortida de fase C que utilitza PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 i PC29, corresponent pin Arduino Due: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, respectivament

p_C2 = (p_C & B11000000) << 22; // això genera PC28 i PC29

p_C3 = (p_C & B00111111) << 21; // això genera PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // això genera una sortida paral·lela de la fase C.

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

PIOC-> PIO_ODSR = p_A; // registre de sortida = p_A t ++; }

Recomanat: