Table des matières:
- Étape 1: Générer un tableau de données sinusoïdales
- Étape 2: Activation de la sortie parallèle
- Étape 3: Activation de l'interruption
- Étape 4: DAC R/2R
- Étape 5: Code complet
Vidéo: Générateur d'onde sinusoïdale triphasée basé sur Arduino Due : 5 étapes
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:07
le but de ce partage est d'aider quelqu'un qui essaie d'utiliser les meilleures performances de Due + le manque de référence + la fiche technique non utile.
ce projet est capable de générer jusqu'à 3 phases d'onde sinusoïdale à 256 échantillons/cycle à basse fréquence (<1 kHz) et 16 échantillons/cycle à haute fréquence (jusqu'à 20 kHz), ce qui est assez bon pour être lissé par de simples LPF et le le rendu est presque parfait.
le fichier joint n'était pas ma version finale car j'ai ajouté des fonctionnalités supplémentaires, mais le noyau est le même. Notez que le nombre d'échantillons/cycle a été défini plus bas que la déclaration ci-dessus.
étant donné que la capacité du processeur est maximisée grâce à l'approche indiquée dans le fichier joint, j'ai utilisé un Arduino Uno comme unité de contrôle, qui utilise l'interruption externe d'Arduino Due pour transmettre la valeur de fréquence à Arduino Due. En plus du contrôle de fréquence, l'Arduino Uno contrôle également l'amplitude (via un potentiel-mètre numérique + OpAmp) ainsi que les E/S --- il y aura beaucoup de place pour jouer avec.
Étape 1: Générer un tableau de données sinusoïdales
Étant donné que le calcul en temps réel est exigeant en CPU, une matrice de données sinusoïdales est requise pour de meilleures performances
uint32_t sin768 PROGMEM= ….while x=[0:5375]; y = 127+127*(sin(2*pi/5376/*ou quelque # que vous préférez dépend de l'exigence*/))
Étape 2: Activation de la sortie parallèle
Contrairement à Uno, Due a une référence limitée. Cependant, afin de générer une onde sinusoïdale triphasée basée sur Arduino Uno, 1er de tous, les performances ne sont pas appréciables en raison de son faible MCLK (16MHz tandis que Due est de 84MHz), 2ème, il est limité GPIO peut produire une sortie maximale de 2 phases et vous avez besoin de plus circuit analogique pour produire la 3ème phase (C=-AB).
La suite de l'activation de GPIO était principalement basée sur un essai et une fiche technique non utile de SAM3X
PIOC->PIO_PER = 0xFFFFFFFE; // Contrôleur PIO Registre d'activation PIO (voir p656 de la fiche technique ATMEL SAM3X) et https://arduino.cc/en/Hacking/PinMappingSAM3X, les broches Arduino Due 33-41 et 44-51 ont été activées
PIOC->PIO_OER = 0xFFFFFFFE; //Registre d'activation de la sortie du contrôleur PIO, reportez-vous à p657 de la fiche technique ATMEL SAM3X PIOC->PIO_OSR = 0xFFFFFFFE; //Registre d'état de sortie du contrôleur PIO, voir p658 de la fiche technique ATMEL SAM3X
PIOC->PIO_OWER = 0xFFFFFFFE; //Registre d'activation d'écriture de sortie PIO, reportez-vous à p670 de la fiche technique ATMEL SAM3X
//PIOA->PIO_PDR = 0x30000000; //optionnel comme assurance, ne semble pas affecter les performances, la broche numérique 10 se connecte à la fois au PC29 et au PA28, la broche numérique 4 se connecte à la fois au PC29 et au PA28, ici pour désactiver désactiver PIOA #28 & 29
Étape 3: Activation de l'interruption
Pour maximiser ses performances, la charge CPU doit être aussi faible que possible. Cependant, en raison de la correspondance non 1 à 1 entre la broche CPU et la broche Due, une opération sur les bits est nécessaire.
Vous pouvez encore optimiser l'algorithme mais la place est très limitée.
void TC7_Handler(void){ TC_GetStatus(TC2, 1);
t = t% échantillons; //utiliser t%samples au lieu de 'if' pour éviter le débordement de t
phaseAInc = (prédéfini*t)%5376; //utiliser %5376 pour éviter le débordement de l'index du tableau
phaseBInc = (phaseAInc+1792)%5376;
phaseCInc = (phaseAInc+3584)%5376;
p_A = sin768[phaseAInc]<<1; // se référer à PIOC: PC1 à PC8, broche Arduino Due correspondante: broche 33-40, donc décaler à gauche pour 1 chiffre
p_B = sin768[phaseBInc]<<12; // se référer à PIOC: PC12 à PC19, broche Arduino Due correspondante: broche 51-44, donc décaler à gauche 12 chiffres
p_C = sin768[phaseCInc]; // sortie phase C employe PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 et PC29, broche Arduino Due correspondante: broche numérique: 9, 8, 7, 6, 5, 4, 3, 10, respectivement
p_C2 = (p_C&B11000000)<<22; //cela génère PC28 et PC29
p_C3 = (p_C&B00111111)<<21; //cela génère PC21-PC26
p_C = p_C2|p_C3; //cela génère une sortie parallèle de la phase C
p_A = p_A|p_B|p_C; //sortie 32 bits = phase A (8 bits)|phase B|phase C
PIOC->PIO_ODSR = p_A; //registre de sortie =p_A
t++; }
Étape 4: DAC R/2R
build 3x8bit R/2R DAC, beaucoup de références sur google.
Étape 5: Code complet
#définir _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; //phase A phase B phase C valeur - bien que la sortie ne soit que de 8 bits, les valeurs p_A et p_B seront utilisées pour générer une nouvelle valeur de 32 bits afin de gérer la sortie PIOC de 32 bits
uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t intervalle; échantillons uint16_t, prédéfinis; uint32_t t = 0;
void setup() {
//Configuration PIOC de sortie parallèle: les broches 33-40 Arduino Due sont utilisées comme sortie de phase A tandis que les broches 44-51 fonctionnent pour la sortie de phase B
PIOC->PIO_PER = 0xFFFFFFFE; // Contrôleur PIO Registre d'activation PIO (voir p656 de la fiche technique ATMEL SAM3X) et https://arduino.cc/en/Hacking/PinMappingSAM3X, les broches Arduino Due 33-41 et 44-51 ont été activées
PIOC->PIO_OER = 0xFFFFFFFE; //Registre d'activation de la sortie du contrôleur PIO, reportez-vous à p657 de la fiche technique ATMEL SAM3X
PIOC->PIO_OSR = 0xFFFFFFFE; //Registre d'état de sortie du contrôleur PIO, voir p658 de la fiche technique ATMEL SAM3X
PIOC->PIO_OWER = 0xFFFFFFFE; //Registre d'activation d'écriture de sortie PIO, reportez-vous à p670 de la fiche technique ATMEL SAM3X
//PIOA->PIO_PDR = 0x30000000; //facultatif comme assurance, ne semble pas affecter les performances, la broche numérique 10 se connecte à la fois au PC29 et au PA28, la broche numérique 4 se connecte à la fois au PC29 et au PA28, ici pour désactiver la PIOA #28 & 29 //configuration de la minuterie, reportez-vous à https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect(false); // désactiver la protection en écriture des registres de contrôle de gestion de l'alimentation
pmc_enable_periph_clk(ID_TC7); // activer le compteur horaire de l'horloge périphérique 7
TC_Configure(/* horloge */TC2, /* canal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); //Horloge TC 42MHz (horloge, canal, réglage du mode de comparaison) TC_SetRC(TC2, 1, intervalle); TC_Début(TC2, 1);
// activer les interruptions du timer sur le timer TC2->TC_CHANNEL[1]. TC_IER=TC_IER_CPCS; // IER = registre d'activation d'interruption TC2->TC_CHANNEL[1]. TC_IDR=~TC_IER_CPCS; // IDR = registre de désactivation d'interruption
NVIC_EnableIRQ(TC7_IRQn); // Activer l'interruption dans le contrôleur d'interruption vectorielle imbriquée freq = 60; //initialiser la fréquence en tant que préréglage 60 Hz = 21; //augmentation de l'index du tableau de 21 échantillons = 256; //sortir les échantillons 256/intervalle de cycle = 42000000/(freq*samples); //compte d'interruption TC_SetRC(TC2, 1, intervalle); //démarrer TC Serial.begin(9600); //à des fins de test }
void checkFreq()
{ freqNouveau = 20000;
if (freq == freqNew) {} else
{ freq = freqNouveau;
if (freq>20000) {freq = 20000; /*fréquence max 20kHz*/};
si (freq<1) {freq = 1; /*fréquence min 1Hz*/};
if (freq>999) {préréglé = 384; échantillons = 14;} //pour la fréquence >=1kHz, 14 échantillons pour chaque cycle
else if (freq>499) {preset = 84; échantillons = 64;} //pour 500<=fréquence99) {préréglage = 42; échantillons = 128;} //pour 100Hz<=fréquence<500Hz, 128 échantillons/cycle
else {préréglé = 21; échantillons = 256;}; //pour la fréquence<100hz, 256 échantillons pour chaque cycle
intervalle = 42000000/(freq*échantillons); t = 0; TC_SetRC(TC2, 1, intervalle); } }
boucle vide() {
vérifierFréq(); retard (100); }
void TC7_Handler(void)
{ TC_GetStatus(TC2, 1);
t = t% échantillons; //utiliser t%samples pour éviter le débordement de t phaseAInc = (preset*t)%5376; //utiliser %5376 pour éviter le débordement de l'index du tableau
phaseBInc = (phaseAInc+1792)%5376;
phaseCInc = (phaseAInc+3584)%5376;
p_A = sin768[phaseAInc]<<1; // se référer à PIOC: PC1 à PC8, broche Arduino Due correspondante: broche 33-40, donc décaler à gauche pour 1 chiffre
p_B = sin768[phaseBInc]<<12; // se référer à PIOC: PC12 à PC19, broche Arduino Due correspondante: broche 51-44, donc décaler à gauche 12 chiffres
p_C = sin768[phaseCInc]; // sortie phase C employe PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 et PC29, broche Arduino Due correspondante: broche numérique: 9, 8, 7, 6, 5, 4, 3, 10, respectivement
p_C2 = (p_C&B11000000)<<22; //cela génère PC28 et PC29
p_C3 = (p_C&B00111111)<<21; //cela génère PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2|p_C3; //cela génère une sortie parallèle de la phase C
p_A = p_A|p_B|p_C; //sortie 32 bits = phase A (8 bits)|phase B|phase C //Serial.println(p_A>>21, BIN); //PIOC->PIO_ODSR = 0x37E00000;
PIOC->PIO_ODSR = p_A; //registre de sortie =p_A t++; }
Conseillé:
Onduleur à onde sinusoïdale pure : 8 étapes
Onduleur sinusoïdal pur : mes recherches
Production de la carte de contrôle à onde sinusoïdale : 5 étapes
Production de carte de commande à onde sinusoïdale : cette fois, il s'agit d'une carte de commande hors réseau à onde sinusoïdale monophasée, suivie d'une carte de commande hors réseau à onde sinusoïdale monophasée, puis d'une carte de commande hors réseau à onde sinusoïdale triphasée, et enfin un tableau de commande hors réseau à onde sinusoïdale triphasée. Nous espérons que
Générateur de formes d'onde Arduino : 5 étapes (avec images)
Arduino Waveform Generator : mise à jour février 2021 : découvrez la nouvelle version avec un taux d'échantillonnage 300x, basée sur le Raspberry Pi Pico. En laboratoire, on a souvent besoin d'un signal répétitif d'une certaine fréquence, forme et amplitude. Cela peut être pour tester un amplificateur, vérifier un circuit
Générateur de musique basé sur la météo (Générateur Midi basé sur ESP8266): 4 étapes (avec images)
Générateur de musique basé sur la météo (Générateur Midi basé sur ESP8266): Bonjour, aujourd'hui, je vais vous expliquer comment créer votre propre petit générateur de musique basé sur la météo. Il est basé sur un ESP8266, qui ressemble un peu à un Arduino, et il réagit à la température, à la pluie et l'intensité lumineuse. Ne vous attendez pas à ce qu'il fasse des chansons entières ou un programme d'accords
Bricolage d'un circuit NE555 pour générer une onde sinusoïdale : 6 étapes
Bricolage d'un circuit NE555 pour générer une onde sinusoïdale : Ce didacticiel vous explique comment bricoler un circuit NE555 pour générer une onde sinusoïdale. Ce kit de bricolage abordable est très utile pour vous permettre de comprendre comment les condensateurs peuvent fonctionner avec des résistances pour contrôler le temps de charge et de décharge qui doit générer