সুচিপত্র:

AVR Assembler টিউটোরিয়াল 3: 9 ধাপ
AVR Assembler টিউটোরিয়াল 3: 9 ধাপ

ভিডিও: AVR Assembler টিউটোরিয়াল 3: 9 ধাপ

ভিডিও: AVR Assembler টিউটোরিয়াল 3: 9 ধাপ
ভিডিও: Can You Reattach a Severed Finger? 🤔 2024, জুলাই
Anonim
AVR Assembler টিউটোরিয়াল 3
AVR Assembler টিউটোরিয়াল 3

টিউটোরিয়াল নম্বর 3 এ স্বাগতম!

আমরা শুরু করার আগে আমি একটি দার্শনিক কথা বলতে চাই। এই টিউটোরিয়ালগুলিতে আমরা যে সার্কিট এবং কোডটি তৈরি করছি তা নিয়ে পরীক্ষা করতে ভয় পাবেন না। চারপাশে তারের পরিবর্তন করুন, নতুন উপাদান যোগ করুন, উপাদানগুলি বের করুন, কোডের লাইন পরিবর্তন করুন, নতুন লাইন যোগ করুন, লাইন মুছে দিন এবং দেখুন কী হয়! কোন কিছু ভেঙ্গে ফেলা খুব কঠিন এবং যদি আপনি তা করেন, কে পরোয়া করে? মাইক্রোকন্ট্রোলার সহ আমরা যা কিছু ব্যবহার করছি তা খুব ব্যয়বহুল এবং জিনিসগুলি কীভাবে ব্যর্থ হতে পারে তা দেখতে সর্বদা শিক্ষামূলক। পরের বার কী করবেন না তা আপনি কেবল খুঁজে পাবেন তা নয়, আরও গুরুত্বপূর্ণ, আপনি এটি কেন করবেন না তা জানতে পারবেন। তুমি যদি আমার মত কিছু হও, যখন তুমি ছিলে এবং তুমি একটি নতুন খেলনা পেয়েছো এটা খুব বেশি আগে ছিল না যে টুকরো টুকরো করে দেখেছিল কি এটা ঠিক টিক দিয়েছে? কখনও কখনও খেলনাটি অপূরণীয়ভাবে ক্ষতিগ্রস্ত হয় কিন্তু কোন বড় ব্যাপার নয়। একটি শিশুকে তার কৌতূহল অন্বেষণ করার অনুমতি দেওয়া এমনকি ভাঙা খেলনার বিন্দু পর্যন্ত যা তাকে ডিশওয়াশারের পরিবর্তে বিজ্ঞানী বা ইঞ্জিনিয়ারে পরিণত করে।

আজ আমরা একটি খুব সহজ সার্কিট ওয়্যারিং করতে যাচ্ছি এবং তারপরে তত্ত্বে কিছুটা ভারী হয়ে যাচ্ছি। এই জন্য দু Sorryখিত, কিন্তু আমাদের সরঞ্জাম প্রয়োজন! আমি প্রতিশ্রুতি দিচ্ছি যে আমরা টিউটোরিয়াল 4 এ এর জন্য তৈরি করব যেখানে আমরা আরও কিছু গুরুতর সার্কিট বিল্ডিং করব এবং ফলাফলটি বেশ দুর্দান্ত হবে। যাইহোক, এই সমস্ত টিউটোরিয়ালগুলি আপনাকে যেভাবে করতে হবে তা খুব ধীর, মননশীল পদ্ধতিতে। আপনি যদি কেবল লাঙ্গল, সার্কিট তৈরি করেন, কোডটি অনুলিপি এবং আটকান এবং তারপর এটি চালান, অবশ্যই, এটি কাজ করবে, কিন্তু আপনি কিছু শিখবেন না। আপনাকে প্রতিটি লাইন সম্পর্কে চিন্তা করতে হবে। বিরতি। পরীক্ষা। উদ্ভাবন। যদি আপনি এইভাবে করেন তাহলে ৫ ম টিউটোরিয়ালের শেষে আপনি ঠান্ডা জিনিস তৈরির কাজ বন্ধ করে দেবেন এবং আর কোন টিউটরিং এর প্রয়োজন হবে না। অন্যথায় আপনি কেবল শিখছেন এবং তৈরি করার চেয়ে দেখছেন।

যাই হোক না কেন, যথেষ্ট দর্শন, আসুন শুরু করা যাক!

এই টিউটোরিয়ালে আপনার প্রয়োজন হবে:

  1. আপনার প্রোটোটাইপিং বোর্ড
  2. একটি LED
  3. তারের সংযোগ
  4. 220 থেকে 330 ohms এর কাছাকাছি একটি প্রতিরোধক
  5. নির্দেশিকা সেট ম্যানুয়াল: www.atmel.com/images/atmel-0856-avr-instruction-se…
  6. ডেটাশীট: www.atmel.com/images/Atmel-8271-8-bit-AVR- মাইক্রো…
  7. একটি ভিন্ন স্ফটিক দোলক (alচ্ছিক)

এখানে টিউটোরিয়ালগুলির সম্পূর্ণ সংগ্রহের একটি লিঙ্ক রয়েছে:

ধাপ 1: সার্কিট গঠন

সার্কিট নির্মাণ
সার্কিট নির্মাণ

এই টিউটোরিয়ালের সার্কিট অত্যন্ত সহজ। আমরা মূলত "ব্লিঙ্ক" প্রোগ্রাম লিখতে যাচ্ছি তাই আমাদের যা দরকার তা হল নিম্নলিখিতগুলি।

একটি LED কে PD4 তে হুক আপ করুন, তারপর একটি 330 ওহম প্রতিরোধক, তারপর গ্রাউন্ডে। যেমন

PD4 - LED - R (330) - GND

এবং এটা!

তত্ত্বটি কঠিন স্লগিং হতে যাচ্ছে যদিও …

ধাপ 2: আমাদের কেন মন্তব্য এবং M328Pdef.inc ফাইল দরকার?

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

এখানে আমরা আজ যে কোডটি লিখতে যাচ্ছি, তা ছাড়া আমি মন্তব্যগুলি এবং অন্তর্ভুক্ত ফাইলটি সরিয়েছি:

ডিভাইস ATmega328P

.org 0x0000 জেএমপি এ। cbi 0x0b, 0x04 rcall c rjmp bc: clr r17 d: cpi r17, 0x1e brne d ret e: inc r17 cpi r17, 0x3d brne PC+2 clr r17 reti

বেশ সহজ ডান? হাহাহা। যদি আপনি এই ফাইলটি একত্রিত করেন এবং আপলোড করেন তাহলে আপনি প্রতি সেকেন্ডে 1 টি ব্লিংক হারে LED টিকে জ্বলজ্বল করতে পারবেন যার সাথে ব্লিংকটি 1/2 সেকেন্ড স্থায়ী হবে এবং 2/2 সেকেন্ড স্থায়ী ব্লিঙ্কগুলির মধ্যে বিরতি হবে।

