সাত অধ্যায়


7.1 State the importance for writing program in C

সি’ প্রোগ্রামিং ভাষা একটি স্ট্রাকচার্ড বা প্রোসিডিউর প্রোগ্রামিং ভাষা যা “ডেনিশ রিচি” ডেভলোপ করেন। এই ভাষাটি বেল ল্যাবরেটরিতে UNIX অপারেটিং সিস্টেম তৈরি করার সময় তৈরি করেন। মিড লেভেল ভাষা হিসেবে ‘সি’ অত্যন্ত জনপ্রিয়। ‘সি ভাষাটি ১৯৭২ সালে DEC PDP-11 নামক কম্পিউটারে সর্বপ্রথম বাস্তবায়ন করা হয়। ‘সি’ নামটা এসেছে মার্টিন রিচার্ডস (Martins Richards) এর উদ্ভাবিত বিসিপিএল (BCPL-Basic Combined Programming Language) ভাষা থেকে। BCPL সংক্ষেপে B নামে পরিচিত ছিল। পরে B এর উন্নয়নের ফলে C এর বিকাশ ঘটে।

‘সি’ ভাষাকে সকল আধুনিক প্রোগ্রামিং ভাষার মাতৃ-ভাষা (mother language) বলা হয়। কারণ অধিকাংশ প্রোগ্রামিং ভাষা যেমন- C++, Java, C#, ইত্যাদি ‘সি’ ভাষার সিনট্যাক্স অনুসরণ করে। ‘সি’ ভাষা অ্যারে, স্ট্রিং, ফাংশন, ফাইল ইত্যাদির ধারণা দেয় যা C++, Java, C#, ইত্যাদি ভাষায় ব্যবহৃত হয়।

‘সি’ প্রোগ্রামিং ভাষা একটি স্ট্রাকচার্ড বা প্রোসিডিউর অরিয়েন্টেড প্রোগ্রামিং ভাষা

‘সি’ কে স্ট্রাকচার্ড প্রোগ্রামিং ভাষা বলা হয়, কারণ ‘সি’ তে একটি প্রোগ্রামকে কতগুলো ছোট ছোট অংশে বিভক্ত করে প্রতিটি অংশের জন্য আলাদাভাবে ভেরিয়েবল, স্ট্রাকচার, ফাংশন ইত্যাদি বর্ণনা করা যায় এবং প্রয়োজনে if, while, for, goto ইত্যাদি কন্ট্রোল স্টেটমেন্টের মাধ্যমে বিভিন্ন অংশের মধ্যে সমন্বয় সাধন করা যায়, কিংবা কোন ফাংশন বা স্ট্রাকচার পুনঃব্যবহার করা যায়। তাই ‘সি’ প্রোগ্রামিং ভাষাকে একটি স্ট্রাকচার্ড প্রোগ্রামিং ভাষা বলা হয়। আনস্ট্রাকচার্ড ভাষায় (যেমন- বেসিক) এভাবে মূল সমস্যাকে একাধিক অংশে বিভক্ত করে প্রতিটি আলাদা অংশের জন্য আলাদাভাবে ফাংশন বর্ণনা করা যায় না।

‘সি’ কে প্রোসিডিউর অরিয়েন্টেড প্রোগ্রামিং ভাষাও বলা হয়, কারণ একটি প্রোগ্রামকে কতগুলো ছোট ছোট অংশে বিভক্ত করে প্রতিটি অংশের জন্য আলাদাভাবে ভেরিয়েবল, স্ট্রাকচার, ফাংশন ইত্যাদি বর্ণনা করা যায় এবং এই ছোট ছোট অংশগুলো পর্যায়ক্রমে নির্বাহের মাধ্যমে একটি সমস্যার সমাধান করে।

‘সি’ একটি মধ্যস্তরের প্রোগ্রামিং ভাষা

