এটি দেখতে অদ্ভুত নয়। এটি সাধারণ এমসিইউ কোডের মতো দেখতে।
আপনার এখানে যা আছে তা মেমরি-ম্যাপযুক্ত পেরিফেরিয়ালের ধারণার একটি উদাহরণ । মূলত, এমসিইউ হার্ডওয়্যারটির জন্য নির্ধারিত এমসিইউর এসআরএএম ঠিকানা স্পেসে বিশেষ অবস্থান রয়েছে। আপনি যদি এই ঠিকানাগুলিতে লিখেন, বাইটের বিটগুলি সম্বোধন করতে n লিখে পেরিফেরিয়াল মি এর আচরণ নিয়ন্ত্রণ করে ।
মূলত, মেমরির কয়েকটি ব্যাঙ্কে আক্ষরিক অর্থে এসআরএএম সেল থেকে হার্ডওয়্যারে সামান্য তারের চলমান থাকে। আপনি যদি এই বিটটিতে একটি "1" লিখে থাকেন তবে এটি এই এসআরাম সেলটি একটি লজিকাল হাইতে সেট করে, যা পরে হার্ডওয়্যারটির কিছু অংশ চালু করে।
আপনি যদি এমসইউ-র শিরোনামগুলি লক্ষ্য করেন তবে কী-ওয়ার্ডের বড় বড় টেবিল রয়েছে <-> ঠিকানা ম্যাপিং। TCCR1B
সংকলনের সময় এভাবেই ... ইত্যাদি জিনিসগুলি সমাধান করা হয়।
এই মেমরি-ম্যাপিং প্রক্রিয়াটি এমসিইউগুলিতে অত্যন্ত বিস্তৃতভাবে ব্যবহৃত হয়। আরডুইনোর এটিমেগা এমসিইউ এটি ব্যবহার করে, যেমন পিক, এআরএম, এমএসপি 430, এসটিএম 32 এবং এসটিএম 8 এমসিইউ সিরিজ, পাশাপাশি প্রচুর এমসিইউগুলির সাথে আমি তাত্ক্ষণিকভাবে পরিচিত নই।
আরডুইনো কোড হ'ল অদ্ভুত জিনিস, এমসিইউ নিয়ন্ত্রণ অ্যাক্সেস করে এমন ফাংশনগুলি পরোক্ষভাবে নিবন্ধভুক্ত করে। যদিও এটি কিছুটা "ভাল" দেখায়, এটি আরও ধীর গতির এবং আরও অনেক প্রোগ্রাম স্পেস ব্যবহার করে।
রহস্যময় ধ্রুবকগুলি এটিমেগা 328 পি ডাটাশিটে দুর্দান্তভাবে বর্ণনা করা হয়েছে , যা আপনি সত্যিই পড়া উচিত যদি আপনি আরডুইনোতে পিন টগলিং করে আরও কিছু করার আগ্রহী হন তবে।
উপরে লিঙ্ক করা ডেটাশিট থেকে অংশগুলি নির্বাচন করুন:
সুতরাং, উদাহরণস্বরূপ, TIMSK1 |= (1 << TOIE1);
বিট সেট করে TOIE1
এ TIMSK1
। বাইনারি 1 ( 0b00000001
) TOIE1
বিট দ্বারা বামে স্থানান্তরিত করে এটি অর্জন করা হয় , TOIE1
0 হিসাবে শিরোলেখ ফাইলটিতে সংজ্ঞায়িত করা হয় এটি এর পরে বিটওয়াইডের বর্তমান মান হিসাবে অর্ড করা হয় TIMSK1
, যা কার্যকরভাবে এই এক বিটকে উচ্চতর করে দেয়।
বিট 0 এর জন্য ডকুমেন্টেশনের দিকে তাকানো TIMSK1
, আমরা দেখতে পাচ্ছি এটি হিসাবে বর্ণিত হয়েছে
এই বিটটি যখন কোনওটিতে লেখা হয়, এবং স্থিতি রেজিস্ট্রে আই-পতাকা সেট করা হয় (বিশ্বব্যাপী সক্ষম হওয়া বাধাগ্রস্ত হয়), টাইমার / কাউন্টার 1 ওভারফ্লো বাধা সক্ষম হয়। টিআইএফআর 1 এ অবস্থিত টিওভি 1 ফ্ল্যাগটি সেট করা হলে সংশ্লিষ্ট ইন্টারপেন ভেক্টর (57 পৃষ্ঠায় "বাধা" দেখুন) কার্যকর করা হয়।
অন্যান্য সমস্ত লাইন একই পদ্ধতিতে ব্যাখ্যা করা উচিত।
কিছু নোট:
আপনি দেখতে পছন্দ করতে পারেন TIMSK1 |= _BV(TOIE1);
। মূলত AVR libc বাস্তবায়ন থেকে ব্যবহৃত_BV()
একটি সাধারণ ব্যবহৃত ম্যাক্রো । আরও ভাল পাঠযোগ্যতার সুবিধার সাথে কার্যত অভিন্ন ident_BV(TOIE1)
(1 << TOIE1)
এছাড়াও, আপনি লাইনগুলি যেমন দেখতে পারেন: TIMSK1 &= ~(1 << TOIE1);
বা TIMSK1 &= ~_BV(TOIE1);
। এই বিপরীত ফাংশন আছে TIMSK1 |= _BV(TOIE1);
যে এটা unsets বিট TOIE1
মধ্যে TIMSK1
। এটি উত্পাদিত বিট-মাস্ক গ্রহণ করে _BV(TOIE1)
, এতে বিটওয়াইস নট অপারেশন ( ~
) চালিয়ে এবং এরপরে TIMSK1
এই নোটযুক্ত মানটি (যা 0 বি 11111110) দ্বারা অ্যান্ডিং করে অর্জন করা হয়।
মনে রাখবেন যে এই সমস্ত ক্ষেত্রে, কম্পাইল করার সময়(1 << TOIE1)
বা _BV(TOIE1)
তার মতো সামগ্রীর মান পুরোপুরি সমাধান করা হয় , তাই এগুলি কার্যকরীভাবে একটি সাধারণ ধ্রুবককে হ্রাস করে এবং তাই রানটাইমের সময় গণনা করতে কোনও কার্যকর সময় নেয় না।
সঠিকভাবে লিখিত কোডগুলিতে সাধারণত কোডগুলির সাথে ইনলাইন কমেন্ট থাকবে যাতে রেজিস্ট্রিগুলিকে কী নির্ধারিত করা হচ্ছে তা বিশদ রয়েছে। এখানে আমি সম্প্রতি লিখেছি মোটামুটি সরল নরম-এসপিআই রুটিন:
uint8_t transactByteADC(uint8_t outByte)
{
// Transfers one byte to the ADC, and receives one byte at the same time
// does nothing with the chip-select
// MSB first, data clocked on the rising edge
uint8_t loopCnt;
uint8_t retDat = 0;
for (loopCnt = 0; loopCnt < 8; loopCnt++)
{
if (outByte & 0x80) // if current bit is high
PORTC |= _BV(ADC_MOSI); // set data line
else
PORTC &= ~(_BV(ADC_MOSI)); // else unset it
outByte <<= 1; // and shift the output data over for the next iteration
retDat <<= 1; // shift over the data read back
PORTC |= _BV(ADC_SCK); // Set the clock high
if (PINC & _BV(ADC_MISO)) // sample the input line
retDat |= 0x01; // and set the bit in the retval if the input is high
PORTC &= ~(_BV(ADC_SCK)); // set clock low
}
return retDat;
}
PORTC
এটি নিবন্ধ যা PORTC
এটিমেগ 328 পি এর মধ্যে আউটপুট পিনের মান নিয়ন্ত্রণ করে । PINC
নিবন্ধটি যেখানে ইনপুট মানগুলি PORTC
উপলব্ধ। মৌলিকভাবে, এর মতো জিনিসগুলি হ'ল অভ্যন্তরীণভাবে ঘটে যখন আপনি ব্যবহার করেন digitalWrite
বা digitalRead
ফাংশন ব্যবহার করেন । যাইহোক, একটি চেহারা অপারেশন রয়েছে যা আরডুইনো "পিন নম্বরগুলি" কে সত্যিকারের হার্ডওয়্যার পিন সংখ্যায় রূপান্তর করে যা 50 ঘড়ির চক্রের রাজ্যে কোথাও নিয়ে যায়। আপনি সম্ভবত অনুমান করতে পারেন, আপনি যদি দ্রুত এগিয়ে যাওয়ার চেষ্টা করছেন, তবে অপারেশনে 50 টি ঘড়ির চক্র নষ্ট করা কেবলমাত্র 1 টির হাস্যকর।
উপরের ফাংশনটি সম্ভবত 8 টি বিট স্থানান্তর করতে 100-200 ঘড়ির চক্রের অঞ্চলে লাগে somewhere এটিতে 24 টি পিন-রাইটস এবং 8 টি পড়ার দরকার রয়েছে। এটি digital{stuff}
ফাংশনগুলি ব্যবহার করে অনেকগুলি অনেক বেশি দ্রুত faster