যাইহোক, এই কোডটি দেখতে খুব কমই আলোকিত। আপনি যদি এইরকম কোড লিখতেন এবং ভবিষ্যতে এটি সংশোধন করতে বা পুনর্নির্মাণ করতে চান তবে আপনার একটি কঠিন সময় হবে।

সুতরাং আসুন মন্তব্য করা যাক এবং ফাইলটি আবার অন্তর্ভুক্ত করা যাক যাতে আমরা এর কিছুটা ধারণা করতে পারি।

ধাপ 3: Blink.asm

এই কোডটি আমরা আজ আলোচনা করব:

;************************************

; লিখেছেন: 1o_o7; তারিখ: সংস্করণ: 1.0; ফাইলটি এইভাবে সংরক্ষিত হয়েছে: blink.asm; AVR এর জন্য: atmega328p; ঘড়ির ফ্রিকোয়েন্সি: 16MHz (alচ্ছিক); **************************************; প্রোগ্রাম ফাংশন: ---------------------; একটি LED ঝলকানি দ্বারা সেকেন্ড বন্ধ গণনা;; PD4 - LED - R (330 ohm) - GND;; --------------------------------------.নলিস্ট। অন্তর্ভুক্ত "./m328Pdef.inc".list; ================; ঘোষণা:.def temp = r16.def overflows = r17.org 0x0000; মেমরি (পিসি) রিসেট হ্যান্ডলারের অবস্থান rjmp রিসেট; jmp খরচ 2 cpu চক্র এবং rjmp খরচ মাত্র 1; তাই যতক্ষণ না আপনাকে 8k বাইটের বেশি লাফাতে হবে; আপনার শুধুমাত্র rjmp প্রয়োজন। কিছু মাইক্রোকন্ট্রোলার তাই শুধুমাত্র; rjmp আছে এবং jmp নয়.org 0x0020; টাইমার 0 ওভারফ্লো হ্যান্ডলার মেমরি লোকেশন rjmp overflow_handler; একটি টাইমার 0 ওভারফ্লো বাধা ঘটলে এখানে যান; ============ রিসেট করুন: ঘড়ি নির্বাচক বিট CS00, CS01, CS02 থেকে 101 সেট করুন; এটি FCPU/1024 মোডে টাইমার কাউন্টার 0, TCNT0 রাখে; তাই এটি CPU freq/1024 ldi temp, 0b00000001 sts TIMSK0, temp এ টিক দেয়; টাইমার ওভারফ্লো ইন্টারাপ্ট এনাবল (TOIE0) বিট সেট করুন; টাইমার ইন্টারাপ্ট মাস্ক রেজিস্টার (TIMSK0) sei; বৈশ্বিক বাধা সক্ষম করুন - "sbi SREG, I" এর সমতুল্য TCNT0, temp; টাইমার/কাউন্টার শুরু করুন 0 sbi DDRD, 4; PD4 আউটপুট সেট করুন; ========================; প্রোগ্রামের প্রধান অংশ: চোখের পলক: sbi PORTD, 4; PD4 rcall বিলম্বের উপর LED চালু করুন; বিলম্ব হবে 1/2 সেকেন্ড cbi PORTD, 4; PD4 rcall বিলম্বের উপর LED বন্ধ করুন; বিলম্ব 1/2 সেকেন্ড rjmp ঝলক হবে; শুরু বিলম্ব ফিরে লুপ: clr overflows; ওভারফ্লো সেট করুন 0 sec_count: cpi overflows, 30; ওভারফ্লো সংখ্যা এবং 30 brne sec_count তুলনা করুন; সমান ret না হলে sec_count এ শাখা ফিরে যান; যদি 30 টি ওভারফ্লো ঝলক দিয়ে ফিরে আসে overflow_handler: inc overflows; ওভারফ্লো ভেরিয়েবল সিপিআই ওভারফ্লোতে 1 যোগ করুন, 61; 61 brne PC+2 এর সাথে তুলনা করুন; প্রোগ্রাম কাউন্টার + 2 (পরবর্তী লাইন এড়িয়ে যান) যদি সমান clr ওভারফ্লো না হয়; যদি 61 ওভারফ্লো ঘটে তবে কাউন্টারটি শূন্য রেটিতে রিসেট করুন; বাধা থেকে ফিরে

আপনি দেখতে পাচ্ছেন, আমার মন্তব্যগুলি এখন একটু সংক্ষিপ্ত। একবার আমরা যখন নির্দেশিকা সেটে কী কমান্ড জানি তা আমাদের মন্তব্যগুলিতে ব্যাখ্যা করার দরকার নেই। প্রোগ্রামের দৃষ্টিকোণ থেকে কী চলছে তা আমাদের কেবল ব্যাখ্যা করতে হবে।

আমরা আলোচনা করব এই সব কি টুকরো টুকরো করে, কিন্তু প্রথমে আসুন একটি বৈশ্বিক দৃষ্টিভঙ্গি পেতে চেষ্টা করি। প্রোগ্রামের প্রধান সংস্থা নিম্নরূপ কাজ করে।

প্রথমে আমরা "sbi PORTD, 4" দিয়ে PORTD এর বিট 4 সেট করি এটি PD4 তে 1 পাঠায় যা সেই পিনে ভোল্টেজ 5V রাখে। এটি LED চালু করবে। আমরা তারপর "বিলম্ব" সাবরুটিনে ঝাঁপিয়ে পড়ি যা 1/2 সেকেন্ড গণনা করে (আমরা ব্যাখ্যা করব এটি কীভাবে এটি পরে করে)। আমরা তারপর PORTD- তে ব্লিঙ্ক এবং ক্লিয়ার বিট 4 এ ফিরে যাই যা PD4 থেকে 0V সেট করে এবং তাই LED বন্ধ করে দেয়। আমরা তারপর আরও ১/২ সেকেন্ডের জন্য দেরি করি, এবং তারপর "rjmp blink" দিয়ে আবার চোখের পলকের শুরুতে ফিরে যাই।

আপনার এই কোডটি চালানো উচিত এবং এটি দেখতে হবে যে এটি যা করা উচিত তা করে।

এবং সেখানে আপনি এটা আছে! এই সব কোড শারীরিকভাবে করে। মাইক্রোকন্ট্রোলার যা করছে তার অভ্যন্তরীণ মেকানিক্স একটু বেশি জড়িত এবং সে কারণেই আমরা এই টিউটোরিয়ালটি করছি। সুতরাং আসুন প্রতিটি বিভাগ ঘুরে ঘুরে আলোচনা করি।

ধাপ 4:.org অ্যাসেম্বলার নির্দেশিকা

আমাদের পূর্ববর্তী টিউটোরিয়ালগুলি থেকে

.org 0x0000

jmp রিসেট.org 0x0020 jmp overflow_handler