‘সি’ প্রোগ্রামিং ভাষায় নিম্নস্তরের ভাষার সুবিধা যেমন- বিট পর্যায়ের প্রোগ্রামিং বা সিস্টেম সফটওয়্যার এর মাধ্যমে হার্ডওয়্যার নিয়ন্ত্রণ এবং উচ্চস্তরের ভাষার সুবিধা যেমন- অ্যাপ্লিকেশন সফটওয়্যার তৈরি করা যায়। অর্থাৎ উচ্চস্তরের ভাষার সুবিধা পাওয়া যায় আবার নিম্নস্তরের ভাষার সুবিধাও পাওয়া যায়। তাই এই প্রোগ্রামিং ভাষাকে মধ্যস্তরের প্রোগ্রামিং ভাষা বলা হয়।

‘সি’ প্রোগ্রামিং ভাষা একটি general purpose প্রোগ্রামিং ভাষা

‘সি’ প্রোগ্রামিং ভাষাটি সব ধরণের কাজের জন্য ব্যবহৃত হয়। একজন প্রোগ্রামারের যেসব সুবিধা দরকার, যেমন- বিভিন্ন ডেটা ব্যবহারের ব্যাপক স্বাধীনতা, স্বল্প সংখ্যক কী-ওয়ার্ড, দ্রুত ও দক্ষতার সাথে প্রোগ্রাম চালানো এবং একই সাথে উচ্চ ও নিম্নস্তরের ভাষা সমন্বয় করা ইত্যাদি সব রকম সুবিধাই ‘সি’ প্রোগ্রামিং ভাষাতে আছে। তাই যেকোনো ধরণের প্রোগ্রাম লিখতে ‘সি’ প্রোগ্রামিং ভাষা ব্যবহার করা যায়। এই জন্য ‘সি’ ভাষাকে একটি General Purpose প্রোগ্রামিং ভাষা বলা হয়।

7.2 Mention C data types and operators for 8051

সি প্রোগ্রামিং ডেটা টাইপ

মৌলিক(Fundamental) ডেটা টাইপ

  • ইন্টেজার টাইপ(Integer type)
  • ফ্লোটিং টাইপ(Floating type)
  • ক্যারক্টার টাইপ(Character type)


char - ক্যারেক্টার ডেটা টাইপ


ক্যারেক্টার টাইপের ভ্যারিয়েবল ডিক্লেয়ার করার জন্য char কীওয়ার্ড ব্যবহৃত হয়। উদাহরণস্বরূপঃ

char alphabet = 'a'

এখানে alphabet হলো ক্যারেক্টার ভ্যারিয়েবল এবং alphabet এর ভ্যালু 'a'।

ক্যারেক্টার ভ্যারিয়েবলের সাইজ 1 বাইট।

int - ইন্টেজার ডেটা টাইপ


দশমিক(.) সংখ্যা ব্যতীত সকল ধনাত্মক এবং ঋণাত্মক পূর্ণ সংখ্যা এই টাইপের মধ্যে পড়ে। যেমন- 0, -10, 10 ইত্যাদি

সি প্রোগ্রামিং এ ইন্টেজার টাইপের ভ্যারিয়েবল ডিক্লেয়ার করার জন্য int কীওয়ার্ড ব্যবহৃত হয়। উদাহরণস্বরূপঃint roll_no;

এখানে roll_no হলো ইন্টেজার টাইপের ভ্যারিয়েবল।

সি প্রোগ্রামিং এ আপনি একটি ডিক্লেয়ারেশনের মাধ্যমে অনেক ভ্যারিয়েবলকে একই সঙ্গে ডিক্লেয়ার করতে পারেন। উদাহরনস্বরুপঃ
int roll_no, age, years;

int এর সাইজ 2 বাইট(পুরাতন কম্পিউটারে) অথবা 4 বাইট হতে পারে। আপনার ভ্যারিয়েবলের সাইজ যদি 4 বাইট হয় তাহলে ইহা 232 সংখ্যক স্বতন্ত্র ভ্যালু গ্রহণ করতে পারে। যেমন- -231,-231+1, ...,-2, -1, 0, 1, 2, ..., 231-2, 231-1

একইভাবে int ভ্যারিয়েবলের সাইজ 2 বাইট হলে ইহা -215 থেকে 215-1 এর মধ্যে 216 সংখ্যক বিভিন্ন ভ্যালু গ্রহণ করতে পারে। আপনি যদি 231-1 অর্থাৎ +2147483647 থেকে বড় নাম্বার এবং -231 অর্থাৎ -2147483648 থেকে ছোট নাবার স্টোর(store) করতে চান তাহলে প্রোগ্রাম ঠিকমত রান(run) করবে না।

