Inhoudsopgave:
- Stap 1: Genereer sinusgegevensarray
- Stap 2: Parallelle uitvoer inschakelen
- Stap 3: Onderbreking inschakelen
- Stap 4: R/2R DAC
- Stap 5: Volledige code
Video: 3-fasen sinusgenerator op basis van Arduino Due - Ajarnpa
2024 Auteur: John Day | [email protected]. Laatst gewijzigd: 2024-01-30 11:17
het doel van dit aandeel is om iemand te helpen die de betere prestaties van Due probeert te gebruiken + gebrek aan referentie + niet-nuttige datasheet.
dit project is in staat om tot 3 fase sinusgolf @ 256 samples/cyclus bij lage freq (<1kHz) en 16 samples/cyclus @ hoge freq (tot 20kHz) te genereren, wat goed genoeg is om te worden afgevlakt door eenvoudige LPF's en de uitvoer is bijna perfect.
het bijgevoegde bestand was niet mijn definitieve versie, want ik heb een extra functie toegevoegd, maar de kern is hetzelfde. Merk op dat de monsters/cyclus lager was ingesteld dan de bovenstaande verklaring.
aangezien de CPU-capaciteit wordt gemaximaliseerd door de benadering die wordt getoond in het bijgevoegde bestand, heb ik een Arduino Uno als besturingseenheid gebruikt, die de externe interrupt van Arduino Due gebruikt om de frequentiewaarde door te geven aan Arduino Due. Naast frequentieregeling regelt de Arduino Uno ook de amplitude (via digitale potentiaalmeter + OpAmp) en I/O --- er zal veel ruimte zijn om mee te spelen.
Stap 1: Genereer sinusgegevensarray
Aangezien real-time berekening CPU-veeleisend is, is een sinusgegevensarray vereist voor betere prestaties
uint32_t sin768 PROGMEM= ….terwijl x=[0:5375]; y = 127+127*(sin(2*pi/5376/*of een # die u verkiest, hangt af van de vereiste*/))
Stap 2: Parallelle uitvoer inschakelen
In tegenstelling tot Uno heeft Due een beperkte referentie. Om echter een 3-fase sinusgolf te genereren op basis van Arduino Uno, ten eerste, zijn de prestaties niet te applaudisseren vanwege de lage MCLK (16 MHz terwijl Due 84 MHz is), ten tweede is het beperkt GPIO kan max. 2-fasen output produceren en je hebt extra nodig analoge schakeling om de 3e fase (C=-AB) te produceren.
Het inschakelen van GPIO was meestal gebaseerd op proberen en proberen + niet nuttig gegevensblad van SAM3X
PIOC->PIO_PER = 0xFFFFFFFE; //PIO-controller PIO Enable register (zie p656 van ATMEL SAM3X datasheet) en https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 en 44-51 waren ingeschakeld
PIOC->PIO_OER = 0xFFFFFFFE; // PIO-controller uitgang inschakelen register, zie p657 van ATMEL SAM3X datasheet PIOC->PIO_OSR = 0xFFFFFFFE; //PIO-controller output statusregister, zie p658 van ATMEL SAM3X datasheet
PIOC->PIO_OWER = 0xFFFFFFFE; // PIO-uitgang schrijf-enabled register, zie p670 van ATMEL SAM3X datasheet
//PIOA->PIO_PDR = 0x30000000; // optioneel als verzekering, lijkt de prestaties niet te beïnvloeden, digitale pin 10 maakt verbinding met zowel PC29 als PA28, digitale pin 4 maakt verbinding met zowel PC29 als PA28, hier om PIOA #28 & 29 uit te schakelen
Stap 3: Onderbreking inschakelen
Om de prestaties te maximaliseren, moet de CPU-belasting zo laag mogelijk zijn. Vanwege de niet-op-1-correspondentie tussen de CPU-pin en de Due-pin is bitbewerking echter noodzakelijk.
Je kunt het algoritme verder optimaliseren maar de ruimte is erg beperkt.
void TC7_Handler(void){ TC_GetStatus(TC2, 1);
t = t% monsters; // gebruik t%samples in plaats van 'if' om overloop van t. te voorkomen
phaseAInc = (preset*t)%5376; // gebruik %5376 om overloop van de array-index te voorkomen
phaseBInc = (phaseAInc+1792)%5376;
phaseCInc = (phaseAInc+3584)%5376;
p_A = sin768[phaseAInc]<<1; //verwijs naar PIOC: PC1 tot PC8, corresponderende Arduino Due pin: pin 33-40, vandaar naar links schuiven voor 1 cijfer
p_B = sin768[phaseBInc]<<12; // verwijzen naar PIOC: PC12 tot PC19, overeenkomstige Arduino Due pin: pin 51-44, vandaar shift links 12 cijfers
p_C = sin768[phaseCInc]; //fase C uitgang werknemer PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 en PC29, bijbehorende Arduino Due pin: digitale pin: 9, 8, 7, 6, 5, 4, 3, 10, respectievelijk
p_C2 = (p_C&B11000000)<<22; //dit genereert PC28 en PC29
p_C3 = (p_C&B00111111)<<21; //dit genereert PC21-PC26
p_C = p_C2|p_C3; // dit genereert parallelle output van fase C
p_A = p_A|p_B|p_C; //32 bit output = fase A (8bit)|fase B|fase C
PIOC->PIO_ODSR = p_A; // uitvoerregister =p_A
t++; }
Stap 4: R/2R DAC
bouw 3x8bit R/2R DAC, veel ref op google.
Stap 5: Volledige code
#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 fase C-waarde - hoewel de uitvoer alleen 8 bits is, zullen de p_A- en p_B-waarde worden gebruikt om een nieuwe 32-bits waarde te genereren om met 32-bits PIOC-uitvoer om te gaan
uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t-interval; uint16_t voorbeelden, vooraf ingesteld; uint32_t t = 0;
ongeldige setup() {
//parallelle output PIOC setup: Arduino Due pin33-40 wordt gebruikt als fase A-uitgang, terwijl pin 44-51 werkt voor fase B-uitgang
PIOC->PIO_PER = 0xFFFFFFFE; //PIO-controller PIO Enable register (zie p656 van ATMEL SAM3X datasheet) en https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 en 44-51 waren ingeschakeld
PIOC->PIO_OER = 0xFFFFFFFE; // PIO-controller uitgang inschakelen register, zie p657 van ATMEL SAM3X datasheet
PIOC->PIO_OSR = 0xFFFFFFFE; //PIO-controller output statusregister, zie p658 van ATMEL SAM3X datasheet
PIOC->PIO_OWER = 0xFFFFFFFE; // PIO-uitvoer schrijf-enabled register, zie p670 van ATMEL SAM3X datasheet
//PIOA->PIO_PDR = 0x30000000; //optioneel als verzekering, lijkt de prestaties niet te beïnvloeden, digitale pin 10 verbindt met zowel PC29 als PA28, digitale pin 4 maakt verbinding met zowel PC29 als PA28, hier om PIOA #28 & 29 uit te schakelen //timer setup, zie https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect(false); // schrijfbeveiliging van Power Management Control-registers uitschakelen
pmc_enable_periph_clk(ID_TC7); // schakel perifere kloktijdteller 7. in
TC_Configure(/* klok */TC2, /* kanaal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); //TC klok 42MHz (klok, kanaal, vergelijk modus instelling) TC_SetRC (TC2, 1, interval); TC_Start(TC2, 1);
// schakel timeronderbrekingen in op de timer TC2->TC_CHANNEL[1]. TC_IER=TC_IER_CPCS; // IER = interrupt inschakelen register TC2->TC_CHANNEL[1]. TC_IDR=~TC_IER_CPCS; // IDR = interrupt uitschakelen register
NVIC_EnableIRQ(TC7_IRQn); // Schakel de interrupt in de geneste vector interruptcontroller in freq = 60; // initialiseer frequentie als 60 Hz preset = 21; // matrixindexverhoging met 21 samples = 256; //output samples 256/cyclus interval = 42000000/(freq*samples); //onderbreking telt TC_SetRC (TC2, 1, interval); //start TC Serial.begin (9600); //voor testdoeleinden}
ongeldige checkFreq()
{ freqNieuw = 20000;
if (freq == freqNieuw) {} else
{ freq = freqNieuw;
als (freq>20000) {freq = 20000; /*max frequentie 20kHz*/};
als (freq<1) {freq = 1; /*min frequentie 1Hz*/};
if (freq>999) {preset = 384; samples = 14;} // voor frequentie >=1kHz, 14 samples voor elke cyclus
else if (freq>499) {preset = 84; samples = 64;} // voor 500<=frequentie99) {preset = 42; samples = 128;} //voor 100Hz<=frequentie<500Hz, 128 samples/cyclus
anders {voorinstelling = 21; monsters = 256;}; // voor frequentie <100 hz, 256 monsters voor elke cyclus
interval = 42000000/(freq*samples); t = 0; TC_SetRC(TC2, 1, interval); } }
lege lus() {
checkFreq(); vertraging (100); }
ongeldig TC7_Handler (ongeldig)
{ TC_GetStatus(TC2, 1);
t = t% monsters; // gebruik t%samples om overloop van t phaseAInc = (preset*t)%5376 te voorkomen; // gebruik %5376 om overloop van de array-index te voorkomen
phaseBInc = (phaseAInc+1792)%5376;
phaseCInc = (phaseAInc+3584)%5376;
p_A = sin768[phaseAInc]<<1; //verwijs naar PIOC: PC1 tot PC8, corresponderende Arduino Due pin: pin 33-40, vandaar naar links schuiven voor 1 cijfer
p_B = sin768[phaseBInc]<<12; //verwijs naar PIOC: PC12 tot PC19, corresponderende Arduino Due pin: pin 51-44, vandaar shift links 12 cijfers
p_C = sin768[phaseCInc]; //fase C uitgang werknemer PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 en PC29, bijbehorende Arduino Due pin: digitale pin: 9, 8, 7, 6, 5, 4, 3, 10, respectievelijk
p_C2 = (p_C&B11000000)<<22; //dit genereert PC28 en PC29
p_C3 = (p_C&B00111111)<<21; //dit genereert PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2|p_C3; // dit genereert parallelle output van fase C
p_A = p_A|p_B|p_C; //32 bit output = fase A (8bit)|fase B|fase C //Serial.println(p_A>>21, BIN); //PIOC->PIO_ODSR = 0x37E00000;
PIOC->PIO_ODSR = p_A; // uitvoerregister =p_A t++; }
Aanbevolen:
SmartHome draadloze communicatie: de extreme basis van MQTT: 3 stappen
SmartHome draadloze communicatie: de extreme basis van MQTT: MQTT basis: **Ik ga een serie domotica doen, ik zal de stappen doorlopen die ik heb genomen om alles te leren wat ik in de toekomst heb gedaan. Deze Instructable is de basis voor het instellen van MQTT voor gebruik in mijn toekomstige Instructables. echter
Een goedkope IoT-luchtkwaliteitsmonitor op basis van RaspberryPi 4: 15 stappen (met afbeeldingen)
Een goedkope IoT-luchtkwaliteitsmonitor op basis van RaspberryPi 4: Santiago, Chili tijdens een winterse milieunoodsituatie hebben het voorrecht om in een van de mooiste landen ter wereld te wonen, maar helaas zijn het niet allemaal rozen. Chili heeft tijdens het winterseizoen veel last van luchtverontreiniging, ma
Basis van FastLED: 8 stappen
Basis van FastLED: in deze Instructables zullen we zien hoe we FastLED-programma kunnen schrijven en hoe we de FastLed-bibliotheek kunnen gebruiken. We zullen ook zien hoe we kunnen coderen om onze eigen kleurpatronen te ontwerpen. Deze bibliotheek ondersteunt verschillende soorten ledstrips die bij de
Milieubewakingssysteem op basis van OBLOQ-IoT-module: 4 stappen
Milieubewakingssysteem op basis van OBLOQ-IoT-module: dit product wordt voornamelijk toegepast in elektronische laboratoria om indicatoren zoals temperatuur, vochtigheid, licht en stof te bewaken en te controleren, en deze tijdig te uploaden naar de cloudgegevensruimte om bewaking en controle op afstand van de luchtontvochtiger te bereiken , luchtzuiver
BASIS VAN UART-COMMUNICATIE: 16 stappen
BASIS VAN UART-COMMUNICATIE: Weet je nog dat printers, muizen en modems dikke kabels hadden met die enorme onhandige connectoren? Degenen die letterlijk in je computer moesten worden geschroefd? Die apparaten gebruikten waarschijnlijk UART's om met uw computer te communiceren. Terwijl USB bijna