। আপনার প্রোগ্রামটি চালানোর সাথে সাথে, "প্রোগ্রাম কাউন্টার" (পিসি হিসাবে সংক্ষিপ্ত) চলমান লাইনের ঠিকানা রয়েছে। সুতরাং এই ক্ষেত্রে যখন পিসি 0x0000 এ থাকে তখন সেই মেমরি অবস্থানে থাকা "jmp Reset" কমান্ডটি দেখতে পাবে। আমরা যে স্থানে jmp রিসেট রাখতে চাই তার কারণ হল যখন প্রোগ্রাম শুরু হয়, অথবা চিপটি পুনরায় সেট করা হয়, তখন পিসি এই স্থানে কোড চালানো শুরু করে। সুতরাং, আমরা যেমন দেখতে পাচ্ছি, আমরা কেবলমাত্র এটিকে "রিসেট" লেবেলযুক্ত বিভাগে অবিলম্বে "লাফ" দিতে বলেছি। আমরা কেন এমন করলাম? এর মানে হল যে উপরের শেষ দুটি লাইন শুধু বাদ দেওয়া হচ্ছে! কেন?

ঠিক আছে যেখানে জিনিসগুলি আকর্ষণীয় হয়ে ওঠে। আপনাকে এখন সম্পূর্ণ ATmega328p ডেটশীট সহ একটি পিডিএফ ভিউয়ার খুলতে হবে যা আমি এই টিউটোরিয়ালের প্রথম পৃষ্ঠায় উল্লেখ করেছি (এজন্য এটি "আপনার প্রয়োজন হবে" বিভাগে আইটেম 4)। যদি আপনার স্ক্রিনটি খুব ছোট হয়, অথবা আপনার অনেকগুলি উইন্ডো ইতিমধ্যেই খোলা থাকে (যেমন আমার ক্ষেত্রে) আপনি যা করতে পারেন তা করতে পারেন এবং এটি একটি ইরিডার বা আপনার অ্যান্ড্রয়েড ফোনে রাখতে পারেন। যদি আপনি সমাবেশ কোড লেখার পরিকল্পনা করেন তবে আপনি এটি সর্বদা ব্যবহার করবেন। দুর্দান্ত বিষয় হল যে সমস্ত মাইক্রোকন্টোলারগুলি খুব অনুরূপ উপায়ে সংগঠিত হয় এবং তাই একবার আপনি তাদের কাছ থেকে ডেটশীট এবং কোডিং পড়তে অভ্যস্ত হয়ে গেলে আপনি অন্য মাইক্রোকন্ট্রোলারের জন্য একই কাজ করা প্রায় তুচ্ছ মনে করবেন। তাই আমরা আসলে শিখছি কিভাবে সব মাইক্রোকন্ট্রোলারকে এক অর্থে ব্যবহার করতে হয় এবং শুধু atmega328p নয়।

ঠিক আছে, ডেটশীটে পৃষ্ঠা 18 এ যান এবং চিত্র 8-2 দেখুন।

এইভাবে মাইক্রোকন্ট্রোলারে প্রোগ্রাম মেমরি সেট আপ করা হয়। আপনি দেখতে পারেন যে এটি 0x0000 ঠিকানা দিয়ে শুরু হয় এবং দুটি বিভাগে বিভক্ত; একটি অ্যাপ্লিকেশন ফ্ল্যাশ বিভাগ এবং একটি বুট ফ্ল্যাশ বিভাগ। যদি আপনি সংক্ষিপ্তভাবে পৃষ্ঠা 277 টেবিল 27-14 তে উল্লেখ করেন তবে আপনি দেখতে পাবেন যে অ্যাপ্লিকেশন ফ্ল্যাশ বিভাগটি 0x0000 থেকে 0x37FF পর্যন্ত অবস্থান গ্রহণ করে এবং বুট ফ্ল্যাশ বিভাগ 0x3800 থেকে 0x3FFF অবশিষ্ট স্থানগুলি গ্রহণ করে।

অনুশীলন 1: প্রোগ্রাম স্মৃতিতে কতগুলি অবস্থান রয়েছে? I.e. 3FFF কে দশমিক রূপান্তর করুন এবং 1 যোগ করুন যেহেতু আমরা 0 এ গণনা শুরু করি যেহেতু প্রতিটি মেমরির অবস্থান 16 বিট (বা 2 বাইট) প্রশস্ত মেমরির মোট বাইট সংখ্যা কত? এখন এটিকে কিলোবাইটে রূপান্তর করুন, মনে রাখবেন যে একটি কিলোবাইটে 2^10 = 1024 বাইট আছে। বুট ফ্ল্যাশ বিভাগটি 0x3800 থেকে 0x37FF পর্যন্ত যায়, এটি কত কিলোবাইট? আমাদের প্রোগ্রাম সঞ্চয় করার জন্য আমাদের কত কিলোবাইট মেমরি অবশিষ্ট আছে? অন্য কথায়, আমাদের প্রোগ্রাম কত বড় হতে পারে? পরিশেষে, কোডের কত লাইন থাকতে পারে?

ঠিক আছে, এখন যেহেতু আমরা ফ্ল্যাশ প্রোগ্রাম মেমোরির সংগঠন সম্পর্কে সব জানি, আসুন.org স্টেটমেন্ট নিয়ে আমাদের আলোচনা চালিয়ে যাই। আমরা দেখি যে প্রথম মেমরির অবস্থান 0x0000 আমাদের রিসেট লেবেলযুক্ত আমাদের বিভাগে ঝাঁপিয়ে পড়ার জন্য নির্দেশনা রয়েছে। এখন আমরা দেখি ".org 0x0020" বিবৃতিটি কি করে। এটি বলে যে আমরা চাই পরবর্তী লাইনের নির্দেশনা মেমরি লোকেশন 0x0020 এ স্থাপন করা হোক। আমরা যে নির্দেশনাটি সেখানে রেখেছি তা হল আমাদের কোডের একটি বিভাগে একটি লাফ যা আমরা "ওভারফ্লো_হ্যান্ডলার" লেবেলযুক্ত করেছি … এখন আমরা কেন এই লাফটি মেমরি লোকেশনে 0x0020 এ রাখার দাবি করব? খুঁজে বের করার জন্য, আমরা ডেটশীটে পৃষ্ঠা to৫-এ ফিরে যাই এবং টেবিল ১২--6 দেখুন।

