একটি বিঘ্নিত রুটিনের মধ্যে মিলিস () এবং মাইক্রো () ব্যবহার করা


13

এর জন্য ডকুমেন্টেশন attachInterrupt()বলেছেন:

... millis()গণনা করতে বাধা নির্ভর করে, তাই এটি কোনও আইএসআরের অভ্যন্তরে কখনই বাড়বে না। যেহেতু delay()কাজ করতে বাধা প্রয়োজন, কোনও আইএসআরের অভ্যন্তরে ডাকা হলে এটি কাজ করবে না। micros()প্রাথমিকভাবে কাজ করে তবে 1-2 এমএসের পরে ভ্রান্তভাবে আচরণ শুরু করবে। ...

(তাদের যথার্থতার জন্য অবশ্যই বাদে) কীভাবে micros()আলাদা হয় millis()? উপরোক্ত সতর্কতাটির অর্থ কি micros()কোনও বাধা রুটিনের অভ্যন্তরে ব্যবহার করা সর্বদা একটি খারাপ ধারণা?

প্রসঙ্গ - আমি কম পালস পেশা পরিমাপ করতে চাই , সুতরাং আমার ইনপুট সিগন্যাল পরিবর্তিত হয়ে বর্তমান সময়টি রেকর্ড করার সময় আমার রুটিনটি ট্রিগার করা দরকার।

উত্তর:


16

অন্যান্য উত্তরগুলি খুব ভাল তবে আমি কীভাবে micros()কাজ করে তা বিশদতে চাই । এটি সর্বদা বর্তমান হার্ডওয়্যার টাইমার পড়ে থাকে (সম্ভবত TCNT0) যা নিয়মিতভাবে হার্ডওয়্যার দ্বারা আপডেট করা হয় (প্রকৃতপক্ষে, প্রতি 4 µs কারণ pres৪ এর প্রেসক্যালারের কারণে)। এটি টাইমার 0 ওভারফ্লো গণনায় যোগ করে, যা টাইমার ওভারফ্লো বাধা (256 দ্বারা গুণিত) দ্বারা আপডেট হয়।

সুতরাং, এমনকি কোনও আইএসআরের অভ্যন্তরেও আপনি micros()আপডেট করার উপর নির্ভর করতে পারেন । তবে আপনি যদি খুব বেশি অপেক্ষা করেন তবে আপনি ওভারফ্লো আপডেটটি মিস করেন এবং তারপরে ফিরে আসা ফলাফলটি নীচে নেমে আসবে (যেমন আপনি 253, 254, 255, 0, 1, 2, 3 ইত্যাদি পাবেন)

এটি হ'ল micros()- অন্যান্য প্রসেসরের জন্য সংজ্ঞাগুলি সরানোর জন্য সামান্য সরলীকৃত:

unsigned long micros() {
    unsigned long m;
    uint8_t oldSREG = SREG, t;
    cli();
    m = timer0_overflow_count;
    t = TCNT0;
    if ((TIFR0 & _BV(TOV0)) && (t < 255))
        m++;
    SREG = oldSREG;
    return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

উপরের কোডটি ওভারফ্লোর জন্য অনুমতি দেয় (এটি TOV0 বিটটি পরীক্ষা করে) তাই এটি ওভারফ্লো সহ্য করতে পারে যখন বিরতিগুলি বন্ধ থাকে তবে কেবল একবার - দুটি ওভারফ্লো পরিচালনা করার কোনও ব্যবস্থা নেই।


TLDR;

  • কোনও আইএসআরের অভ্যন্তরে বিলম্ব করবেন না
  • যদি আপনার অবশ্যই তা করা হয় micros()তবে আপনি সময় সহ করতে পারেন তবে তা করতে পারেন না millis()। এছাড়াও delayMicroseconds()একটি সম্ভাবনা।
  • 500 ডিগ্রি বা তার বেশি বিলম্ব করবেন না, বা আপনি একটি টাইমার ওভারফ্লো মিস করবেন।
  • এমনকি সংক্ষিপ্ত বিলম্বের কারণে আপনি আগত সিরিয়াল ডেটা মিস করতে পারেন (115200 বাউডে আপনি প্রতি 87 µ সে একটি নতুন চরিত্র পাবেন)।

নীচে প্রদত্ত বিবৃতিটি মাইক্রোতে ব্যবহার করা হয় তা বুঝতে সক্ষম হন না ()। আপনি দয়া করে বিস্তারিত বলতে পারেন? যেহেতু আইএসআর লেখা হয়েছে, আইএসআর প্রবেশের সাথে সাথে TOV0 পতাকা সাফ হবে এবং সুতরাং নীচের শর্তটি সত্য না হয়ে যেতে পারে! যদি ((TIFR0 & _BV (TOV0)) && (t <255%) মি ++;
রাজেশ

micros()আইএসআর নয়। এটি একটি সাধারণ কাজ। TOV0 পতাকাটি আপনাকে টাইমার ওভারফ্লো হয়েছে কিনা তা পরীক্ষা করার জন্য হার্ডওয়্যারটি পরীক্ষা করতে দেয় (তবে এখনও প্রক্রিয়া করা হয়নি)।
নিক গ্যামন

যেহেতু পরীক্ষাটি বাধাগুলি দিয়ে করা হয়ে থাকে আপনি জানেন যে পরীক্ষার সময় পতাকাটি পরিবর্তন হবে না।
নিক গ্যামন

সুতরাং আপনি মাইক্রো () ফাংশনের ভিতরে ক্লিপ () এর পরে বলতে চাইছেন, যদি কোনও ওভারফ্লো হয় তবে তা পরীক্ষা করা দরকার? যে বুদ্ধিমান। অন্যথায় মাইক্রোস একটি ফাংশন না হলেও, টিআইএমআর 0_OVF_vect আইএসআর টিআইএফআর 0 এ TOV0 সাফ করবে যে আমার সন্দেহ ছিল।
রাজেশ

এছাড়াও টিসিএনটি 0 কে কেন 255 এর তুলনায় তুলনা করা হচ্ছে তা 255 এর চেয়ে কম কিনা? ক্লায়ারের পরে () টিসিএনটি 0 255 এ পৌঁছালে কী হবে?
রাজেশ

8

এটি ব্যবহার করা বা একটি বিঘ্নিত রুটিনের মধ্যে ভুল নয় ।millis()micros()

এটা তোলে হয় তাদের ভুল ব্যবহার করতে ভুল।

এখানে মূল বিষয়টি হ'ল আপনি যখন একটি বাধা রুটিনে রয়েছেন তখন "ঘড়িটি টিক দিচ্ছে না"। millis()এবং micros()পরিবর্তন হবে না ( micros()প্রথমে ভাল, শুরুতে হবে, তবে একবার যে ম্যাজিক মিলিসেকেন্ড পয়েন্ট যেতে হবে যেখানে একটি মিলিসেকেন্ড টিক প্রয়োজন হয় এটি সমস্ত পৃথক পৃথকভাবে পড়ে যায়।)

সুতরাং আপনি অবশ্যই উপর কল করতে পারেন millis()বা micros()আপনার ISR মধ্যে বর্তমান সময় খুঁজে বের করতে কিন্তু পরিবর্তনের সেই সময় আশা করবেন না।

আপনার প্রদত্ত উক্তিটি সম্পর্কে সতর্ক করা হচ্ছে এমন সময়ে পরিবর্তনের অভাব। কত সময় কেটে গেছে তা জানতে পরিবর্তনের delay()উপর নির্ভর করে millis()। যেহেতু এটি পরিবর্তন হয় delay()না কখনই শেষ করতে পারে না।

অতএব মূলত millis()এবং micros()আপনাকে সময়টি বলবে যখন আপনার আইএসআর যখন আপনি যখন তাদের আইএসআর থাকবেন তখন আপনি সেগুলি ব্যবহার করেন তা বিবেচ্য নয়।


3
না, micros()আপডেট। এটি সর্বদা হার্ডওয়্যার টাইমার রেজিস্টার পড়ে reads
নিক গ্যামন

4

উদ্ধৃত শব্দগুচ্ছ না একটি সতর্কবার্তা, এটা নিছক কিভাবে জিনিসগুলো কাজ সম্পর্কে একটি বিবৃতি হল।

সঠিকভাবে লিখিত বিঘ্নিত রুটিন ব্যবহার millis()বা অভ্যন্তরের অভ্যন্তরীণ কিছু নেই micros()

অন্যদিকে, অযথাই-লিখিত বিঘ্নিত রুটিনের মধ্যে মোটেও কিছু করা সংজ্ঞা দ্বারা ভুল।

একটি বাধা রুটিন যা কিছু কাজ করার জন্য কয়েকটি মাইক্রোসেকেন্ডের বেশি নেয়, সম্ভবত সমস্ত ক্ষেত্রেই এটি ভুলভাবে লেখা।

সংক্ষেপে বলতে গেলে: একটি সঠিকভাবে লেখা বিঘ্ন রুটিন কারণ বা সাক্ষাত সমস্যা হবে না millis()বা micros()

সম্পাদনা: "কেন মাইক্রো ()" ত্রুটিযুক্ত আচরণ শুরু করে "" সম্পর্কিত, " আরডুইনো মাইক্রো ফাংশন পরীক্ষা " ওয়েবপৃষ্ঠায় বর্ণিত হিসাবে , micros()একটি সাধারণ ইউনোর কোড কার্যত সমতুল্য

unsigned long micros() {
  return((timer0_overflow_count << 8) + TCNT0)*(64/16);
}

এটি timer0_overflow_countটাইমার -0 গণনা নিবন্ধের তিনটি সর্বনিম্ন বাইট এবং একটি বাইট সমন্বয়ে একটি চার-বাইট স্বাক্ষরযুক্ত দীর্ঘ প্রত্যাবর্তন করে ।

timer0_overflow_countএকবার দ্বারা মিলিসেকেন্ডে প্রতি মান বৃদ্ধি হয় TIMER0_OVF_vectবিঘ্ন হ্যান্ডলার, একটি ব্যাখ্যা Arduino Millis ফাংশনের পরীক্ষা ওয়েবপেজ।

একটি বাধাপ্রাপ্ত হ্যান্ডলার শুরু হওয়ার আগে, AVR হার্ডওয়্যার বাধা অক্ষম করে। যদি (উদাহরণস্বরূপ) একটি বিঘ্নিত হ্যান্ডলারটি এখনও নিষ্ক্রিয় হওয়া বাধা সহ পাঁচ মিলি সেকেন্ডের জন্য চালানো হয় তবে কমপক্ষে চারটি টাইমার 0 ওভারফ্লো মিস হবে। [আরডুইনো সিস্টেমে সি কোডে লিখিত বাধাগুলি পুনরায় তদন্তকারী নয় (একই হ্যান্ডলারের মধ্যে একাধিক ওভারল্যাপিং ফাঁসি কার্যকরভাবে পরিচালনা করতে সক্ষম) তবে কেউ একটি পুনর্বারক সমাবেশ ভাষা হ্যান্ডলার লিখতে পারে যা একটি সময়সাপেক্ষ প্রক্রিয়া শুরুর আগে বাধা পুনরায় সক্ষম করে]]

অন্য কথায়, টাইমার ওভারফ্লোগুলি "স্ট্যাক আপ" করে না; যখনই সামনে পূর্ববর্তী ওভারফ্লো থেকে বিঘ্ন ঘাঁটা হয়েছে একটি ওভারফ্লো ঘটে, millis()পাল্টা একটি মিলিসেকেন্ডে হারায়, এবং অমিল timer0_overflow_countঘুরে তোলে micros()একটি মিলিসেকেন্ডে খুব দ্বারা ভুল।

বাধা প্রক্রিয়াকরণের জন্য একটি উচ্চতর সময়সীমা হিসাবে "500 ডিগ্রি এর চেয়ে কম" সম্পর্কে, "টাইমারকে খুব বেশি সময়ের জন্য বাধা দেওয়া রোধ করতে", আপনি কেবল 1024 ডিগ্রি (যেমন 1020 μ সে) এর অধীনে যেতে পারেন এবং millis()বেশিরভাগ ক্ষেত্রেই কাজ করতে পারবেন সময়। তবে, আমি একটি বাধাপ্রাপ্ত হ্যান্ডলারটিকে বিবেচনা করি যা 5% এর চেয়ে বেশি আস্তর হিসাবে নেয়, 10 than এর চেয়ে বেশি আস্তে, 20 than এর চেয়ে বেশি শামুকের মতো।


আপনি কীভাবে "কীভাবে জিনিসগুলি কাজ করে" micros()বিশদটি ব্যাখ্যা করতে পারেন, বিশেষত কেন "ক্ষতিকারক আচরণ শুরু করুন"? এবং "সঠিকভাবে লিখিত বিঘ্নিত রুটিন" বলতে কী বোঝ? আমি ধরে নিচ্ছি এর অর্থ "500us এর চেয়ে কম" (টাইমারকে খুব বেশি সময়ের জন্য বাধা দেওয়া রোধ করতে), "যোগাযোগের জন্য উদ্বায়ী ভেরিয়েবলগুলি ব্যবহার করা" এবং "লাইব্রেরি কোডটিতে কল করা না যতটা সম্ভব", অন্য কিছু আছে কি?
পেটর পুদলেক

@ পেটরপুদলক, সম্পাদনা দেখুন
জেমস ওয়াল্ডবি - jwpat7
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.