Tabla de contenido:
- Paso 1: generar una matriz de datos sinusoidal
- Paso 2: Habilitación de la salida en paralelo
- Paso 3: Habilitación de la interrupción
- Paso 4: R / 2R DAC
- Paso 5: Código completo
Video: Generador de onda sinusoidal trifásica basado en Arduino Due: 5 pasos
2024 Autor: John Day | [email protected]. Última modificación: 2024-01-30 08:42
el propósito de este recurso compartido es ayudar a alguien que está tratando de utilizar el mayor rendimiento de Due + falta de referencia + hoja de datos no útil.
Este proyecto es capaz de generar hasta una onda sinusoidal trifásica a 256 muestras / ciclo a baja frecuencia (<1kHz) y 16 muestras / ciclo a alta frecuencia (hasta 20kHz), lo cual es lo suficientemente bueno para ser suavizado por LPF simples y el la salida es casi perfecta.
el archivo adjunto no era mi versión final porque agregué alguna característica adicional, pero el núcleo es el mismo. Tenga en cuenta que las muestras / ciclo se establecieron por debajo de la declaración anterior.
Dado que la capacidad de la CPU se maximiza a través del enfoque que se muestra en el archivo adjunto, utilicé un Arduino Uno como unidad de control, que utiliza la interrupción externa de Arduino Due para pasar el valor de frecuencia a Arduino Due. Además del control de frecuencia, el Arduino Uno también controla la amplitud (a través del medidor de potencial digital + OpAmp) así como la E / S; habrá mucho espacio para jugar.
Paso 1: generar una matriz de datos sinusoidal
Dado que el cálculo en tiempo real es exigente para la CPU, se requiere una matriz de datos sinusoidal para un mejor rendimiento
uint32_t sin768 PROGMEM =….mientras que x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * o algún # que prefiera depende del requisito * /))
Paso 2: Habilitación de la salida en paralelo
A diferencia de Uno, Due tienen una referencia limitada. Sin embargo, para generar una onda sinusoidal trifásica basada en Arduino Uno, en primer lugar, el rendimiento no es aceptable debido a su bajo MCLK (16MHz mientras que Due es 84MHz), segundo, su GPIO limitado puede producir una salida máxima de 2 fases y necesita más circuito analógico para producir la 3ª fase (C = -AB).
La siguiente habilitación de GPIO se basó principalmente en prueba y prueba + hoja de datos no útil de SAM3X
PIOC-> PIO_PER = 0xFFFFFFFE; // Controlador PIO PIO Enable register (consulte la p656 de la hoja de datos ATMEL SAM3X) y https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 y 44-51 fueron habilitados
PIOC-> PIO_OER = 0xFFFFFFFE; // Registro de habilitación de salida del controlador PIO, consulte la p657 de la hoja de datos ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Registro de estado de salida del controlador PIO, consulte la p658 de la hoja de datos ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Registro de habilitación de escritura de salida PIO, consulte la p670 de la hoja de datos ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // opcional como seguro, no parece afectar el rendimiento, el pin digital 10 se conecta a PC29 y PA28, el pin digital 4 se conecta a PC29 y PA28, aquí para deshabilitar deshabilitar PIOA # 28 y 29
Paso 3: Habilitación de la interrupción
Para maximizar su rendimiento, la carga de la CPU debe ser lo más baja posible. Sin embargo, debido a la correspondencia no 1 a 1 entre el pin de la CPU y el pin Due, la operación de bits es necesaria.
Puede optimizar aún más el algoritmo, pero el espacio es muy limitado.
anular TC7_Handler (anular) {TC_GetStatus (TC2, 1);
t = t% de muestras; // use t% samples en lugar de 'if' para evitar el desbordamiento de t
PhaseAInc = (preestablecido * t)% 5376; // use% 5376 para evitar el desbordamiento del índice de la matriz
faseBInc = (faseAInc + 1792)% 5376;
faseCInc = (faseAInc + 3584)% 5376;
p_A = sin768 [phaseAInc] << 1; // consulte PIOC: PC1 a PC8, pin correspondiente de Arduino Due: pin 33-40, por lo tanto, cambie a la izquierda para 1 dígito
p_B = sin768 [faseBInc] << 12; // consulte PIOC: PC12 a PC19, pin correspondiente de Arduino Due: pin 51-44, por lo tanto, cambie a la izquierda 12 dígitos
p_C = sin768 [phaseCInc]; // empleo de salida de fase C PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 y PC29, correspondiente pin Arduino Due: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, respectivamente
p_C2 = (p_C & B11000000) << 22; // esto genera PC28 y PC29
p_C3 = (p_C & B00111111) << 21; // esto genera PC21-PC26
p_C = p_C2 | p_C3; // esto genera una salida en paralelo de la fase C
p_A = p_A | p_B | p_C; // Salida de 32 bits = fase A (8 bits) | fase B | fase C
PIOC-> PIO_ODSR = p_A; // registro de salida = p_A
t ++; }
Paso 4: R / 2R DAC
construya 3x8bit R / 2R DAC, un montón de referencias en google.
Paso 5: Código completo
#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 fase B valor de fase C - aunque las salidas son solo de 8 bits, los valores p_A y p_B se operarán para generar un nuevo valor de 32 bits con el fin de copiar con la salida PIOC de 32 bits
uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; intervalo uint32_t; uint16_t samples, preset; uint32_t t = 0;
configuración vacía () {
// Configuración de PIOC de salida paralela: los pines 33-40 de Arduino Due se emplean como salida de fase A mientras que el pin 44-51 funciona para la salida de fase B
PIOC-> PIO_PER = 0xFFFFFFFE; // Controlador PIO PIO Enable register (consulte la p656 de la hoja de datos ATMEL SAM3X) y https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 y 44-51 fueron habilitados
PIOC-> PIO_OER = 0xFFFFFFFE; // Registro de habilitación de salida del controlador PIO, consulte la p657 de la hoja de datos ATMEL SAM3X
PIOC-> PIO_OSR = 0xFFFFFFFE; // Registro de estado de salida del controlador PIO, consulte la p658 de la hoja de datos ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Registro de habilitación de escritura de salida PIO, consulte la p670 de la hoja de datos de ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // opcional como seguro, no parece afectar el rendimiento, el pin digital 10 se conecta a PC29 y PA28, el pin digital 4 se conecta a PC29 y PA28, aquí para deshabilitar deshabilitar PIOA # 28 y 29 // configuración del temporizador, consulte https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (falso); // deshabilitar la protección contra escritura de los registros de control de administración de energía
pmc_enable_periph_clk (ID_TC7); // habilitar el contador de tiempo del reloj periférico 7
TC_Configure (/ * reloj * / TC2, / * canal * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Reloj TC 42MHz (reloj, canal, ajuste de modo de comparación) TC_SetRC (TC2, 1, intervalo); TC_Start (TC2, 1);
// habilita las interrupciones del temporizador en el temporizador TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = registro de habilitación de interrupciones TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = registro de desactivación de interrupciones
NVIC_EnableIRQ (TC7_IRQn); // Habilita la interrupción en el controlador de interrupciones vectoriales anidado freq = 60; // inicializar la frecuencia como preajuste de 60Hz = 21; // aumento del índice de la matriz en 21 muestras = 256; // muestras de salida 256 / intervalo de ciclo = 42000000 / (frecuencia * muestras); // interrupción cuenta TC_SetRC (TC2, 1, intervalo); // iniciar TC Serial.begin (9600); // con fines de prueba}
void checkFreq ()
{freqNew = 20000;
if (freq == freqNew) {} más
{freq = freqNew;
si (frecuencia> 20000) {frecuencia = 20000; / * frecuencia máxima 20 kHz * /};
si (frecuencia <1) {frecuencia = 1; / * frecuencia mínima 1Hz * /};
if (freq> 999) {preset = 384; samples = 14;} // para frecuencia> = 1kHz, 14 muestras para cada ciclo
else if (freq> 499) {preset = 84; samples = 64;} // para 500 <= frecuencia99) {preset = 42; samples = 128;} // para 100Hz <= frecuencia <500Hz, 128 muestras / ciclo
else {preset = 21; muestras = 256;}; // para frecuencia <100 hz, 256 muestras para cada ciclo
intervalo = 42000000 / (frecuencia * muestras); t = 0; TC_SetRC (TC2, 1, intervalo); }}
bucle vacío () {
checkFreq (); retraso (100); }
vacío TC7_Handler (vacío)
{TC_GetStatus (TC2, 1);
t = t% de muestras; // use t% samples para evitar el desbordamiento de t phaseAInc = (preset * t)% 5376; // use% 5376 para evitar el desbordamiento del índice de la matriz
faseBInc = (faseAInc + 1792)% 5376;
faseCInc = (faseAInc + 3584)% 5376;
p_A = sin768 [phaseAInc] << 1; // consulte PIOC: PC1 a PC8, pin correspondiente de Arduino Due: pin 33-40, por lo tanto, cambie a la izquierda para 1 dígito
p_B = sin768 [faseBInc] << 12; // consulte PIOC: PC12 a PC19, pin correspondiente de Arduino Due: pin 51-44, por lo tanto, mueva 12 dígitos a la izquierda
p_C = sin768 [phaseCInc]; // empleo de salida de fase C PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 y PC29, correspondiente pin Arduino Due: pin digital: 9, 8, 7, 6, 5, 4, 3, 10, respectivamente
p_C2 = (p_C & B11000000) << 22; // esto genera PC28 y PC29
p_C3 = (p_C & B00111111) << 21; // esto genera PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // esto genera una salida en paralelo de la fase C
p_A = p_A | p_B | p_C; // Salida 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; // registro de salida = p_A t ++; }
Recomendado:
Inversor de onda sinusoidal pura: 8 pasos
Inversor de onda sinusoidal pura: mi investigación
Producción de la placa de control de onda sinusoidal: 5 pasos
Producción de la placa de control de onda sinusoidal: esta vez es una placa de control fuera de la red de onda sinusoidal monofásica, seguida de una placa de control fuera de la red de onda sinusoidal monofásica, luego una placa de control fuera de la red de onda sinusoidal trifásica, y finalmente un tablero de control sin conexión a la red de onda sinusoidal trifásica. Esperamos que
Generador de formas de onda Arduino: 5 pasos (con imágenes)
Generador de forma de onda Arduino: actualización de febrero de 2021: consulte la nueva versión con 300 veces la frecuencia de muestreo, basada en Raspberry Pi Pico En el laboratorio, a menudo se necesita una señal repetitiva de cierta frecuencia, forma y amplitud. Puede ser para probar un amplificador, comprobar un circuito
Generador de música basado en el clima (generador Midi basado en ESP8266): 4 pasos (con imágenes)
Generador de música basado en el clima (Generador Midi basado en ESP8266): Hola, hoy explicaré cómo hacer tu propio generador de música basado en el clima. Está basado en un ESP8266, que es como un Arduino, y responde a la temperatura, la lluvia y la intensidad de la luz. No espere que haga canciones completas o programas de acordes
Haz un circuito NE555 para generar una onda sinusoidal: 6 pasos
Haz un circuito NE555 para generar una onda sinusoidal: este tutorial te enseña cómo hacer un circuito NE555 para generar una onda sinusoidal. Estos asequibles kits de bricolaje son muy útiles para que comprenda cómo pueden funcionar los condensadores con resistencias para controlar el tiempo de carga y descarga que generará