float - ফ্লোটিং টাইপ

ফ্লোটিং টাইপ ভ্যারিয়েবলে যেকোনো বাস্তব সংখ্যা থাকতে পারে। যেমন- 3.1416, -5.382, 10.0 ইত্যাদি। ফ্লোট টাইপের ভ্যারিয়েবল ডিক্লেয়ার(declare) করার জন্য আপনি হয় float অথবা double কীওয়ার্ড ব্যবহার করতে পারেন। উদাহরনস্বরুপঃ
float accountBalance; double bookPrice;

এখানে accountBalance এবং bookPrice উভয়েই ফ্লোটিং টাইপ ভ্যারিয়েবল।

সি প্রোগ্রামিং এ ফ্লোটিং ভ্যালুকে এক্সপনেনশিয়াল(exponential) ফর্মেও উপস্থাপন করা যায়। উদাহরনস্বরুপঃ
float normalizationFactor = 22.442e2; 

সি প্রোগ্রামিং অপারেটর

  1. এরিথমেটিক অপারেটর - Arithmetic Operator
  2. ইনক্রিমেন্ট এবং ডিক্রিমেন্ট অপারেটর- Increment and Decrement Operator
  3. এসাইনমেন্ট অপারেটর - Assignment Operator
  4. রিলেশনাল অপারেটর - Relational Operator
  5. লজিকাল অপারেটর - Logical Operator
  6. কন্ডিশনাল অপারেটর - Conditional Operator
  7. বিটওয়াইজ অপারেটর - Bitwise Operator
  8. স্পেশিয়াল অপারেটর - Special Operator

সি এরিথমেটিক অপারেটর

এরিথমেটিক অপারেটর গাণিতিক হিসাব নিকাশ যেমন- যোগ, বিয়োগ, গুন এবং ভাগ ইত্যাদি কার্য সম্পন্ন করে।
অপারেটরঅপারেটেরের অর্থউদাহরণ(int a=11, b=5)ফলাফল
+যোগ বা ইউনারী(unary) যোগa + b16
-বিয়োগ বা ইউনারী বিয়োগa - b6
*গুনa * b55
/ভাগa / b2
%ভাগের পরে ফলাফল ভাগশেষ(মডিউলো অপারেটর)a % b1

সি এসাইনমেন্ট অপারেটর

ভ্যারিয়েবলে ভ্যালু এসাইন করা বা জমা রাখার জন্য এসাইনমেন্ট(assignment) অপারেটর ব্যবহৃত হয়। সবচেয়ে বেশী ব্যবহৃত এসাইনমেন্ট অপারেটর হলো =
অপারেটরউদাহরন(int a=11, b=5)একই রকমফলাফল
=a = ba = b5
+=a += ba = a+b16
-=a -= ba = a-b6
*=a *= ba = a*b55
/=a /= ba = a/b2
%=a %= ba = a%b1

সি রিলেশনাল অপারেটর

সি প্রোগ্রামিং এ রিলেশনাল অপারেটর(relational operator) দুটি অপারেন্ডের মধ্যে সম্পর্ক যাচাই করে। রিলেশন সত্যি(true) হলে 1 রিটার্ন করে; রিলেশন মিথ্যা(false) হলে 0 রিটার্ন করে।
সিদ্ধান্ত গ্রহণ(decision making) এবং লুপ(loop) এ রিলেশনাল অপারেটর ব্যবহৃত হয়।
অপারেটরঅপারেটরের অর্থউদাহরণ(int a=11, b=5)ফলাফল
==Equal toa == bFalse
>Greater thana > bTrue
<Less thana < bFalse
!=Not equal toa != bTrue
>=Greater than or equal toa >= bTrue
<=Less than or equal toa <= bFalse

সি লজিক্যাল অপারেটর

সি প্রোগ্রামিং এ &&, || এবং ! অপারেটরসমূহকে লজিক্যাল(Logial) অপারেটর বলা হয়। সি প্রোগ্রামিং এসিদ্ধান্ত গ্রহণে(in decision making ) সচারচর লজিক্যাল অপারেটর ব্যবহৃত হয়।
অপারেটরঅপারেটরের অর্থউদাহরণ(int a=11, b=5, c =15)ফলাফল
&&Logial AND - উভয় অপারেন্ড true হলে True (a==b) && (b>c)True
||Logical OR - যেকোনো একটি অপারেন্ড true হলে True(b==c) || (a>c)False
!Logical NOT - অপারেন্ড false হলে True!(b==c)True

বিটওয়াইজ অপারেটর

হিসাব নিকাশের সময় গাণিতিক অপারেশন যেমন- যোগ, বিয়োগ, গুণ এবং ভাগ বিট-লেভেলে রূপান্তরিত হলে দ্রুত প্রোসেসিং হয় এবং শক্তি(power) সংরক্ষিত হয়।
সি প্রোগ্রামিং এ বিট-লেভেল অপারেশন সম্পন্ন করার জন্য বিটওয়াইজ(Bitwise) অপারেটর ব্যবহৃত হয়।
মনেকরি, নিচের টেবিলে x = 10 (বাইনারিতে 0000 1010) এবং y = 4 (বাইনারিতে 0000 0100)
অপারেটরঅপারেটরের অর্থউদাহরণ(x=10 এবং y=4)ফলাফল
&Bitwise ANDx& y = 0 (0000 0000)0
|Bitwise ORx | y = 14 (0000 1110)14
^Bitwise exclusive ORx ^ y = 14 (0000 1110)14
~Bitwise complement~x = -11 (1111 0101)-11
<<Shift leftx<< 2 = 42 (0010 1000)42
>>Shift rightx>> 2 = 2 (0000 0010)2
বিটওয়াইজ অপারেটর সম্মন্ধে আরোও জানতে আমাদের সি বিটওয়াইজ অপারেটর অধ্যায় ভিজিট করুন

অন্যান্য অপারেটর


কমা অপারেটর
সম্পর্কযুক্ত এক্সপ্রেশনসমূহকে একইসঙ্গে ডিক্লেয়ার(declare) করার জন্য কমা(comma) অপারেটর ব্যবহৃত হয়। উদাহরনস্বরুপঃ
int a, b = 10, c = 5, d;

sizeof অপারেটর

sizeof অপারেটর হলো ইউনারী অপারেটর যা ডেটা যেমন- কনস্ট্যান্ট, ভ্যারিয়েবল, অ্যারে, স্ট্রাকচার ইত্যাদির সাইজ রিটার্ন করে
সিনট্যাক্স
sizeof(variable)

7.3 Describe creating time delay in C.

টাইমার যে আসলে কত গুরুত্বপূর্ণ একটি পেরিফেরাল তা বলে বুঝানো যাবেনা। এর আগের পোস্টগুলোতে আমরা টাইমার সম্পর্কে যথেষ্ট জেনেছি কিন্তু তারপরও কিছু খুঁটিনাটি বিষয় এখনও বাকি থেকে গেছে। আজকের পোস্টে আমরা মোটামোটি ভাবে টাইমার সম্পর্কে বাকি বিষয়গুলো জেনে নিব। টাইমার দিয়ে delay() ফাংশন রিলেটেড কিছু করতে গেলে অবশ্যই 8051 মাইক্রোকন্ট্রোলারের সাথে ১২ মেগাহার্টজের ক্রিস্টাল অসসিলেটর সংযোগ করতে হবে। কারন আমরা আগেই জেনেছি। ১২ মেগাহার্টজ ক্রিস্টাল অসসিলেটরের জন্যে 8051 মাইক্রোকন্ট্রোলারের মেশিন সাইকেলের পালস্‌ হয় ১ মাইক্রোসেকেন্ড। হিসাবের সিমপ্লিসিটি বজায় রাখার জন্যেই এরুপ ক্রিস্টাল সিলেক্ট করা। তাহলে এটুকু বোঝা যাচ্ছে যে মাইক্রোকন্ট্রোলারের এরুপ কনফিগারেশনের জন্যে আমরা টাইমার দিয়ে সর্বনিম্ন ১ মাইক্রোসেকেন্ড এবং সর্বোচ্চ ৬৫.৫৩৫ মিলিসেকেন্ড পর্যন্ত সময় গণনা করতে পারি। সর্বোচ্চ ৬৫.৫৩৫ মিলি সেকেন্ড কেন সেটা আমাদের সবারই মোটামোটি বুঝতে পারার কথা। না বুঝে থাকলে টাইমার রিলেটেড আগের পোস্টগুলো একটু দেখে নিবো। এখন ঘটনা হল এই ৬৫.৫৩৫ মিলিসেকেন্ড গণনার পর কি হবে?? আমাদের যদি এর চেয়ে বেশি সময় গণনার দরকার হয় তখন কি করব? তখন আসলে আমাদের ইন্টারাপ্টের সাহায্য নিতে হবে। এবং ইন্টারাপ্টের সাথে সাথে আরেকটু হিসাব করতে হবে। কথা না বাড়িয়ে সরাসরি হিসাব দেখে নেয়া যাক একটি উদাহরনের মাধ্যমে।

