CTC मोड में टाइमर 3 सेट करना - सर्वो लाइब्रेरी के साथ संघर्ष


10

मैं फ़ंक्शन को प्रति सेकंड 800 बार कॉल करने के लिए एक टाइमर सेट करना चाहूंगा। मैं 1024 के एक प्रीस्कूलर के साथ Arduino मेगा और टिमर 3 का उपयोग कर रहा हूं। मैंने जो प्रीस्कूलर फैक्टर चुना है, उसे चुनने के लिए निम्नलिखित चरण देखें:

  • CPU फ्रीक: 16MHz
  • समय संकल्प: 65536 (16 बिट)
  • 16x10 ^ 6 /: चुना prescaler से विभाजित सीपीयू freq 1024 = 15625
  • बाकी को वांछित फ्रीक 62500/800 = 19 के माध्यम से विभाजित करें ।
  • परिणाम + 1 को OCR3 रजिस्टर में डालें।

मैंने TCCR3B के रजिस्टर सेट करने के लिए निम्न तालिका का उपयोग किया है:

यहां छवि विवरण दर्ज करें

त्रुटि

कोड को संकलित करना असंभव है। यह कंपाइलर द्वारा दी गई त्रुटि है:

सर्वो \ Servo.cpp.o: फ़ंक्शन में '__vector_32': C: \ Program Files (x86) \ Arduino \ पुस्तकालयों \ Servo.cpp: 110: '__vector -32' AccelPart1_35.cpp.o: C: \: की कई परिभाषाएँ प्रोग्राम फाइल्स (x86) \ Arduino / AccelPart1_35.ino: 457: पहली बार यहाँ c: / प्रोग्राम फाइल्स (x86) / arduino / हार्डवेयर / टूल्स / avr / bin /../ lib / gcc / avr / 4.3.2 / को परिभाषित किया गया है। ./../../..//r/bin/ld.exe: छूट को अक्षम करना: यह कई परिभाषाओं के साथ काम नहीं करेगा

कोड

volatile int cont = 0;
unsigned long aCont = 0;
void setup()
{
 [...]
  // initialize Timer3
  cli();          // disable global interrupts
  TCCR3A = 0;     // set entire TCCR3A register to 0
  TCCR3B = 0;     // same for TCCR3B

  // set compare match register to desired timer count: 800 Hz
  OCR3A = 20;
  // turn on CTC mode:
  TCCR3B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR3B |= (1 << CS30) | (1 << CS32);
  // enable timer compare interrupt:
  TIMSK3 |= (1 << OCIE3A);
  // enable global interrupts:
  sei();
}

void loop()
{
 // Print every second the number of ISR invoked -> should be 100
 if ( millis() % 1000 == 0)
 {
   Serial.println();
   Serial.print(" tick: ");
   Serial.println(contatore);
   contatore = 0;
 }
}

[...]

// This is the 457-th line
ISR(TIMER3_COMPA_vect)
{
    accRoutine();
    contatore++;
}

void accRoutine()
{
  // reads analog values
}

इमदादी पुस्तकालय के साथ संघर्ष को हल करने के लिए कैसे?

समाधान

निम्नलिखित कोड का उपयोग करके संघर्ष हल किया गया। यह संकलित करता है लेकिन 800Hz टाइमर से जुड़ा काउंटर इसके मूल्य में वृद्धि नहीं करता है।

volatile int cont = 0;

void setup()
{
  Serial.begin(9600);
  // Initialize Timer
  cli();          // disable global interrupts
  TCCR3A = 0;     // set entire TCCR3A register to 0
  TCCR3B = 0;     // same for TCCR3B

  // set compare match register to desired timer count: 800 Hz
  OCR3B = 20;
  // turn on CTC mode:
  TCCR3B |= (1 << WGM12);
  // Set CS10 and CS12 bits for 1024 prescaler:
  TCCR3B |= (1 << CS30) | (1 << CS32);
  // enable timer compare interrupt:
  TIMSK3 |= (1 << OCIE3B);
  // enable global interrupts:
  sei();

  Serial.println("Setup completed");
}

