Otázka:
Nastavte frekvenci PWM na 25 kHz
user16307
2016-06-24 05:52:48 UTC
view on stackexchange narkive permalink

V současné době mohu nastavit čtyři piny PWM na přibližně 31 kHz s následujícím kódem:

  void setup () {TCCR1B = TCCR1B & B11111000 | B00000001; // Nastavení frekvence PWM pro D9 & D10: pinMode (pwmPin9, OUTPUT); // Nastaví pin jako výstupní pinMode (pwmPin10, OUTPUT); // Nastaví kolík jako výstup TCCR2B = TCCR2B & B11111000 | B00000001; // Nastavení PWM pro D3 & D11 pinMode (pwmPin3, OUTPUT); // Nastaví pin jako výstupní pinMode (pwmPin11, OUTPUT); // Nastaví pin jako výstup}  

Našel jsem toto nastavení někde, ale nevím, jak mohu místo toho nastavit tyto čtyři PWM piny na zhruba 25 kHz. Jak je to možné?

Rozumíte tomu, jak fungují časovače AVR?
Viz [moje stránka o časovačích] (http://www.gammon.com.au/timers).
@IgnacioVazquez-Abrams Nejsem obeznámen a musím na začátku nastavit ty čtyři piny na zhruba 25kHz. Spěchám s dokončením projektu a byl bych rád, kdyby mi někdo pomohl. Kód mám nastaven na 31kHz. Mohu to upravit na 25kHz? Stejnosměrné motory vyžadují, aby frekvence
@NickGammon Díky, ale v tuto chvíli opravdu nemám dost času je studovat. Mohl byste mi poskytnout část kódu pro nastavení 25kHz. Ztratil jsem se
Proč čtyři špendlíky? Budou mít všichni různé pracovní cykly? Proč ne jeden špendlík a neposlat jej na čtyři různá místa?
`` V současné době mohu nastavit čtyři pwm piny na přibližně 31kHz s následujícím kódem` - právě jsem zkusil váš kód a nic nevydal.
Musím vyladit jejich přesné otáčky, aby se jejich pracovní cykly mírně lišily. Co takhle je možné nastavit 2 piny pouze na 25kHz?
Tento kód lze snadno přizpůsobit pro nastavení frekvence na 31400, 3920, 490, 123 nebo 30,6 Hz. Jiné frekvence by nebyly tak jednoduché a budou s největší pravděpodobností zahrnovat změnu rozlišení výstupu PWM. Dokážete žít s rozlišením pouze 41 kroků? Nebo 80 kroků, ale ztráta funkce „správná fáze“? Nebo 321 kroků, ale pouze na piny 9 a 10?
Myslím, že poslední možnost by byla skvělá, pak použiji dva Ard. desky. Můžete mi s touto částí pomoci? Nejsem obeznámen
Při diskusi s Gerbenem jsem přemýšlel o čtvrté možnosti: Mohli byste zpomalit hlavní systémové hodiny na 8 MHz a použít tři časovače. Pak byste měli 4 kanály PWM při 25 kHz a 161 krocích na jednom Arduino Uno. Cena by byla ztráta časovacích funkcí (`millis ()`, `delay ()` a spol.), Nutnost upravit sériové přenosové rychlosti a celý program by běžel napůl tak rychle. Byla by to zajímavá volba?
@EdgarBonet Děkujeme za podrobné podrobné odpovědi. V mém aktuálním kódu mohu ovládat 31kHz čtyři pwm piny. Zároveň mohu použít LCD obrazovku (zde používám delay (), abych zabránil blikání) a přenosová rychlost je 9600. Pokud tedy použiji váš návrh 8MHz, jakou přenosovou rychlost mám použít?
S CPU @ 8 MHz, pokud „Serial.begin (19200)“, bude skutečná přenosová rychlost 9600 b / s. `delay ()` může fungovat, ale v jednotkách 39,0625 µs.
Nejlepší materiál vysvětlující PWM s časovači AVR, který jsem zatím našel, je video YouTube * „[8. Arduino Timers and Counters] (https://www.youtube.com/watch?v=faCVhp7gm-g) *“ ( 1 h 00 m 08 s).
prohledal jsem to, je to správné, co potřebuji. Jak to upravit tak, aby poskytovalo výstup asi 14 KHz? ve skutečnosti mezi 11 - 19 khz OK. Děkuji
Dva odpovědi:
Edgar Bonet
2016-06-24 17:54:56 UTC
view on stackexchange narkive permalink

Můžete nakonfigurovat časovač 1 tak, aby cykloval na 25 kHz ve fázově správném režimu PWM, a použít dva výstupy na pinech 9 a 10 takto:

  // PWM output @ 25 kHz, only on pins 9 and 10.// Output value should be between 0 and 320, including. vyloučit analogWrite25k (int pin, int value) {switch (pin) {případ 9: OCR1A = hodnota; přestávka; případ 10: OCR1B = hodnota; přestávka; výchozí: // žádný jiný pin nebude fungovat; }} void setup () {// Konfigurace časovače 1 pro PWM @ 25 kHz. TCCR1A = 0; // vrátit zpět konfiguraci provedenou ... TCCR1B = 0; // ... základní knihovna Arduino TCNT1 = 0; // reset časovače TCCR1A = _BV (COM1A1) // neinvertovaný PWM na kap. A | _BV (COM1B1) // stejné na ch; B | _BV (WGM11); // režim 10: ph. správné PWM, TOP = ICR1 TCCR1B = _BV (WGM13) // ditto | _BV (CS10); // prescaler = 1 ICR1 = 320; // TOP = 320 // Nastaví PWM piny jako výstup. pinMode (9, VÝSTUP); pinMode (10, OUTPUT);} void loop () {// Jen příklad: analogWrite25k (9, 110); analogWrite25k (10, 210); pro (;;) ; // nekonečná smyčka}  

Zápis hodnoty 0 pomocí analogWrite25k () znamená, že pin bude vždy LOW, zatímco 320 znamená vždy HIGH. Normální analogWrite () by měl téměř fungovat, ale bude interpretovat 255 stejně jako 320 (iealways HIGH).

Tento kód předpokládá Arduino Uno nebo podobná deska (ATmega168 nebo 328 @ 16 MHz). Metoda použitá zde vyžaduje 16bitový časovač, a tudíž ituses Timer 1, protože je jediný dostupný na Uno; proto jsou k dispozici pouze dva výstupy. Metodu lze přizpůsobit jiným deskám založeným na AVR s 16bitovým časovačem. Jak poznamenal Gerben, tento časovač by měl mít odpovídající registr ICRx. Na Arduino Mega jsou 4 takové časovače, každý se 3 výstupy.

Může být užitečné vysvětlit, že tato metoda funguje pouze pro časovač1, protože ostatní časovače nemají registr `ICRx`. Maximálně můžete mít pouze jeden pin PWM na časovač, pro časovače 0 a 2.
@Gerben: Nemají všechny 16bitové časovače tento registr? Alespoň na Mega to dělají.
Ano, ale pouze časovač1 je na ATMega328 16bitový. Zbytek je 8bitový. A OP chce výstup 4 PWM a vaše řešení poskytuje pouze 2. Nebo se pletu?
@Gerben: Ne, máte pravdu. Jen říkám, že požadavek ICRx se zdá být nadbytečný s požadavkem, aby časovač byl 16 bitů. Přinejmenším pro Uno a Mega si nejste jisti jinými Arduiny založenými na AVR. OP rozumí tomu, že poskytuje pouze 2 kanály PWM: viz můj komentář k jeho otázce a jeho odpovědi.
Na ATMega328 (který OP používá) má pouze časovač1 registr `ICRx`. U ostatních budete muset použít `OCRxA` jako TOP, což znemožní použití PWM na pinu` OCxA`. OP uvedl, že je v pořádku pouze se dvěma piny PWM, ale pak říká, že bude používat 2 Arduina. Stále by mělo být možné dělat pouze s 1 Uno, pokud je OP ochoten ztratit „millis“ a „delay“.
@Gerben: Pouze jedno Uno? Mluvíte o dalších dvou možnostech, které jsem navrhl (tj. Nastavení přednastavovačů na 8)? Mohl by se také změnit kmitočet hlavních hodin a mít 161 kroků, ale o tom jsem neměl. To máš na mysli?
Opravdu jsem nesledoval hlavní vlákno komentářů. Opravdu jsem mluvil o vaší 41krokové alternativě. (Nejsem si jistý, jestli OP opravdu potřebuje více než 41 kroků pro ovládání RPM.)
@Edgar Bonet Snažím se to sledovat a generovat stejných 25kHz na pin 8 arduino mega, který je řízen TIMER 4; Nevidím žádný úspěch; mohl byste prosím pomoci?
@techniche: 1. Pracuje pro mě. Možná jste zapomněli nastavit `COM4C1` v` TCCR4A`? 2. Pokud to není problém, přečtěte si [Jak se mohu zeptat na dobrou otázku?] (Https://arduino.stackexchange.com/help/how-to-ask) a poté aktualizujte [svou otázku] (https: / /arduino.
@EdgarBonet - moc děkuji za reakci a pomoc; Jsem schopen generovat signál pwm a někdo jiný jej ověřil pomocí ventilátoru alpine 64 gt a zdá se, že funguje; to nefunguje s ventilátorem Mám https://www.amazon.in/StorinTM-CPU-Cooler-Cooling-Connector/dp/B06XJV1SH8/ Je to standardní CPU ventilátor se 4 dráty a jeho infact hodně použitý; mohl by to být problém s ventilátorem a kabel pwm je jen pro parádu?
Edgar Bonet
2016-06-25 01:29:19 UTC
view on stackexchange narkive permalink

Zveřejňuji tuto druhou odpověď, protože jsem si uvědomil, že je možné mít 4 kanály PWM při 25 kHz se 161 kroky na jediném Arduino Uno. To zahrnuje změnu hlavní taktovací frekvence na 8 MHz, což má některé vedlejší účinky, protože celý program poběží napůl tak rychle. Italso zahrnuje rekonfiguraci tří časovačů, což znamená ztrátu časovacích funkcí Arduino ( millis () , micros () , delay () a delayMicroseconds () ). Pokud jsou tyto kompromisy přijatelné, postupuje se takto:

  void setup () {// Nastavit hodiny hlavního systému na 8 MHz. noInterrupts (); CLKPR = _BV (CLKPCE); // povolit změnu předvoliče hodin CLKPR = _BV (CLKPS0); // dělení frekvence o 2 přerušení (); // Konfigurace časovače 0 pro fázově správné PWM @ 25 kHz. TCCR0A = 0; // vrátit zpět konfiguraci provedenou ... TCCR0B = 0; // ... základní knihovna Arduino TCNT0 = 0; // reset časovače TCCR0A = _BV (COM0B1) // neinvertovaný PWM na kap. B | _BV (WGM00); // režim 5: ph. správné PWM, TOP = OCR0A TCCR0B = _BV (WGM02) // ditto | _BV (CS00); // prescaler = 1 OCR0A = 160; // TOP = 160 // Totéž pro časovač 1. TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1A = _BV (COM1A1) // neinvertovaný PWM na ch. A | _BV (COM1B1) // stejné na kap. B | _BV (WGM11); // režim 10: ph. správné PWM, TOP = ICR1 TCCR1B = _BV (WGM13) // ditto | _BV (CS10); // prescaler = 1 ICR1 = 160; // Totéž pro časovač 2. ​​TCCR2A = 0; TCCR2B = 0; TCNT2 = 0; TCCR2A = _BV (COM2B1) // neinvertovaný PWM na ch. B | _BV (WGM20); // režim 5: ph. správné PWM, TOP = OCR2A TCCR2B = _BV (WGM22) // ditto | _BV (CS20); // prescaler = 1 OCR2A = 160;} void loop () {analogWrite (3, 1); // pracovní cyklus = 1/160 analogWrite (5, 53); // ~ 1/3 analogWrite (9, 107); // ~ 2/3 analogWrite (10, 159); // 159/160}

Na rozdíl od jiné odpovědi nepotřebuje upravenou verzi analogWrite () : standardní bude fungovat dobře. Mělo by se dbát pouze na to, že:

  1. Zapisovaná hodnota by měla být mezi 0 (tj. Vždy NÍZKÁ) a 160 (vždy VYSOKÁ) včetně.
  2. Pouze piny 3, 5 9 a 10 jsou k dispozici. Pokus o analogWrite () na piny 6 nebo 11 nejenže nepřinese výstup PWM, ale také změní frekvenci na pinu 5 nebo 3.
Byla to velmi dlouhá doba a teď jsem uvízl se stejnou věcí s Arduino Due, který používá jiný procesor. Byl bych rád, kdybyste zde měli jakýkoli vstup https://arduino.stackexchange.com/questions/67053/trouble-with-setting-the-pwm-frequency-for-arduino-due


Tyto otázky a odpovědi byly automaticky přeloženy z anglického jazyka.Původní obsah je k dispozici na webu stackexchange, za který děkujeme za licenci cc by-sa 3.0, pod kterou je distribuován.
Loading...