ধরা যাক আমরা একটি লেড বাল্ব ১ সেকেন্ড পর পর অন অফ করতে চাই। তাহলে হিসাবটি হবে-

আমাদের প্রয়োজন = ১ সেকেন্ড = ১,০০০ মিলিসেকেন্ড

যেহেতু 8051 মাইক্রোকন্ট্রোলার সর্বোচ্চ ৬৫.৫৩৫ মিলিসেকেন্ড সময় গণনা করতে পারে সেহেতু,
১,০০০ / ৬৫.৫৩৫ = ১৫.২৫৯০ সংখ্যক বার আমাদের টাইমারের কাউন্ট রিপিট করতে হবে। কিন্তু যেহেতু এটি একটি ভগ্নাংশ সংখ্যা সেহেতু এই সংখ্যকবার তো লুপ ঘুরানো যাবেনা। এর জন্যে আমরা দশমিক পয়েন্টের আগ সংখ্যা পর্যন্ত লুপ ঘুরাবো। অর্থাৎ ১৫ সংখ্যকবার টাইমারকে ওভার-ফ্লো হতে দিব। ১৬ বিটের টাইমার একবার ওভার-ফ্লো হতে সময় লাগে ৬৫.৫৩৫ মিলিসেকেন্ড, তাহলে ১৫ সংখ্যকবার লুপ ঘুরাতে সময় লাগবে মোট = ১৫ * ৬৫.৫৩৫ মিলিসেকেন্ড = ৯৮৩.০২৫ মিলিসেকেন্ড। কিন্তু আমাদের টার্গেট হল ১,০০০ মিলিসেকেন্ড। যেহেতু আমরা দশমিকের পরের সংখ্যা নেগ্লেক্ট করেছি সেহেতু টার্গেট সময়ের চাইতে আমাদের কিছু সময় কম এসেছে।

সময়ের ঘাটতি = ১,০০০ - ৯৮৩.০২৫ = ১৬.৯৭৫ মিলিসেকেন্ড।
এখন এইসময় তো আমরা টাইমার দিয়ে খুব সহজেই গণনা করতে পারি। টাইমার রেজিস্টারের মান হিসাবের জন্যে আমাদের সুত্র হল-

Register_value = Timer Max Value - (Delay / tick)
= ৬৫,৫৩৬ - ((১৬.৯৭৫ * ১০০০) / ১)
= ৬৫,৫৩৬ - ১৬৯৭৫
= ৪৮,৫৬০ হেক্সাডেসিমেলে BDB1

তাহলে ১৫ নম্বর বার ওভার-ফ্লো হওয়ার পরে ১৬ নম্বরের বার আমাদের টাইমার রেজিস্টারের ভ্যালু হবে,
TH0 = 0xBD এবং TL0 = 0xB1

