25 kHz में PWM आवृत्ति सेट करें


12

मैं वर्तमान में निम्नलिखित कोड के साथ चार PWM पिन को लगभग 31 kHz पर सेट कर सकता हूं:

void setup()
{
    TCCR1B = TCCR1B & B11111000 | B00000001; // Set PWM frequency for D9 & D10:
    pinMode(pwmPin9, OUTPUT); // Sets the pin as output
    pinMode(pwmPin10, OUTPUT); // Sets the pin as output


    TCCR2B = TCCR2B & B11111000 | B00000001; // Set PWM for D3 & D11
    pinMode(pwmPin3, OUTPUT); // Sets the pin as output
    pinMode(pwmPin11, OUTPUT); // Sets the pin as output
}

मुझे यह सेटअप कहीं और मिला, लेकिन मुझे नहीं पता कि मैं इन चार PWM पिनों को लगभग 25 kHz के बजाय कैसे सेट कर सकता हूं। वो कैसे संभव है?


3
क्या आप समझते हैं कि AVR टाइमर कैसे काम करते हैं?
इग्नासियो वाज़क्वेज़-अब्राम्स


1
@ इग्नासियोविजेक-अब्राम इम परिचित नहीं हैं और मुझे शुरुआत में 25kHz के आसपास उन चार पिनों को सेट करने की आवश्यकता है। मुझे एक परियोजना खत्म करने की जल्दी है और मुझे खुशी होगी कि कोई भी मदद करेगा। कोड मेरे पास 31kHz पर सेट है। क्या मैं इसे 25kHz में संशोधित कर सकता हूं? डीसी मोटर्स को फ्रीक की आवश्यकता होती है।
user16307

1
@NickGammon धन्यवाद, लेकिन मैं वास्तव में इस समय इन का अध्ययन करने के लिए पर्याप्त समय नहीं है। क्या आप मुझे 25kHz सेटअप करने के लिए कोड भाग प्रदान कर सकते हैं। Im खो गया
user16307

2
मुझे उनके सटीक आरपीएम को ट्यून करने की आवश्यकता है ताकि उनकी ड्यूटी चक्र थोड़ा अलग हो। केवल 25kHz पर 2 पिन सेट करना कैसे संभव है?
user16307

जवाबों:


10

मैं यह दूसरा उत्तर पोस्ट कर रहा हूं क्योंकि मुझे एहसास हुआ कि 25 kHz पर 4 PWM चैनल एक Arduino यो पर 161 चरणों के साथ संभव है। इसमें मुख्य घड़ी की आवृत्ति को 8 मेगाहर्ट्ज में बदलना शामिल है , जिसके कुछ साइड इफेक्ट्स हैं क्योंकि पूरा कार्यक्रम आधे से भी तेज चलेगा। यह भी तीन टाइमर, जिसका अर्थ है Arduino समय कार्यों खो को फिर से कॉन्फ़िगर करना शामिल है ( millis(), micros(), delay()और delayMicroseconds())। यदि ये ट्रेड-ऑफ स्वीकार्य हैं, तो यहां बताया गया है:

void setup()
{
    // Set the main system clock to 8 MHz.
    noInterrupts();
    CLKPR = _BV(CLKPCE);  // enable change of the clock prescaler
    CLKPR = _BV(CLKPS0);  // divide frequency by 2
    interrupts();

    // Configure Timer 0 for phase correct PWM @ 25 kHz.
    TCCR0A = 0;           // undo the configuration done by...
    TCCR0B = 0;           // ...the Arduino core library
    TCNT0  = 0;           // reset timer
    TCCR0A = _BV(COM0B1)  // non-inverted PWM on ch. B
        | _BV(WGM00);  // mode 5: ph. correct PWM, TOP = OCR0A
    TCCR0B = _BV(WGM02)   // ditto
        | _BV(CS00);   // prescaler = 1
    OCR0A  = 160;         // TOP = 160

    // Same for Timer 1.
    TCCR1A = 0;
    TCCR1B = 0;
    TCNT1  = 0;
    TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
        | _BV(COM1B1)  // same on ch. B
        | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
    TCCR1B = _BV(WGM13)   // ditto
        | _BV(CS10);   // prescaler = 1
    ICR1   = 160;

    // Same for Timer 2.
    TCCR2A = 0;
    TCCR2B = 0;
    TCNT2  = 0;
    TCCR2A = _BV(COM2B1)  // non-inverted PWM on ch. B
        | _BV(WGM20);  // mode 5: ph. correct PWM, TOP = OCR2A
    TCCR2B = _BV(WGM22)   // ditto
        | _BV(CS20);   // prescaler = 1
    OCR2A  = 160;
}

void loop()
{
    analogWrite( 3,   1);  // duty cycle = 1/160
    analogWrite( 5,  53);  // ~ 1/3
    analogWrite( 9, 107);  // ~ 2/3
    analogWrite(10, 159);  // 159/160
}

अन्य उत्तर के विपरीत , इसके लिए संशोधित संस्करण की आवश्यकता नहीं है analogWrite(): मानक ठीक काम करेगा। केवल इस बात का ध्यान रखा जाना चाहिए कि:

  1. लिखा मान 0 (मतलब हमेशा कम) और 160 (हमेशा उच्च), समावेशी के बीच होना चाहिए।
  2. केवल पिन 3, 5, 9 और 10 उपलब्ध हैं। analogWrite() 6 या 11 पिन करने का प्रयास केवल पीडब्लूएम आउटपुट देने में विफल नहीं होगा, यह क्रमशः 5 या 3 पिन पर आवृत्ति को बदल देगा।

