AVR ATMEGA / ATTINY टाइमर मिरर आउटपुट को समझने में मदद चाहिए


10

मैं Atmel AVR माइक्रोकंट्रोलर के Timer1, या तो AtMega328 का उपयोग करने की कोशिश कर रहा हूं, जैसा कि Arduino, या ATTiny85 में उपयोग किया जाता है, दो घड़ी संकेतों का उत्पादन करने के लिए जो एक दूसरे के दर्पण चित्र हैं। जिस आवृत्ति को मैं उत्पन्न करने की कोशिश कर रहा हूं वह एक चर 1 मेगाहर्ट्ज से 2 मेगाहर्ट्ज या उससे अधिक है जो आउटपुट पिन को टॉगल करने के लिए कोड का उपयोग करके ऐसा करने के लिए बहुत अधिक है जब तक कि मैं नियंत्रक में लगभग कुछ नहीं करना चाहता। इसलिए मैं संबंधित पिंस पर सीधे टाइमर आउटपुट का उपयोग करना चाहता हूं। मैं जीसीसी टूलकिन का उपयोग कर रहा हूं ताकि अरडिनो लाइब्रेरी या भाषा द्वारा सीमित न हो।

Atmega328 में Timer1 के साथ दो पिन जुड़े हैं और मैं उनमें से दो समान 1MHz से 2MHz सिग्नल प्राप्त कर सकता हूं। हालाँकि डेटशीट यह कहती है कि मुझे एक उल्टा तरंग मिल सकता है, यह मुझे भ्रमित कर रहा है। मैं दो सिग्नल प्राप्त करने में सक्षम हूं जो 1 मेगाहर्ट्ज पर अलग-अलग ड्यूटी साइकल हैं, टिमर 1 के साथ पीडब्लूएम सेटिंग्स का उपयोग करते हैं, लेकिन दोनों सिग्नल एक ही समय में उच्च जाते हैं, छोटा एक पहले कम हो जाता है। यह मेरी परियोजना की सेवा नहीं करता है। मुझे पीडब्लूएम पल्स चौड़ाई भिन्नता की भी आवश्यकता नहीं है, मुझे बस दो समान "क्लॉक" प्रकार के विपरीत चरण के संकेतों की आवश्यकता है, बस।

मैं ऐसा करने के लिए किसी से मेरे लिए कोड लिखने के लिए नहीं कह रहा हूं, मुझे सिर्फ यह बताने की जरूरत है कि टाइमर के कौन से मोड / झंडे मुझे टाइमर से जुड़े दो पिनों में से एक पर एक साधारण उल्टे तरंग दे। यदि संभव हो तो मैं आउटपुट में से किसी एक के लिए बाहरी इनवर्टिंग सर्किट का उपयोग करने से बचना चाहता हूं जब तक कि यह एकमात्र विकल्प न हो।

यदि यह एटटी में संभव है, तो यह और भी बेहतर होगा। ATTiny में एक टाइमर से जुड़े 2 पिन भी हैं, लेकिन मुझे यकीन नहीं है कि इसमें ATMega के समान विकल्प हैं।

मेरे पास पहले से ही 20 मेगाहर्ट्ज का क्रिस्टल और कैपेसिटर पीसीबी पर जुड़ा हुआ है और 20 मेगाहर्ट्ज की घड़ी ATMega328 पर मज़बूती से काम कर रही है। ATTiny85 PCB पर मेरे पास 8 MHz क्रिस्टल है और यह मज़बूती से काम भी कर रहा है।

कृपया मदद कीजिए। धन्यवाद।


अद्यतन : उत्तर और टिप्पणियों में अब तक कुछ अवैध धारणाएं हैं, शायद मुझे स्पष्ट करना चाहिए: ध्यान दें कि मैंने अपने मूल पोस्ट में कहा है कि मैं 20 मेगाहर्ट्ज घड़ी का उपयोग कर रहा हूं, 8 मेगाहर्ट्ज का नहीं , और यह भी कि मुझे PWM की आवश्यकता नहीं है

एकमात्र मोड जो एक उच्च पर्याप्त आउटपुट आवृत्ति देता है वह सीटीसी मोड लगता है क्योंकि पीडब्लूएम मोड 2 मेगाहर्ट्ज आउटपुट के लिए काम नहीं कर रहे हैं। क्या CTC मोड में या तो टाइमर 1 आउटपुट A, या आउटपुट B, इनवर्ट करने का कोई तरीका है?

