Índice:
- Etapa 1: Gerar matriz de dados senoidal
- Etapa 2: Habilitando a saída paralela
- Etapa 3: Habilitando a interrupção
- Etapa 4: R / 2R DAC
- Etapa 5: Código Completo
Vídeo: Gerador de onda senoidal trifásico baseado no Arduino Prazo: 5 etapas
2024 Autor: John Day | [email protected]. Última modificação: 2024-01-30 11:37
o objetivo deste compartilhamento é ajudar alguém que está tentando utilizar o melhor desempenho do Due + falta de referência + folha de dados não útil.
este projeto é capaz de gerar até onda senoidal trifásica @ 256 amostras / ciclo em baixa frequência (<1kHz) e 16 amostras / ciclo @ alta frequência (até 20kHz), o que é bom o suficiente para ser suavizado por LPFs simples e o a saída é quase perfeita.
o arquivo anexado não era minha versão final, pois adicionei alguns recursos adicionais, mas o núcleo é o mesmo. Observe que as amostras / ciclo foram definidas abaixo da declaração acima.
como a capacidade da CPU é maximizada por meio da abordagem mostrada no arquivo anexado, usei um Arduino Uno como unidade de controle, que utiliza a interrupção externa do Arduino Due para passar o valor da frequência para o Arduino Due. Além do controle de frequência, o Arduino Uno também controla a amplitude (por meio do medidor de potencial digital + OpAmp), bem como I / O --- haverá muito espaço para brincar.
Etapa 1: Gerar matriz de dados senoidal
Uma vez que o cálculo em tempo real exige muito da CPU, uma matriz de dados senoidal é necessária para um melhor desempenho
uint32_t sin768 PROGMEM =….enquanto x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * ou algum # que você preferir depende do requisito * /))
Etapa 2: Habilitando a saída paralela
Ao contrário de Uno, Due tem referência limitada. No entanto, a fim de gerar onda senoidal trifásica com base no Arduino Uno, primeiro de tudo, o desempenho não é aplicável devido ao seu baixo MCLK (16 MHz enquanto o vencimento é de 84 MHz), segundo, seu GPIO limitado pode produzir saída máxima de 2 fases e você precisa de mais circuito analógico para produzir a 3ª fase (C = -AB).
A ativação do GPIO seguinte baseou-se principalmente na tentativa e teste + folha de dados não útil de SAM3X
PIOC-> PIO_PER = 0xFFFFFFFE; // PIO controlador PIO Enable register (consulte a p656 da folha de dados ATMEL SAM3X) e https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pino 33-41 e 44-51 foram habilitados
PIOC-> PIO_OER = 0xFFFFFFFE; // Registro de habilitação de saída do controlador PIO, consulte a p657 da folha de dados ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Registro de status de saída do controlador PIO, consulte a p658 da folha de dados ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Registro de habilitação de gravação de saída PIO, consulte a p670 da folha de dados ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // opcional como seguro, não parece afetar o desempenho, o pino digital 10 conecta-se ao PC29 e ao PA28, o pino digital 4 conecta-se ao PC29 e ao PA28, aqui para desativar desabilitar PIOA # 28 e 29
Etapa 3: Habilitando a interrupção
Para maximizar seu desempenho, a carga da CPU deve ser a mais baixa possível. No entanto, devido à correspondência não 1to1 entre o pino da CPU e o pino Devido, a operação do bit é necessária.
Você pode otimizar ainda mais o algoritmo, mas a sala é muito limitada.
vazio TC7_Handler (vazio) {TC_GetStatus (TC2, 1);
t = t% amostras; // use t% samples em vez de 'if' para evitar o estouro de t
phaseAInc = (predefinição * t)% 5376; // use% 5376 para evitar estouro de índice de array
phaseBInc = (phaseAInc + 1792)% 5376;
phaseCInc = (phaseAInc + 3584)% 5376;
p_A = sin768 [phaseAInc] << 1; // consulte PIOC: PC1 a PC8, pino Arduino Due correspondente: pino 33-40, portanto, mude para a esquerda para 1 dígito
p_B = sin768 [phaseBInc] << 12; // consulte PIOC: PC12 para PC19, pino Arduino Due correspondente: pino 51-44, portanto, desloque 12 dígitos para a esquerda
p_C = sin768 [phaseCInc]; // saída de fase C empregar PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 e PC29, pino Arduino Due correspondente: pino digital: 9, 8, 7, 6, 5, 4, 3, 10, respectivamente
p_C2 = (p_C & B11000000) << 22; // isso gera PC28 e PC29
p_C3 = (p_C & B00111111) << 21; // isso gera PC21-PC26
p_C = p_C2 | p_C3; // isso gera saída paralela da fase C
p_A = p_A | p_B | p_C; // saída de 32 bits = fase A (8 bits) | fase B | fase C
PIOC-> PIO_ODSR = p_A; // registro de saída = p_A
t ++; }
Etapa 4: R / 2R DAC
construir 3x8bit R / 2R DAC, cargas de ref no google.
Etapa 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; // valor da fase C da fase A da fase B - embora a saída seja apenas de 8 bits, os valores p_A e p_B serão operados para gerar um novo valor de 32 bits a fim de lidar com a saída PIOC de 32 bits
uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; intervalo uint32_t; amostras uint16_t, predefinidas; uint32_t t = 0;
void setup () {
// configuração PIOC de saída paralela: Arduino Due pinos 33-40 são empregados como saída de fase A enquanto o pino 44-51 trabalha para saída de fase B
PIOC-> PIO_PER = 0xFFFFFFFE; // PIO controlador PIO Enable register (consulte a p656 da folha de dados ATMEL SAM3X) e https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pino 33-41 e 44-51 foram habilitados
PIOC-> PIO_OER = 0xFFFFFFFE; // Registro de ativação de saída do controlador PIO, consulte a p657 da folha de dados ATMEL SAM3X
PIOC-> PIO_OSR = 0xFFFFFFFE; // Registro de status de saída do controlador PIO, consulte a p658 da folha de dados ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Registro de habilitação de gravação de saída PIO, consulte a p670 da folha de dados ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // opcional como seguro, não parece afetar o desempenho, pino digital 10 conecta a PC29 e PA28, pino digital 4 conecta a PC29 e PA28, aqui para desativar desabilitar PIOA # 28 e 29 // configuração do temporizador, consulte https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (false); // desativa a proteção contra gravação de registros de controle de gerenciamento de energia
pmc_enable_periph_clk (ID_TC7); // habilita o contador de tempo 7 do relógio periférico
TC_Configure (/ * clock * / TC2, / * canal * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // Relógio TC 42MHz (relógio, canal, configuração do modo de comparação) TC_SetRC (TC2, 1, intervalo); TC_Start (TC2, 1);
// habilita interrupções do temporizador no temporizador TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = registro de habilitação de interrupção TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = interromper o registro de desabilitação
NVIC_EnableIRQ (TC7_IRQn); // Habilita a interrupção no controlador de interrupção vetorial aninhado freq = 60; // inicializa a frequência como 60 Hz predefinido = 21; // aumento do índice da matriz em 21 amostras = 256; // saída de amostras 256 / intervalo de ciclo = 42000000 / (freq * samples); // interrupções contagens TC_SetRC (TC2, 1, intervalo); // inicia TC Serial.begin (9600); // para fins de teste}
void checkFreq ()
{freqNew = 20000;
if (freq == freqNew) {} else
{freq = freqNew;
if (freq> 20000) {freq = 20000; / * frequência máxima 20kHz * /};
if (freq <1) {freq = 1; / * frequência mínima 1 Hz * /};
if (freq> 999) {preset = 384; samples = 14;} // para frequência> = 1kHz, 14 amostras para cada ciclo
else if (freq> 499) {preset = 84; samples = 64;} // para 500 <= frequência99) {preset = 42; samples = 128;} // para 100Hz <= frequência <500Hz, 128 samples / ciclo
senão {predefinição = 21; amostras = 256;}; // para frequência <100 Hz, 256 amostras para cada ciclo
intervalo = 42000000 / (amostras de frequência *); t = 0; TC_SetRC (TC2, 1, intervalo); }}
void loop () {
checkFreq (); atraso (100); }
void TC7_Handler (void)
{TC_GetStatus (TC2, 1);
t = t% amostras; // use t% samples para evitar overflow de t phaseAInc = (preset * t)% 5376; // use% 5376 para evitar estouro de índice de array
phaseBInc = (phaseAInc + 1792)% 5376;
phaseCInc = (phaseAInc + 3584)% 5376;
p_A = sin768 [phaseAInc] << 1; // consulte PIOC: PC1 a PC8, pino Arduino Due correspondente: pino 33-40, portanto, mude para a esquerda para 1 dígito
p_B = sin768 [phaseBInc] << 12; // consulte PIOC: PC12 para PC19, pino Arduino Due correspondente: pino 51-44, portanto, desloque 12 dígitos para a esquerda
p_C = sin768 [phaseCInc]; // saída de fase C empregar PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 e PC29, pino Arduino Due correspondente: pino digital: 9, 8, 7, 6, 5, 4, 3, 10, respectivamente
p_C2 = (p_C & B11000000) << 22; // isso gera PC28 e PC29
p_C3 = (p_C & B00111111) << 21; // isso gera PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // isso gera saída paralela da fase C
p_A = p_A | p_B | p_C; // saída 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 saída = p_A t ++; }
Recomendado:
Inversor de onda senoidal pura: 8 etapas
Inversor de onda senoidal pura: minha pesquisa
Função DIY / Gerador de forma de onda: 6 etapas (com imagens)
Gerador de função / forma de onda DIY: Neste projeto, daremos uma breve olhada em geradores de função / forma de onda comerciais para determinar quais recursos são importantes para uma versão DIY. Posteriormente, mostrarei como criar um gerador de função simples, o analógico e o digital
Produção da placa de controle de onda senoidal: 5 etapas
Produção da placa de controle de onda senoidal: desta vez, é uma placa de controle de onda senoidal monofásica fora da rede, seguida por uma placa de controle de onda senoidal monofásica fora da rede e, em seguida, uma placa de controle de onda senoidal trifásica fora da rede, e, finalmente, uma placa de controle de onda senoidal trifásica fora da rede. Esperamos que
Gerador de forma de onda Arduino: 5 etapas (com imagens)
Gerador de forma de onda Arduino: atualização de fevereiro de 2021: verifique a nova versão com 300x a taxa de amostragem, baseada no Raspberry Pi Pico. No laboratório, muitas vezes é necessário um sinal repetitivo de certa frequência, forma e amplitude. Pode ser para testar um amplificador, verificar um circuito
Faça você mesmo um circuito NE555 para gerar onda senoidal: 6 etapas
Faça você mesmo um circuito NE555 para gerar uma onda senoidal: Este tutorial ensina como fazer um circuito NE555 para gerar uma onda senoidal. Estes kits DIY acessíveis são muito úteis para você entender como os capacitores podem trabalhar com resistores para controlar o tempo de carga e descarga que gera