এই সবকিছুই আমাদেরকে ইন্টারাপ্ট-সার্ভিস-রুটিনের মাঝে সেট করে দিতে হবে। মূলত কতবার ওভার-ফ্লো হচ্ছে তা আমরা ইন্টারাপ্ট-সার্ভিস-রুটিনের মধ্যে কোন একটি ভ্যারিয়েবেলের মাধ্যমে কাউন্ট করতে পারি এবং যখনই আমাদের উক্ত নম্বর অর্থাৎ ১৫ পেয়ে যাব তখনই একটি কন্ডিশনের মাধ্যমে টাইমার রেজিস্টারের নতুন ভ্যালু দুটি সেট করে দিব। এভাবেই আমরা টাইমার দিয়ে ১ সেকেন্ডের ডিলে তৈরি করতে পারি। শুধু ১ সেকেন্ডের ডিলেই নয় যেকোন সময়ের ডিলে আমরা এভাবে হিসাব করে তৈরি করে নিতে পারি। বিষয়টি এখনও ক্লিয়ার না হয়ে থাকলে কোড অংশটুকু দেখে নিই। তাহলেই ক্লিয়ার হয়ে যাবে কনসেপ্টটি।



 #include<reg52.h>  
 sbit led = P2^0;                //declare P2.0 pin as output pin  
 unsigned char i = 0;            //global interrupt to count the over-flow number  
 void init_timer(void);          //init_timer() function prototype  
 void main()  
 {  
      P2 = 0xFE;                 //declare P2.0 bit as ouput b11111110  
      init_timer();              //just initialize the timer0 at the very beginning  
      while(1)                   //infinite loop to run the program continuous  
      {  
           //do other work here. because interrupt takes care of toggling led  
      }  
 }  
 /*  
      FCPU = 12 MHz  
      Timer0 Frequency = 12 / 12 = 1 MHz  
      1 tick = 1 / Timer0 Frequency  
             = 1 / 1     MHz  
             = 1 uS  
      our target = 1 second = 1000 ms  
      1000ms / 65.535ms = 15.2590  
      15 times overflow needs-   
      15 * 65.535 = 983.025 ms  
      lack time = 1000 - 983.025 = 16.975 ms  
      delay = tick * 1 uS  
      count = delay / tick  
      Register Value = Timer Max - count  
                     = Timer Max - (delay / tick)  
      for 16.975 ms delay   
      ---------------  
      Register Value = Timer Max - (delay / tick)  
                     = 65,536 - ((16.975 * 1000) / 1)  
                     = 65,536 - 16,975  
                     = 48,560 in hex => 0xBD B1  
                                          -- --  
                                         TH0 TL0  
 */  
 void init_timer()  
 {  
      TMOD = 0x01;            //set timer0 in mode1  
      TH0 = 0x00;             //load 0x00 in TH0 and  
      TL0 = 0x00;             //load 0x00 in TL0 to get 65.535ms  
      ET0 = 1;                //enbale Timer0 interrupt in IE register  
      EA = 1;                 //enable global interrupt in IE register  
      TR0 = 1;                //run timer0  
 }  
 void timer_0() interrupt 1  
 {  
      if(i >= 15)               //check whether the 15 times overflow has been occured  
      {  
           TR0 = 0;             //stop the timer first  
           TH0 = 0xBD;          //load 0xBD to THO  
           TL0 = 0xB1;          //and load 0xB1 to TLO to count 16.975 ms  
           TR0 = 1;             //start the timer0 again  
           while(TF0 == 0);     //wait until over-flow  
           led =! led;          //change led state  
           TF0 = 0;             //clear the flag bit  
           i = 0;               //make overflow counter zero again  
      }  
      i++;                      //count the overflow number  
 }  
উপরের কোডের সবকিছুই আমাদের বোঝার কথা। আমরা এখানে ১ সেকেন্ডের একটি ডিলে তৈরি করেছি। কিন্তু প্রকৃতপক্ষে এখানেও ১ সেকেন্ডের কিছু কম বেশি আছে। কারন আমরা লজিক গুলো যে সি কোড দিয়ে করেছি সেখানে হয়ত দুই এক মেশিন সাইকেল এদিক অদিক হয়েছে। তারপর ও আমরা অন্ধের মত লুপ না ঘুরিয়ে টাইমার পেরিফেরালস্‌ দিয়ে এখন থেকে যেকোন delay() টাইপের ফাংশন তৈরি করে নিতে পারব বলে আশা করি। যতটা সম্ভব টাইম রিলেটেড কাজ আমরা মাইক্রোকন্ট্রোলারের টাইমার পেরিফেরালস্‌কে কাজে লাগিয়েই করার চেষ্টা করব।

Download  Project in Timer

No comments

Theme images by Dizzo. Powered by Blogger.