Re: Arduino generování pulzů

Martin Záruba swz na volny.cz
Neděle Červenec 30 19:09:24 CEST 2023


Nevyhoví, protože já potřebuji frekvenci okolo 20kHz.

Ale snad jsem to vyšrachal. Možná by Vás to mohlo zajímat. Zde je ukázka 
programu, který pomocí přerušení od interního časovače generuje dva 
různé nezávislé pulzy na výstupech 9 a 10. Všechny normální funkce 
(externí přerušení, delay) by měly zůstat zachovány.


#include <avr/io.h>
#include <avr/interrupt.h>

// Proměnné pro uchování šířky pulzů
volatile unsigned int pulseWidth1 = 1000; // Výchozí šířka pulzu 1 na 
Counter1 - 1000 us (1 ms)
volatile unsigned int pulseWidth2 = 500;  // Výchozí šířka pulzu 2 na 
Counter2 - 500 us

void setup() {
   // Nastavení pinů pro výstup pulzů
   pinMode(9, OUTPUT);
   pinMode(10, OUTPUT);

   // Nastavení časovače Timer/Counter1
   cli(); // Vypnutí globálních přerušení
   TCCR1A = 0; // Vynulování registru TCCR1A
   TCCR1B = 0; // Vynulování registru TCCR1B

   // Nastavení režimu Fast PWM (TOP = ICR1)
   TCCR1A |= (1 << WGM11);
   TCCR1B |= (1 << WGM13) | (1 << WGM12);

   // Nastavení hodinového děliče na 64 (frekvence časovače = frekvence 
CPU / 64)
   TCCR1B |= (1 << CS11) | (1 << CS10);

   // Nastavení intervalu pro generování přerušení (1 ms) - pro 
frekvenci CPU 16 MHz
   // ICR1 = (F_CPU / (časový interval * hodinový dělič)) - 1
   ICR1 = 249; // 1 ms při frekvenci CPU 16 MHz a hodinovém děliči 64

   // Povolení přerušení od časovače Timer/Counter1
   TIMSK1 |= (1 << TOIE1);

   // Nastavení časovače Timer/Counter2
   TCCR2A = 0; // Vynulování registru TCCR2A
   TCCR2B = 0; // Vynulování registru TCCR2B

   // Nastavení režimu Fast PWM (TOP = 255)
   TCCR2A |= (1 << WGM21) | (1 << WGM20);
   TCCR2B |= (1 << CS22); // Hodinový dělič 64 - frekvence časovače = 
frekvence CPU / 64

   // Povolení přerušení od časovače Timer/Counter2
   TIMSK2 |= (1 << TOIE2);

   sei(); // Zapnutí globálních přerušení
}

void loop() {
   // V hlavní smyčce (loop) můžete provádět další činnosti
}

// Obsluha přerušení od časovače Timer/Counter1
ISR(TIMER1_OVF_vect) {
   // Generování pulzu 1 na pinu 9 (při logické 1)
   digitalWrite(9, HIGH);

   // Počkejte na dobu odpovídající šířce pulzu 1
   delayMicroseconds(pulseWidth1);

   // Ukončení pulzu 1 (nastavení logické 0)
   digitalWrite(9, LOW);
}

// Obsluha přerušení od časovače Timer/Counter2
ISR(TIMER2_OVF_vect) {
   // Generování pulzu 2 na pinu 10 (při logické 1)
   digitalWrite(10, HIGH);

   // Počkejte na dobu odpovídající šířce pulzu 2
   delayMicroseconds(pulseWidth2);

   // Ukončení pulzu 2 (nastavení logické 0)
   digitalWrite(10, LOW);
}

Martin Záruba

Dne 30.7.2023 v 16:36 Jaroslav Buchta napsal(a):
> To zalezi, jaky mate MCU. Treba ESP32 na generovani prubehu i 
> neperiodickych ma super periferii.
> Jinak nevyhovi obecne PWM? To by mely umet vsechny MCU.
>
> Dne 30.07.2023 v 14:59 Martin Záruba napsal(a):
>> Potřeboval bych přimět Arduino generovat pulzy o frekvenci cca 20kHz, 
>> ale s jinou střídou, než 1:1, jak dělá příkaz tone. Jde to nějak?
>>
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20230730/e9ac3b89/attachment.htm>


Další informace o konferenci Hw-list