बहुत समय हो गया है और अब मैं Arduino ड्यू के साथ एक ही चीज के साथ फंस गया हूं जो दूसरे प्रोसेसर का उपयोग करता है। मुझे खुशी है कि हो सकता है अगर आप यहाँ किसी भी इनपुट hae arduino.stackexchange.com/questions/67053/...
user16307

11

आप चरण 1 को 25 किलोहर्ट्ज़ पर चरण सही PWM मोड में कॉन्फ़िगर कर सकते हैं, और इसे पिन 9 और 10 पर दो आउटपुट का उपयोग कर सकते हैं जैसे:

// PWM output @ 25 kHz, only on pins 9 and 10.
// Output value should be between 0 and 320, inclusive.
void analogWrite25k(int pin, int value)
{
    switch (pin) {
        case 9:
            OCR1A = value;
            break;
        case 10:
            OCR1B = value;
            break;
        default:
            // no other pin will work
            break;
    }
}

void setup()
{
    // Configure Timer 1 for PWM @ 25 kHz.
    TCCR1A = 0;           // undo the configuration done by...
    TCCR1B = 0;           // ...the Arduino core library
    TCNT1  = 0;           // reset timer
    TCCR1A = _BV(COM1A1)  // non-inverted PWM on ch. A
           | _BV(COM1B1)  // same on ch; B
           | _BV(WGM11);  // mode 10: ph. correct PWM, TOP = ICR1
    TCCR1B = _BV(WGM13)   // ditto
           | _BV(CS10);   // prescaler = 1
    ICR1   = 320;         // TOP = 320

    // Set the PWM pins as output.
    pinMode( 9, OUTPUT);
    pinMode(10, OUTPUT);
}

void loop()
{
    // Just an example:
    analogWrite25k( 9, 110);
    analogWrite25k(10, 210);
    for (;;) ;  // infinite loop
}

0 के मान को लिखने का analogWrite25k()मतलब है कि पिन हमेशा कम रहेगा, जबकि 320 का मतलब हमेशा हाई होता है। नियमित analogWrite() को लगभग काम करना चाहिए , लेकिन यह 320 (यानी हमेशा उच्च) के रूप में 255 की व्याख्या करेगा।

यह कोड Arduino Uno या समान बोर्ड (ATmega168 या 328 @ 16 MHz) को मानता है। यहां इस्तेमाल की जाने वाली विधि में 16-बिट टाइमर की आवश्यकता होती है, और इस प्रकार यह टाइमर 1 का उपयोग करता है क्योंकि यह केवल यूनो पर उपलब्ध है; इसलिए केवल दो आउटपुट उपलब्ध हैं। विधि 16-बिट टाइमर के साथ अन्य AVR- आधारित बोर्डों के लिए अनुकूलित किया जा सकता है। जैसा कि गेरबेन ने कहा, उस टाइमर में एक समान ICRx रजिस्टर होना चाहिए। Arduino Mega पर 4 ऐसे टाइमर हैं, जिनमें से प्रत्येक में 3 आउटपुट हैं।


1
यह समझाने के लिए उपयोगी हो सकता है कि यह विधि केवल टाइमर 1 के लिए काम करती है, क्योंकि अन्य टाइमर में ICRxरजिस्टर नहीं है । अधिक से अधिक, आप केवल टाइमर प्रति एक PWM पिन, टाइमर 0 और 2 के लिए हो सकता है
Gerben

1
@ गेरबेन: सभी 16-बिट टाइमर के पास वह रजिस्टर नहीं है? कम से कम मेगा पर वे करते हैं।
एडगर बोनेट

1
हां, लेकिन ATMega328 पर केवल टाइमर 1 16-बिट है। बाकी 8 बिट हैं। और ओपी 4 पीडब्लूएम आउटपुट चाहता है, और आपका समाधान केवल 2. प्रदान करता है या क्या मैं गलत हूं?
Gerben

1
@ गेरबेन: नहीं, आप सही हैं। मैं सिर्फ इतना कहता हूं कि ICRx की आवश्यकता 16-बिट्स टाइमर की आवश्यकता के साथ बेमानी लगती है। Uno और Mega के लिए कम से कम, अन्य AVR- आधारित Arduinos के बारे में निश्चित नहीं है। ओपी यह समझता है कि यह केवल 2 पीडब्लूएम चैनल प्रदान करता है: उसके प्रश्न और उसके उत्तर पर मेरी टिप्पणी देखें।
एडगर बोनट

2
@techniche: 1. मेरे लिए काम करता है। हो सकता है कि आप सेट करना भूल गया COM4C1में TCCR4A? 2. अगर यह समस्या नहीं है, तो पढ़ें मैं एक अच्छा सवाल कैसे पूछूं? , फिर अपने पूर्ण स्रोत कोड को शामिल करके अपने प्रश्न को अपडेट करें और स्पष्ट रूप से बताएं कि आप कार्यक्रम को करने की अपेक्षा करते हैं और इसके बजाय क्या करते हैं ("मुझे कोई सफलता नहीं दिखती है" एक वैध समस्या कथन नहीं माना जाता है)।
एडगर बोनेट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.