मैंने अब अपने कोड की जांच करने के लिए अपने स्वयं के 20 मेगाहर्ट्ज बोर्ड के बजाय एक मानक Arduino Uno (ATMega328, 16 MHz) पर स्विच किया है, और यह 9 और 10, टाइमर से CTC मोड में एक अच्छी स्थिर 2 मेगाहर्ट्ज घड़ी के लिए मेरा कोड है। 1 आउटपुट पिन:

#define tick 9
#define tock 10

void setup() {
  pinMode(tick, OUTPUT);  
  pinMode(tock, OUTPUT); 

  TCCR1A = _BV(COM1A0) | _BV(COM1B0) ;   // activate both output pins 
  TCCR1B = _BV(WGM12)| 1;                // set CTC mode, prescaler mode 1

  // various frustrating attempts to invert OC1B failed. What do I put here?

  OCR1A = 3;                             // set the counter max for 2 MHz

}

void loop() {
}

दोनों पिनों के लिए आस्टसीलस्कप निशान समान हैं और सिंक में, मैं दोनों में से किसी भी संकेत को कैसे प्राप्त कर सकता हूं? डेटाशीट में इनवर्ट मोड CTC मोड में कुछ नहीं करने के लिए प्रकट होता है। क्या मैं डेटाशीट को गलत पढ़ रहा हूं, या क्या मुझे कम आवृत्ति और पीडब्लूएम मोड का उपयोग करने के लिए मजबूर किया जाएगा?

मेरी मूल क्वेरी में एक विशिष्ट "बाउंटी" प्रश्न जोड़ने के लिए:
इसलिए मुझे अपने कोड में ऊपर से क्या बदलाव करने की आवश्यकता है, इसे बनाने के लिए पिन 9 और 11 पर पूरी तरह से उल्टे संकेत देने के लिए 16 मेगाहर्ट्ज घड़ी के लिए उच्चतम संभव आवृत्ति पर , चाहे वह 2 मेगाहर्ट्ज है या नहीं?

मैं अभी के लिए एक मानक Arduino Uno के साथ रहूंगा, ताकि मेरे होमस्पून बोर्ड द्वारा कोई त्रुटि मोड पेश नहीं किया जा सके, और इसलिए कि कोई भी arduino वाला व्यक्ति मेरे कोड को ऊपर आज़मा सकता है और पुष्टि कर सकता है कि यह मेरे बताए अनुसार काम करता है और जैसा मैंने नहीं किया है जरुरत!


1
Atmega8L डेटाशीट के पृष्ठ 97-98 को देखते हुए , ऑपरेशन के तरीकों की एक तालिका है। पृष्ठ 108 में लिखा है "COM21: 0 बिट्स नियंत्रित करते हैं कि पीडब्लूएम आउट-जनरेट किया जाना चाहिए या नहीं (उलटा या गैर-उलटा पीडब्लूएम)"। हमें अपनी सफलता पर तैनात रखें!
वोरैक

मिररेड आउटपुट के लिए एक साधारण ट्रांजिस्टर इन्वर्टर का उपयोग क्यों नहीं किया जाता है?
जॉनी बी गुड

जवाबों:


10

ATtiny85 डेटशीट से:

ऑपरेशन का मोड, अर्थात, टाइमर / काउंटर का व्यवहार और आउटपुट की तुलना पिंस, वेवफॉर्म जेनरेशन मोड (WGM0 [2: 0]) के संयोजन से परिभाषित होती है और आउटपुट मोड की तुलना करती है (COM0x [1: 0)) बिट्स। आउटपुट मोड बिट्स की तुलना मतगणना अनुक्रम को प्रभावित नहीं करती है, जबकि वेवफॉर्म जेनरेशन मोड बिट्स करते हैं। COM0x [1: 0] बिट्स नियंत्रित करते हैं कि उत्पन्न PWM आउटपुट उलटा होना चाहिए या नहीं (उलटा या गैर-उलटा PWM )।

तालिका 11-5 से पता चलता है कि मोड को कैसे सेट किया जाए।

Mode   WGM  WGM  WGM  Timer/Counter Mode    TOP      Update of    TOV Flag
c0     02   01   00   of Operation                   OCRx at      Set on
==========================================================================
0      0    0    0    Normal                0xFF     Immediate    MAX(1)
1      0    0    1    PWM, Phase Correct    0xFF     TOP          BOTTOM
2      0    1    0    CTC                   OCRA     Immediate    MAX
3      0    1    1    Fast PWM              0xFF     BOTTOM       MAX
4      1    0    0    Reserved                                  
5      1    0    1    PWM, Phase Correct    OCRA     TOP          BOTTOM
6      1    1    0    Reserved                                  
7      1    1    1    Fast PWM              OCRA     BOTTOM       TOP