void loop()
{
  if (millis() % 1000 == 0)
  {
    Serial.print(" tick: ");
    Serial.println(cont);
    cont = 0;
  }
}

ISR(TIMER3_COMPB_vect)
{
  cont++;
}

चूंकि मुख्य समस्या हल हो गई है, इसलिए मैंने काउंटर इन्क्रीप्शन की समस्या से संबंधित एक और प्रश्न यहां बनाया है ।


क्या आप अपने प्रोगाम में सर्वो लाइब्रेरी का उपयोग करते हैं या नहीं?
jfpoilpret

2
Servo.cpp संभावित ISR (TIMER3_COMPA_vect)
TMa

1
इसके बजाय सिर्फ टाइमर 1, 4 या 5 का उपयोग करें।
गेरबेन

1
सर्वो ने COMPA के लिए megas पर टाइमर 1,3,4 और 5 के लिए रुकावट कार्यों को परिभाषित किया। COMPB का उपयोग कैसे करें?
ब्रेटतम

1
आप सही कह रहे हैं । वे सिर्फ सभी टाइमर लगा रहे हैं। मुझे लगता है कि आपको #define _useTimer3लाइन को हटाकर पुस्तकालय को थोड़ा बदलना होगा , या #undef _useTimer3शामिल करने के बाद एक सही डालने का प्रयास करना होगा।
गेरबन 19

जवाबों:


4

दुर्भाग्य से, सर्वो पुस्तकालय भंडार का उत्पादन ए, (आरसीआर * ए) की तुलना टाइमर पर 1,3,4, और 5 जब एक आर्किनो मेगा पर लोड होता है। प्रत्येक में केवल एक ISR हो सकता है, इसलिए आप लायब्रेरी को संशोधित किए बिना सर्वो का उपयोग करते समय अपने स्वयं के समय * _COMPA_vect को परिभाषित करने में सक्षम नहीं होंगे।

हालांकि, प्रत्येक हार्डवेयर टाइमर रजिस्टरों की तुलना में 2 आउटपुट से लैस है। सर्वो किसी भी TIMER का दावा नहीं करता * _COMPB_vect इंटरप्ट करता है, इसलिए वे उपयोग करने के लिए स्वतंत्र हैं, और बिल्कुल उसी तरह काम करते हैं।

आपको सर्वो लाइब्रेरीज़ गतिविधियों के लिए बाहर देखना चाहिए, यह आपके टाइमर के कॉन्फ़िगरेशन को बदल सकता है। डिफ़ॉल्ट ऑर्डर megas पर है 5,1,3,4 और प्रत्येक 12 सर्वो को देने के लिए। इसे जरूरत पड़ने पर ही यह टाइमर को कॉन्फ़िगर करता है, इसलिए जब तक आप उस 25 वें सर्वो को जोड़ते हैं, तब तक आपको टाइमर 3 का उपयोग करके ठीक होना चाहिए।

अपना कोड बदलने के लिए, OCR3A (आउटपुट तुलना रजिस्टर) के बजाय OCR3B का उपयोग करें और TIMSK3 में OCIE3A के बजाय बिट OCIE3B सेट करें (आउटपुट इंटरप्ट इनेबल बिट्स की तुलना करें)। फिर आपको अपने ISR फ़ंक्शन को बदलना होगा ISR(TIMER3_COMPB_vect){}

CTC मोड केवल OCR3A के साथ काम करता है, लेकिन यदि आप अपने रुकावट फ़ंक्शन में TCNT3 से 0 सेट करते हैं तो आप समान व्यवहार प्राप्त कर सकते हैं। WGM12 का उपयोग करने पर CTC मोड को चालू करने वाली लाइन को हटाने के लिए याद रखें।


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