টেবিল 12-6 হল "রিসেট এবং ইন্টারাপ্ট ভেক্টর" এর একটি টেবিল এবং এটি দেখায় যে পিসি যখন "ইন্টারাপ্ট" পাবে তখন ঠিক কোথায় যাবে। উদাহরণস্বরূপ, যদি আপনি ভেক্টর নম্বর 1 এর দিকে তাকান তবে বাধাটির "উৎস" হল "RESET" যা "বাহ্যিক পিন, পাওয়ার-অন রিসেট, ব্রাউন-আউট রিসেট, এবং ওয়াচডগ সিস্টেম রিসেট" অর্থ, যদি কোনটি এই বিষয়গুলো আমাদের মাইক্রোকন্ট্রোলারের সাথে ঘটে, পিসি প্রোগ্রাম মেমরি লোকেশন 0x0000 এ আমাদের প্রোগ্রাম চালানো শুরু করবে। তাহলে আমাদের.org নির্দেশনা সম্পর্কে কি? আচ্ছা, আমরা মেমরি লোকেশনে একটি কমান্ড দিয়েছি 0x0020 এবং যদি আপনি টেবিলের নিচে তাকান তাহলে আপনি দেখতে পাবেন যে যদি টাইমার/কাউন্টার 0 ওভারফ্লো হয় (TIMER0 OVF থেকে আসছে) এটি 0x0020 লোকেশনে যা কিছু আছে তা কার্যকর করবে। সুতরাং যখনই এটি ঘটবে, পিসি সেই জায়গায় চলে যাবে যেখানে আমরা "ওভারফ্লো_হ্যান্ডলার" লেবেলযুক্ত। ঠান্ডা তাই না? আপনি এক মিনিটে দেখতে পাবেন কেন আমরা এটা করেছি, কিন্তু প্রথমে টিউটোরিয়ালের এই ধাপটি একপাশে শেষ করি।

আমরা যদি আমাদের কোডকে আরো পরিপাটি এবং পরিপাটি করতে চাই তাহলে আমাদের বর্তমানে যে 4 টি লাইন নিয়ে আলোচনা করা হচ্ছে তা সত্যিই প্রতিস্থাপন করা উচিত (পৃষ্ঠা 66 দেখুন):

.org 0x0000

rjmp রিসেট; পিসি = 0x0000 reti; পিসি = 0x0002 reti; পিসি = 0x0004 reti; পিসি = 0x0006 reti; পিসি = 0x0008 reti; পিসি = 0x000A… reti; PC = 0x001E jmp overflow_handler: PC = 0x0020 reti: PC = 0x0022… reti; পিসি = 0x0030 reti; পিসি = 0x0032

যাতে কোনো প্রদত্ত বাধাপ্রাপ্ত হলে তা কেবল "রেটি" হবে যার অর্থ "বাধা থেকে ফিরে আসা" এবং অন্য কিছু ঘটবে না। কিন্তু আমরা যদি কখনও এই বিভিন্ন বাধাগুলিকে "সক্ষম" না করি, তাহলে সেগুলি ব্যবহার করা হবে না এবং আমরা এই স্পটগুলিতে প্রোগ্রাম কোড রাখতে পারি। আমাদের বর্তমান "blink.asm" প্রোগ্রামে আমরা কেবল টাইমার 0 ওভারফ্লো ইন্টারাপ্ট (এবং অবশ্যই রিসেট ইন্টারাপ্ট যা সবসময় সক্রিয় থাকে) সক্ষম করতে যাচ্ছি এবং তাই আমরা অন্যদের নিয়ে বিরক্ত হব না।

আমরা কীভাবে টাইমার 0 ওভারফ্লো বাধাটিকে "সক্ষম" করব? … এই টিউটোরিয়ালে আমাদের পরবর্তী ধাপের বিষয়।

ধাপ 5: টাইমার/কাউন্টার 0

টাইমার/কাউন্টার 0
টাইমার/কাউন্টার 0

উপরের ছবিটি একবার দেখুন। এটি "পিসি" এর সিদ্ধান্ত গ্রহণ প্রক্রিয়া যখন কিছু বাইরের প্রভাব আমাদের প্রোগ্রামের প্রবাহকে "বাধাগ্রস্ত" করে। প্রথম কাজটি যখন এটি বাইরে থেকে একটি সংকেত পায় যে একটি বিঘ্ন ঘটেছে তা হল এটি পরীক্ষা করা যে আমরা সেই ধরণের বাধাটির জন্য "বাধা সক্ষম" বিট সেট করেছি কিনা। যদি আমরা না করি, তাহলে এটি কেবল আমাদের পরবর্তী লাইন কোডটি চালানো অব্যাহত রাখে। যদি আমরা সেই নির্দিষ্ট ইন্টারাপ্ট এনাবল বিট সেট করে থাকি (যাতে 0 এর পরিবর্তে সেই বিট লোকেশনে 1 থাকে) তাহলে আমরা "গ্লোবাল ইন্টারাপ্টস" সক্ষম করেছি কি না তা পরীক্ষা করে দেখবে, যদি না হয় তা আবার পরবর্তী লাইনে যাবে কোড এবং চালিয়ে যান। যদি আমরা বৈশ্বিক বিঘ্নগুলিও সক্ষম করে থাকি, তাহলে এটি সেই ধরণের বাধা প্রোগ্রাম মেমরি লোকেশনে যাবে (যেমন সারণি 12-6 তে দেখানো হয়েছে) এবং আমরা সেখানে যে কমান্ডটি রেখেছি তা কার্যকর করবে। সুতরাং আসুন দেখি কিভাবে আমরা আমাদের কোডে এই সমস্ত প্রয়োগ করেছি।

আমাদের কোডের রিসেট লেবেল করা বিভাগটি নিম্নলিখিত দুটি লাইন দিয়ে শুরু হয়:

রিসেট:

ldi temp, 0b00000101 TCCR0B, temp