आप एक फास्ट पीडब्लूएम मोड चाहते हैं (इसलिए या तो मोड 3 या मोड 7)। यदि आप कर्तव्य चक्र को बदलना चाहते हैं, और ऐसा लगता है जैसे आप करते हैं, तो आप मोड 7 चाहते हैं और OCRA सेट करके कर्तव्य चक्र को बदलते हैं।

तालिका 11-3 से पता चलता है कि फास्ट पीडब्लूएम मोड के लिए तुलना आउटपुट मोड कैसे सेट करें।

COM0A1/   COM0A0/
COM0B1    COM0B0     Description
===============================================================================
0         0          Normal port operation, OC0A/OC0B disconnected.
0         1          Reserved
1         0          Clear OC0A/OC0B on Compare Match, set OC0A/OC0B at BOTTOM
                     (non-inverting mode)
1         1          Set OC0A/OC0B on Compare Match, clear OC0A/OC0B at BOTTOM
                     (inverting mode)

कहने का तात्पर्य यह है कि, आप टाइमर मूल्य == OCR0A और उच्च जब टाइमर मान == 0x00 को COM0A1: COM0A0 = 0b10 सेट करके कम करने के लिए OC0A आउटपुट सेट कर सकते हैं। या COM0A1: COM0A0 = 0b11 सेट करके वर्सा दें। और इसी तरह OC0B, OCR0B, COM0B0, COM0B1 के लिए।

पीडब्लूएम आवृत्ति I / O क्लॉक (8MHz यह आपके लिए जैसा लगता है) और आपके टाइमर प्रीस्कूलर सेटिंग द्वारा निर्धारित की जाती है। और फास्ट PWM मोड के लिए समीकरण f_clk_IO / (N * 256) के रूप में दिया गया है।

इसलिए आप OCR0A और OCR0B को एक ही मान पर सेट करके और COM0A1: COM0A0 = 0b10 और COM0B1: COM0B0 से 0b11 पर सेट करके "उल्टा" ध्रुवीयता के लिए OC0A का उपयोग "सामान्य" ध्रुवीयता और OC0B के लिए कर सकते हैं।

अपडेट करें

यह देखते हुए कि आप जितनी जल्दी हो सके आउटपुट को चालू करना चाहते हैं और आप 1632 मेगाहर्ट्ज पर काम कर रहे मेगा 328 का उपयोग कर रहे हैं, सीटीसी ऑपरेटिंग मोड आपको एक स्विचिंग आवृत्ति प्राप्त करने की अनुमति देगा:

f_OCnA = f_clk_IO / (2 * N * [1 + OCRnA) = 16e6 / (2 * 1 * [1 + 1]) = 4MHz

फास्ट PWM मोड आपको पिन को टॉगल करने देगा:

f_OCnxPWM = f_clk_IO / (N * [1 + TOP]) = 16e6 / (1 * [1 + 1]) = 8MHz

इसलिए मुझे अभी भी लगता है कि आप फास्ट पीडब्लूएम मोड चाहते हैं। विशेष रूप से मोड 3 OCR0A = OCR0B = 0x80 के साथ 50% कर्तव्य चक्र के लिए। और OC0A और OC0B पर एक दूसरे के दो तरंगों को बनाने के लिए COMxA बिट्स को 0x3 और COM0B बिट्स को 0x2 पर सेट करें।

# 2 अपडेट करें मेगा 328 इस Arduino कोड को आज़माएं:

#define tick 9
#define tock 10

void setup(){

  pinMode(tick, OUTPUT);  
  pinMode(tock, OUTPUT); 

  // Setup Waveform Generation Mode 15
  // OC1A Compare Output Mode = inverting mode
  // OC1B Compare Output Mode = non-inverting mode
  // Timer Prescaler = 1
  // TOP = OCR1A = 1

  //COM1A[1:0] = 0b11, COM1B[1:0] = 0b10, WGM1[1:0] = 0b11
  TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(WGM11) | _BV(WGM10);

  //WGM1[3:2] = 0b11, CS1[2:0] = 0b001
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

  OCR1A = 0x0001;
  OCR1B = 0x0001;
}

void loop(){

}

मुझे इस पर थोड़ा चबाने दो और देखो कि क्या यह काम करता है। धन्यवाद।
ExcitingProjects

आज इसे आज़माने के लिए आपके उत्तर को पढ़ने के बाद, मुझे कुछ मान्यताओं का पता चलता है: मैंने 20 मेगाहर्ट्ज घड़ी निर्दिष्ट की (और अब मैंने 16 मेगाहर्ट्ज पर स्विच किया है), " नहीं (8MHz यह आपके लिए जैसा लगता है)" । इसके अलावा, मैंने निर्दिष्ट किया कि मुझे पीडब्लूएम पल्स की चौड़ाई भिन्नता की आवश्यकता नहीं है, इसलिए यह सुनिश्चित न करें कि आपने कहां "यदि आप कर्तव्य चक्र को अलग करना चाहते हैं, और ऐसा लगता है जैसे आप करते हैं"
एक्साइटिंगप्रोजेक्ट्स

@ExcitingProjects मैं आपके कथन को बंद कर रहा था "ATTiny85 PCB पर मेरे पास 8 MHz क्रिस्टल है और यह मज़बूती से काम भी कर रहा है।" और मेरा जवाब ATtiny85 के संदर्भ में है। मैं कोशिश करूँगा और प्रतिक्रिया में अपने उत्तर को अपडेट करूंगा आपके अपडेट किए गए प्रश्न।
vicatcu

@vicateu धन्यवाद। मैंने प्रश्न को अपडेट कर दिया है, जब तक कि मुझे लगता है कि CTC मोड में कोई प्रभाव नहीं है, जब तक कि मुझे कुछ कदम याद नहीं है।
ExcitingProjects

ATmega328 डेटाशीट से @ExcitingProjects: "नॉन-पीडब्लूएम मोड्स के लिए COM0x1: 0 बिट्स नियंत्रित करते हैं कि आउटपुट सेट किया जाना चाहिए, क्लियर किया गया, या तुलना मैच में टॉगल किया जाना चाहिए"
vicatuu

1

ATtinyX5 परिवार के पास PLL है, इसे बड़े लड़के का उपयोग करें।

मैं सीपीयू घड़ी को पावर देने के लिए आंतरिक PLL का उपयोग करता हूं और XTAL के बिना 16Mhz है। यह कीमती है क्योंकि आपके पास सिर्फ 5 पिन हैं। (मैं रीसेट पिन की गिनती नहीं करता हूं)। इसके अलावा एक PLL'ed PWM (OCR1B) XTAL पिन पर चलता है, जिसमें यह वैकल्पिक मानार्थ आउटपुट है। आपको बस 16Mhz Xtalless ATtiny के लिए फ़्यूज़ को समायोजित करने की आवश्यकता है ... या बस CPU को 8Mhz में चलने दें, लेकिन फ़्यूज़ को बदले बिना 64Mhz घड़ी के साथ PWM चलाएं ..

आपके पास 64 Mhz की घड़ी PWM (लेकिन 1 बिट रिज़ॉल्यूशन) तक हो सकती है। या 125Khz @ 8 बिट रिज़ॉल्यूशन। आप OCR1C रजिस्टर को कम करके PWM रिज़ॉल्यूशन और स्पीड बढ़ा सकते हैं।

1 Mhz के लिए आपको OCR1C को 63 पर सेट करने की आवश्यकता है। 2 Mhz के लिए आपको OCR1C को 31 पर सेट करने की आवश्यकता है। 4 Mhz के लिए आपको OCR1C को 15. पर सेट करने की आवश्यकता है।

बस इस कोड के साथ PLL सक्षम करें:

PLLCSR |= (1 << PLLE);           //Start PLL
while( !(PLLCSR & (1<<PLOCK)) ); //Wait for PLL lock
//PLLCSR |= (1<<LSM );           //Low Speed PLL that clocks 32Mhz, not 64Mhz
PLLCSR |= (1 << PCKE);           //Enable PLL

अब आपके पास "OCR1B0 / OCR1A0" PWMs पर 64 मेगाहर्ट्ज घड़ी है।

इसके अलावा, आप OCR1 [A / B] 0 और XOCR1 [A / B] 0 को मिरर आउटपुट के लिए समायोजित कर सकते हैं।

if(0){ //Synch mode
     //OCR1A & XOCR1A enable for Synch operation but not allow odd PWM values!
     TCCR1 |= (1 << PWM1A) | (0 << COM1A1) | (1 << COM1A0); 
     //Also ATtinyX5 has "Dead Time Generator", use it ;)
     DTPS1 = 3;   //8x Prescaler for dead time generator (maximum)
     DT1A = 0xff; //Clk dead on both channels (maximum)
     }
   else
     TCCR1 |= (1 << PWM1A) | (1 << COM1A1) | (0 << COM1A0);  //ONLY OCR1A enabled

यदि आप OCR1A = 1 सेट करते हैं, तो आपको पता होना चाहिए कि डेड टाइम जेनरेटर PWM आउटआउट खाएगा। आपको मृत समय की तुलना में उच्च मूल्यों की आवश्यकता है।

सादर,

Erdem

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.