যেমনটি আমরা ইতিমধ্যে জানি, এটি অবিলম্বে নিম্নলিখিত সংখ্যাটি টেম্পে (যেমন R16) লোড করে, যা 0b00000101। তারপর এটি "আউট" কমান্ড ব্যবহার করে TCCR0B নামক রেজিস্টারে এই নম্বরটি লিখে দেয়। এই রেজিস্টার কি? আচ্ছা, আসুন আমরা ডেটশীটের 614 পৃষ্ঠায় যাই। এটি একটি টেবিলের মাঝখানে সমস্ত রেজিস্টারের সংক্ষিপ্তসার। 0x25 ঠিকানায় আপনি TCCR0B পাবেন। (এখন আপনি জানেন যে "0x25, r16 আউট লাইনটি কোথা থেকে এসেছে কোডটির আমার মন্তব্যহীন সংস্করণে)" আমরা উপরের কোড সেগমেন্ট দ্বারা দেখি যে আমরা 0 তম বিট এবং ২ য় বিট সেট করেছি এবং বাকি সব পরিষ্কার করেছি। টেবিল দেখে আপনি দেখতে পাচ্ছেন যে এর মানে হল আমরা CS00 এবং CS02 সেট করেছি। এখন "8-বিট টাইমার/কাউন্টার 0 উইথ পিডব্লিউএম" নামক ডেটশীটে অধ্যায়ের দিকে যাওয়া যাক। বিশেষ করে, সেই অধ্যায়ের 107 পৃষ্ঠায় যান। আপনি "টাইমার/কাউন্টার কন্ট্রোল রেজিস্টার বি" (TCCR0B) রেজিস্টারের একই বিবরণ দেখতে পাবেন যা আমরা শুধু রেজিস্টার সারসংক্ষেপের টেবিলে দেখেছি (তাই আমরা সরাসরি এখানে আসতে পারতাম, কিন্তু আমি চাই আপনি কিভাবে সারসংক্ষেপ টেবিল ব্যবহার করবেন ভবিষ্যতের রেফারেন্সের জন্য)। ডেটশীট সেই রেজিস্টারের প্রতিটি বিট এবং তারা কী করে তার বিবরণ দিতে থাকে। আমরা আপাতত এগুলি বাদ দিয়ে পৃষ্ঠাটি সারণি 15-9 এ পরিণত করব। এই টেবিলে "ক্লক সিলেক্ট বিট বর্ণনা" দেখানো হয়েছে। এখন সেই টেবিলের নিচে তাকান যতক্ষণ না আপনি সেই বিটগুলির সাথে সামঞ্জস্যপূর্ণ লাইনটি খুঁজে পান যা আমরা কেবল সেই রেজিস্টারে সেট করেছি। লাইনটি বলে "clk/1024 (prescaler থেকে)"। এর মানে হল আমরা চাই যে টাইমার/কাউন্টার 0 (TCNT0) একটি হারে টিক দিতে চাই যা CPU ফ্রিকোয়েন্সি 1024 দ্বারা বিভক্ত। যেহেতু আমাদের মাইক্রোকন্ট্রোলার 16MHz ক্রিস্টাল অসিলেটর দ্বারা খাওয়ানো হয়েছে তার মানে হল যে আমাদের CPU নির্দেশাবলী কার্যকর করে প্রতি সেকেন্ডে 16 মিলিয়ন নির্দেশ। তাহলে আমাদের TCNT0 কাউন্টারে যে হারে টিক লাগবে তা হল প্রতি সেকেন্ডে 16 মিলিয়ন/1024 = 15625 বার (বিভিন্ন ক্লক সিলেক্ট বিট দিয়ে চেষ্টা করুন এবং দেখুন কি হয় - আমাদের দর্শন মনে রাখবেন?)। আসুন 15625 নম্বরটি আমাদের মনের পিছনে রাখি এবং পরবর্তী দুটি লাইনের কোডের দিকে এগিয়ে যাই:

ldi temp, 0b00000001

sts TIMSK0, তাপমাত্রা

এটি TIMSK0 নামে একটি রেজিস্টারের 0 তম বিট সেট করে এবং বাকি সব পরিষ্কার করে। আপনি যদি ডেটশীটে পৃষ্ঠা 109 এ নজর দেন তাহলে আপনি দেখতে পাবেন যে TIMSK0 মানে "টাইমার/কাউন্টার ইন্টারপার্ট মাস্ক রেজিস্টার 0" এবং আমাদের কোডটি 0 তম বিট সেট করেছে যার নাম TOIE0 যা দাঁড়ায় "টাইমার/কাউন্টার 0 ওভারফ্লো ইন্টারাপ্ট এনাবল" … সেখানে! এখন আপনি এই সব সম্পর্কে কি দেখতে। আমাদের এখন "ইন্টারাপ্ট এনাবল বিট সেট" আছে যেমনটি আমরা আমাদের ছবির প্রথম সিদ্ধান্ত থেকে উপরের দিকে চেয়েছিলাম। সুতরাং এখন আমাদের যা করতে হবে তা হল "গ্লোবাল ইন্টারাপ্টস" সক্ষম করা এবং আমাদের প্রোগ্রাম এই ধরনের বাধাগুলির প্রতি সাড়া দিতে সক্ষম হবে। আমরা শীঘ্রই বিশ্বব্যাপী বাধাগুলি সক্ষম করব, কিন্তু আমরা এটি করার আগে আপনি কিছু দ্বারা বিভ্রান্ত হতে পারেন.. আমি কেন "sts" কমান্ডটি TIMSK0 রেজিস্টারে স্বাভাবিক "আউট" এর পরিবর্তে অনুলিপি করার জন্য ব্যবহার করলাম?

যখনই আপনি আমাকে দেখেন এমন একটি নির্দেশনা ব্যবহার করেন যা আপনি আগে দেখেননি তার আগে ডেটশীটে পৃষ্ঠা 616 চালু করুন। এটি "ইন্সট্রাকশন সেট সারাংশ"। এখন নির্দেশনা "STS" খুঁজুন যা আমি ব্যবহার করেছি। এটি বলে যে এটি একটি R রেজিস্টার (আমরা R16 ব্যবহার করেছি) এবং "SRM থেকে সরাসরি SRAM" অবস্থান k (আমাদের ক্ষেত্রে TIMSK0 দ্বারা দেওয়া) থেকে একটি নম্বর নেয়। তাহলে কেন আমাদের "sts" ব্যবহার করতে হয়েছে যা TIMSK0 তে সঞ্চয় করতে 2 টি ঘড়ি চক্র (টেবিলে শেষ কলামটি দেখুন) এবং আমাদের কেবলমাত্র "আউট" প্রয়োজন, যা কেবলমাত্র একটি ঘড়ি চক্র লাগে, আগে TCCR0B- এ সংরক্ষণ করতে? এই প্রশ্নের উত্তর দিতে হলে আমাদের register১ page পৃষ্ঠার রেজিস্টার সারসংক্ষেপের টেবিলে ফিরে যেতে হবে। আপনি দেখতে পাচ্ছেন যে TCCR0B রেজিস্টার ঠিকানায় 0x25 কিন্তু (0x45) ঠিক আছে? এর মানে হল যে এটি SRAM এ একটি রেজিস্টার, কিন্তু এটি একটি নির্দিষ্ট ধরনের রেজিস্টার যাকে "পোর্ট" (অথবা i/o রেজিস্টার) বলা হয়। আপনি যদি "আউট" কমান্ডের পাশে নির্দেশের সারসংক্ষেপ টেবিলটি দেখেন তবে আপনি দেখতে পাবেন যে এটি R16 এর মত "ওয়ার্কিং রেজিস্টার" থেকে মান নেয় এবং একটি পোর্টে পাঠায়। তাই TCCR0B- এ লেখার সময় আমরা "আউট" ব্যবহার করতে পারি এবং নিজেদেরকে একটি ঘড়ি চক্র সংরক্ষণ করতে পারি। কিন্তু এখন রেজিস্টার টেবিলে TIMSK0 দেখুন। আপনি দেখেন যে এর ঠিকানা 0x6e আছে। এটি পোর্টের পরিসরের বাইরে (যা শুধুমাত্র SRAM এর প্রথম 0x3F অবস্থান) এবং তাই আপনাকে sts কমান্ড ব্যবহার করতে এবং এটি করার জন্য দুটি CPU ঘড়ি চক্র নিতে হবে। অনুগ্রহ করে এখনই 615 পৃষ্ঠায় নির্দেশনার সারাংশ টেবিলের শেষে নোট 4 পড়ুন। এছাড়াও লক্ষ্য করুন যে আমাদের সমস্ত ইনপুট এবং আউটপুট পোর্ট, যেমন PORTD টেবিলের নীচে অবস্থিত। উদাহরণস্বরূপ, PD4 0x0b ঠিকানায় বিট 4 (এখন আপনি দেখতে পাচ্ছেন যে আমার 0x0b স্টাফ আমার আন-কমেন্ট করা কোড থেকে কোথা থেকে এসেছে!).. ঠিক আছে, দ্রুত প্রশ্ন: আপনি কি "sts" কে "আউট" এ পরিবর্তন করেছেন এবং দেখুন কি ঘটে? আমাদের দর্শন মনে রাখবেন! ভেঙ্গে ফেল! শুধু জিনিসের জন্য আমার কথা গ্রহণ করবেন না।

ঠিক আছে, আমরা এগিয়ে যাওয়ার আগে, এক মিনিটের জন্য ডেটশীটে পৃষ্ঠা 19 এ চালু করুন। আপনি ডেটা মেমরির একটি ছবি দেখতে পান (SRAM)। SRAM এ প্রথম 32 টি রেজিস্টার (0x0000 থেকে 0x001F পর্যন্ত) হল "সাধারণ উদ্দেশ্য কাজ রেজিস্টার" R0 থেকে R31 যা আমরা সব সময় আমাদের কোডের ভেরিয়েবল হিসাবে ব্যবহার করি।পরবর্তী 64 টি রেজিস্টার হল 0x005f পর্যন্ত I/O পোর্ট (অর্থাৎ আমরা যাদের সম্পর্কে কথা বলছিলাম তাদের রেজিস্টার টেবিলে তাদের পাশের অ-বন্ধনী ঠিকানা রয়েছে যা আমরা "sts" এর পরিবর্তে "আউট" কমান্ড ব্যবহার করতে পারি) অবশেষে SRAM এর পরবর্তী বিভাগে 0x00FF ঠিকানা পর্যন্ত সারাংশ টেবিলে অন্যান্য সমস্ত রেজিস্টার রয়েছে এবং অবশেষে বাকিগুলি অভ্যন্তরীণ SRAM। এখন তাড়াতাড়ি, এক সেকেন্ডের জন্য পৃষ্ঠা 12 তে ফিরে আসি। সেখানে আপনি "সাধারণ উদ্দেশ্য কাজ রেজিস্টার" একটি টেবিল দেখতে পাবেন যা আমরা সবসময় আমাদের ভেরিয়েবল হিসাবে ব্যবহার করি। আপনি R0 থেকে R15 এবং তারপর R16 থেকে R31 সংখ্যার মধ্যে পুরু রেখা দেখতে পাচ্ছেন? এই লাইনটি কেন আমরা সর্বদা R16 কে সবচেয়ে ছোট হিসাবে ব্যবহার করি এবং আমি পরবর্তী টিউটোরিয়ালে এটি আরও কিছুটা প্রবেশ করব যেখানে আমাদের তিনটি 16-বিট পরোক্ষ ঠিকানা রেজিস্টার, X, Y এবং Z প্রয়োজন হবে। আমি করব না ঠিক সেই সময়ে প্রবেশ করুন যদিও আমাদের এখন এটির প্রয়োজন নেই এবং আমরা এখানে যথেষ্ট চাপে পড়ে যাচ্ছি।

ডেটশীটের 11 পৃষ্ঠায় এক পৃষ্ঠা ফিরে যান। আপনি উপরের ডানদিকে SREG রেজিস্টারের একটি চিত্র দেখতে পাবেন? আপনি দেখেন যে সেই রেজিস্টারের বিট 7 কে "আমি" বলা হয়। এখন পৃষ্ঠার নিচে যান এবং বিট 7 এর বিবরণ পড়ুন…। হ্যাঁ! এটি গ্লোবাল ইন্টারাপ্ট এনাবল বিট। আমাদের উপরের চিত্রের দ্বিতীয় সিদ্ধান্তের মধ্য দিয়ে যাওয়ার জন্য আমাদের সেট করতে হবে এবং আমাদের প্রোগ্রামে টাইমার/কাউন্টার ওভারফ্লো বাধাকে অনুমতি দিতে হবে। সুতরাং আমাদের প্রোগ্রামের পরবর্তী লাইনটি পড়া উচিত:

sbi SREG, I

যা SREG রেজিস্টারে "I" নামে বিট সেট করে। যাইহোক, এর পরিবর্তে আমরা নির্দেশটি ব্যবহার করেছি

sei

পরিবর্তে. এই বিটটি প্রায়শই প্রোগ্রামগুলিতে সেট করা হয় যে তারা এটি করার একটি সহজ উপায় তৈরি করেছে।

ঠিক আছে! এখন আমরা ওভারফ্লো ইন্টারাপ্টসকে প্রস্তুত করার জন্য প্রস্তুত করেছি যাতে আমাদের "জেএমপি ওভারফ্লো_হ্যান্ডলার" যখনই ঘটবে তখন কার্যকর করা হবে।

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

clr তাপমাত্রা

TCNT0, temp sbi DDRD, 4

এখানে শেষ লাইনটি বেশ স্পষ্ট। এটি পোর্টডির জন্য ডাটা দিকনির্দেশনা নিবন্ধনের 4th র্থ বিট সেট করে যার ফলে PD4 আউটপুট হতে পারে।

প্রথমটি ভেরিয়েবল টেম্পকে শূন্যে সেট করে এবং তারপর TCNT0 রেজিস্টারে কপি করে। TCNT0 হল আমাদের টাইমার/কাউন্টার 0। এটি শূন্য সেট করে। পিসি এই লাইনটি চালানোর সাথে সাথে টাইমার 0 শূন্য থেকে শুরু হবে এবং প্রতি সেকেন্ডে 15625 বার হারে গণনা করবে। সমস্যাটি হল: TCNT0 একটি "8-বিট" নিবন্ধন ঠিক আছে? তাহলে 8-বিট রেজিস্টারে রাখা সবচেয়ে বড় সংখ্যাটি কী? আচ্ছা 0b11111111 এটা। এই সংখ্যাটি 0xFF। কোনটি 255। তাহলে আপনি কি দেখতে পান? টাইমারটি প্রতি সেকেন্ডে 15625 গুণ বৃদ্ধি পাচ্ছে এবং প্রতিবার যখন এটি 255 তে পৌঁছায় তখন এটি "ওভারফ্লো" হয়ে যায় এবং আবার 0 তে ফিরে যায়। একই সময়ে যখন এটি শূন্যে ফিরে যায় তখন এটি একটি টাইমার ওভারফ্লো ইন্টারাপ্ট সিগন্যাল পাঠায়। পিসি এটি পায় এবং আপনি জানেন যে এটি এখন কি করে? হ্যাঁ। এটি প্রোগ্রাম মেমরি লোকেশনে যায় 0x0020 এবং সেখানে যে নির্দেশনা পাওয়া যায় তা কার্যকর করে।

দারুণ! আপনি যদি এখনও আমার সাথে থাকেন তবে আপনি একজন অক্লান্ত সুপারহিরো! চলো যেতে থাকি…

ধাপ 6: ওভারফ্লো হ্যান্ডলার

সুতরাং ধরে নেওয়া যাক যে টাইমার/কাউন্টার 0 নিবন্ধন সবেমাত্র উপচে পড়েছে। আমরা এখন জানি যে প্রোগ্রামটি একটি ইন্টারাপ্ট সিগন্যাল পায় এবং 0x0020 চালায় যা প্রোগ্রাম কাউন্টার, পিসিকে "ওভারফ্লো_হ্যান্ডলার" লেবেলে ঝাঁপিয়ে পড়তে বলে, সেই কোডটি আমরা সেই লেবেলের পরে লিখেছি:

overflow_handler:

inc overflows cpi overflows, 61 brne PC+2 clr overflows reti

প্রথম কাজটি হল ভেরিয়েবল "ওভারফ্লো" বৃদ্ধি করা (যা আমাদের সাধারণ কাজের রেজিস্টার R17 এর নাম) তারপর এটি ওভারফ্লোর বিষয়বস্তু 61 নম্বরের সাথে "তুলনা" করে। নির্দেশ সিপিআই যেভাবে কাজ করে তা হল এটি কেবল বিয়োগ দুটি সংখ্যা এবং যদি ফলাফল শূন্য হয় তবে এটি SREG রেজিস্টারে Z পতাকা সেট করে (আমি আপনাকে বলেছিলাম যে আমরা এই রেজিস্টারটি সব সময় দেখব)। যদি দুটি সংখ্যা সমান হয় তবে Z পতাকা হবে 1, যদি দুটি সংখ্যা সমান না হয় তাহলে তা হবে 0।

পরের লাইনটি বলে "brne PC+2" যার অর্থ "সমান না হলে শাখা"। মূলত, এটি SREG তে Z পতাকা পরীক্ষা করে এবং যদি এটি একটি না হয় (যেমন দুটি সংখ্যা সমান নয়, যদি তারা সমান হয়, শূন্য পতাকা সেট করা হবে) PC শাখাগুলি PC+2 এ, মানে এটি পরবর্তীটি বাদ দেয় লাইন এবং সোজা চলে যায় "রেটি" যা বিরতি থেকে কোডে যে কোন জায়গায় বাধা থেকে ফিরে আসে যখন বাধা আসে। যদি brne নির্দেশটি শূন্য পতাকা বিটে 1 পাওয়া যায় তবে এটি শাখা হবে না এবং পরিবর্তে এটি পরবর্তী লাইনে অব্যাহত থাকবে যা এটি 0 তে পুনরায় সেট করা ওভারফ্লোকে ক্লার করবে।

এই সবের নিট ফলাফল কি?

আচ্ছা আমরা দেখি যে প্রতিবার যখন একটি টাইমার ওভারফ্লো হয় তখন এই হ্যান্ডলার একের পর এক "ওভারফ্লো" এর মান বাড়ায়। সুতরাং ভেরিয়েবল "ওভারফ্লো" হচ্ছে ওভারফ্লোগুলির সংখ্যা গণনা করা হচ্ছে যেমন তারা ঘটে। যখনই সংখ্যা 61 তে পৌঁছায় আমরা এটিকে শূন্যে পুনরায় সেট করি।

এখন কেন পৃথিবীতে আমরা তা করব?

দেখা যাক. মনে রাখবেন যে আমাদের CPU- র জন্য আমাদের ঘড়ির গতি 16MHz এবং আমরা TCCR0B ব্যবহার করে এটিকে "prescaled" করেছি যাতে টাইমার শুধুমাত্র 15625 হারে প্রতি সেকেন্ডে গণনা করে? এবং প্রতিবার টাইমার 255 এর একটি গণনা পৌঁছায় এটি উপচে পড়ে। সুতরাং এর অর্থ এটি 15625/256 = 61.04 বার প্রতি সেকেন্ডে প্রবাহিত হয়। আমরা আমাদের ভেরিয়েবল "ওভারফ্লো" এর সাথে ওভারফ্লোর সংখ্যার উপর নজর রাখছি এবং আমরা সেই সংখ্যাটিকে 61 এর সাথে তুলনা করছি। সুতরাং আমরা দেখি যে "ওভারফ্লো" প্রতি সেকেন্ডে একবার 61 এর সমান হবে! সুতরাং আমাদের হ্যান্ডলার প্রতি সেকেন্ডে একবার "ওভারফ্লো" শূন্যে রিসেট করবে। সুতরাং যদি আমরা কেবলমাত্র ভেরিয়েবল "ওভারফ্লো" নিরীক্ষণ করি এবং প্রতিবার এটি শূন্যে পুনরায় সেট করে নোট করি তবে আমরা রিয়েল টাইমে সেকেন্ড-বাই-সেকেন্ড গণনা করব (উল্লেখ্য যে পরবর্তী টিউটোরিয়ালে আমরা দেখাব কিভাবে আরও সঠিক পেতে হয় মিলিসেকেন্ডে বিলম্ব একইভাবে যেভাবে Arduino "বিলম্ব" রুটিন কাজ করে)।

এখন আমরা টাইমার ওভারফ্লো বাধাগুলিকে "হ্যান্ডেল" করেছি। এটি কীভাবে কাজ করে তা নিশ্চিত করুন এবং তারপরে পরবর্তী ধাপে যান যেখানে আমরা এই সত্যটি ব্যবহার করি।

ধাপ 7: বিলম্ব

এখন আমরা দেখেছি যে আমাদের টাইমার ওভারফ্লো ইন্টারাপ্ট হ্যান্ডলার "ওভারফ্লো_হ্যান্ডলার" রুটিন প্রতি সেকেন্ডে একবার ভেরিয়েবল "ওভারফ্লো" শূন্যে সেট করবে আমরা "বিলম্ব" সাবরুটিন ডিজাইন করতে এই সত্যটি ব্যবহার করতে পারি।

আমাদের বিলম্বের অধীনে নিম্নলিখিত কোডটি দেখুন: লেবেল

বিলম্ব:

clr overflows sec_count: cpi overflows, 30 brne sec_count ret

যখনই আমাদের প্রোগ্রামে বিলম্ব প্রয়োজন তখন আমরা এই সাবরুটিনকে কল করতে যাচ্ছি। এটি যেভাবে কাজ করে তা হল এটি প্রথমে ভেরিয়েবল "ওভারফ্লো" শূন্যে সেট করে। তারপর এটি "sec_count" লেবেলযুক্ত একটি এলাকায় প্রবেশ করে এবং 30 এর সাথে ওভারফ্লোর তুলনা করে, যদি তারা সমান না হয় তবে এটি শাখাগুলি লেবেল সেকেন্ড_কাউন্টে ফিরে আসে এবং আবার এবং আবার তুলনা করে, যতক্ষণ না তারা শেষ পর্যন্ত সমান হয় (মনে রাখবেন পুরো সময় এটি চলছে আমাদের টাইমারে ইন্টারাপ্ট হ্যান্ডলার ক্রমাগত ভেরিয়েবল ওভারফ্লো বাড়িয়ে চলেছে এবং তাই প্রতিবার যখন আমরা এখানে ঘুরে আসি তখন এটি পরিবর্তিত হচ্ছে। 1/2 সেকেন্ড বিলম্ব

অনুশীলন 2: ওভারফ্লো_হ্যান্ডলার রুটিনটি নিম্নলিখিতটিতে পরিবর্তন করুন:

overflow_handler:

inc overflows reti

এবং প্রোগ্রামটি চালান। কিছু ভিন্ন? কেন অথবা কেন নয়?

ধাপ 8: চোখের পলক

অবশেষে চোখের পলক রুটিন দেখুন:

পলক:

sbi PORTD, 4 rcall বিলম্ব cbi PORTD, 4 rcall বিলম্ব rjmp ঝলক

প্রথমে আমরা PD4 চালু করি, তারপর আমরা আমাদের বিলম্ব সাবরুটিনকে কল করি। আমরা rcall ব্যবহার করি যাতে পিসি যখন একটি "ret" স্টেটমেন্ট পায় তখন এটি rcall এর পরে লাইনে ফিরে আসবে। তারপর ওভারফ্লো ভেরিয়েবলে 30 টি গণনার জন্য বিলম্বের রুটিন বিলম্ব হয় যেমন আমরা দেখেছি এবং এটি প্রায় 1/2 সেকেন্ড, তারপর আমরা PD4 বন্ধ করি, আরেকটি 1/2 সেকেন্ড বিলম্ব করি, এবং তারপর আবার শুরুতে ফিরে যাই।

নেট ফলাফল একটি জ্বলজ্বলে LED!

আমি মনে করি আপনি এখন একমত হবেন যে "ব্লিঙ্ক" সম্ভবত সমাবেশ ভাষায় সেরা "হ্যালো ওয়ার্ল্ড" প্রোগ্রাম নয়।

ব্যায়াম 3: প্রোগ্রামের বিভিন্ন প্যারামিটার পরিবর্তন করুন যাতে LED বিভিন্ন হারে জ্বলজ্বল করে যেমন সেকেন্ড বা 4 বার সেকেন্ড, ইত্যাদি 4 ব্যায়াম: এটি পরিবর্তন করুন যাতে LED বিভিন্ন সময়ের জন্য চালু এবং বন্ধ থাকে। উদাহরণস্বরূপ 1/4 সেকেন্ডের জন্য এবং তারপর 2 সেকেন্ডের জন্য বা এরকম কিছু বন্ধ করুন ব্যায়াম 5: TCCR0B ঘড়ি নির্বাচন করুন বিট 100 এ পরিবর্তন করুন এবং তারপর টেবিলের উপরে যাওয়া চালিয়ে যান। টিউটোরিয়াল 1 থেকে আমাদের "হ্যালো.এএসএম" প্রোগ্রাম থেকে কোন সময়ে এটি আলাদা হয়ে যায়? আপনার ব্রেডবোর্ডে নতুনটির জন্য এবং দেখুন যে এটি LED এর ঝলকানি হারকে কীভাবে প্রভাবিত করে। আপনি এখন সুনির্দিষ্ট হিসাবের মধ্য দিয়ে যেতে সক্ষম হবেন এবং ভবিষ্যদ্বাণী করবেন যে এটি হারে কীভাবে প্রভাব ফেলবে।

ধাপ 9: উপসংহার

আপনারা যারা মরিয়া, যারা এতদূর পৌঁছেছেন তাদের জন্য, অভিনন্দন!

আমি বুঝতে পারছি যে আপনি যখন অনেক বেশি পড়ছেন এবং তারের চেয়ে বেশি পরীক্ষা করছেন এবং পরীক্ষা করছেন তার চেয়ে অনেক কঠিন স্লগিং কিন্তু আমি আশা করি আপনি নিম্নলিখিত গুরুত্বপূর্ণ বিষয়গুলি শিখেছেন:

  1. প্রোগ্রাম মেমরি কিভাবে কাজ করে
  2. SRAM কিভাবে কাজ করে
  3. কিভাবে রেজিস্টার সন্ধান করবেন
  4. কীভাবে নির্দেশাবলী সন্ধান করবেন এবং তারা কী করবেন তা জানবেন
  5. কিভাবে বাধা বাস্তবায়ন করতে হয়
  6. সিপি কিভাবে কোডটি এক্সিকিউট করে, SREG কিভাবে কাজ করে এবং ইন্টারাপ্টের সময় কি হয়
  7. কিভাবে loops এবং জাম্প করতে এবং কোড চারপাশে বাউন্স
  8. ডেটশীট পড়া কত গুরুত্বপূর্ণ!
  9. কিভাবে আপনি Atmega328p মাইক্রোকন্ট্রোলারের জন্য এই সব করতে হয় তা একবার জানলে এটি আপনার আগ্রহী নতুন নিয়ামক শিখতে একটি আপেক্ষিক কেক হাঁটা হবে।
  10. কিভাবে সিপিইউ সময়কে রিয়েল টাইমে পরিবর্তন করা যায় এবং বিলম্বের রুটিনে এটি ব্যবহার করা যায়।

এখন যেহেতু আমাদের কাছে অনেক তত্ত্ব আছে আমরা আরও ভাল কোড লিখতে এবং আরো জটিল জিনিস নিয়ন্ত্রণ করতে সক্ষম। তাই পরবর্তী টিউটোরিয়াল আমরা ঠিক তাই করতে হবে। আমরা আরও জটিল, আরও আকর্ষণীয়, সার্কিট তৈরি করব এবং মজাদার উপায়ে এটি নিয়ন্ত্রণ করব।

অনুশীলন 7: বিভিন্ন উপায়ে কোড "ব্রেক" করুন এবং দেখুন কী হয়! বৈজ্ঞানিক কৌতূহলী শিশু! অন্য কেউ সঠিকভাবে বাসন ধুতে পারে? ব্যায়াম 8: একটি তালিকা ফাইল তৈরি করতে "-l" বিকল্প ব্যবহার করে কোডটি একত্রিত করুন। I.e. "avra -l blink.lst blink.asm" এবং তালিকা ফাইলটি দেখুন। অতিরিক্ত ক্রেডিট: আমি শুরুতে যে অ-মন্তব্য কোডটি দিয়েছিলাম এবং মন্তব্য করা কোড যা আমরা পরে আলোচনা করেছি তা আলাদা! কোডের একটি লাইন আছে যা ভিন্ন। তুমি কি এটা খুজে দিতে পার? কেন এই পার্থক্য গুরুত্বপূর্ণ নয়?

আশা করি তুমি উপভোগ করেছো! পরের বার দেখা হবে…

প্রস্তাবিত: