সাত অধ্যায়
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 বাইট।
দশমিক(.) সংখ্যা ব্যতীত সকল ধনাত্মক এবং ঋণাত্মক পূর্ণ সংখ্যা এই টাইপের মধ্যে পড়ে। যেমন- 0, -10, 10 ইত্যাদি
সি প্রোগ্রামিং এ ইন্টেজার টাইপের ভ্যারিয়েবল ডিক্লেয়ার করার জন্য int কীওয়ার্ড ব্যবহৃত হয়। উদাহরণস্বরূপঃint roll_no;
এখানে roll_no হলো ইন্টেজার টাইপের ভ্যারিয়েবল।
সি প্রোগ্রামিং এ আপনি একটি ডিক্লেয়ারেশনের মাধ্যমে অনেক ভ্যারিয়েবলকে একই সঙ্গে ডিক্লেয়ার করতে পারেন। উদাহরনস্বরুপঃ
এখানে 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) করবে না।
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) ফর্মেও উপস্থাপন করা যায়। উদাহরনস্বরুপঃ
এখানে accountBalance এবং bookPrice উভয়েই ফ্লোটিং টাইপ ভ্যারিয়েবল।
সি প্রোগ্রামিং এ ফ্লোটিং ভ্যালুকে এক্সপনেনশিয়াল(exponential) ফর্মেও উপস্থাপন করা যায়। উদাহরনস্বরুপঃ
float normalizationFactor = 22.442e2;
সি প্রোগ্রামিং অপারেটর
- এরিথমেটিক অপারেটর - Arithmetic Operator
- ইনক্রিমেন্ট এবং ডিক্রিমেন্ট অপারেটর- Increment and Decrement Operator
- এসাইনমেন্ট অপারেটর - Assignment Operator
- রিলেশনাল অপারেটর - Relational Operator
- লজিকাল অপারেটর - Logical Operator
- কন্ডিশনাল অপারেটর - Conditional Operator
- বিটওয়াইজ অপারেটর - Bitwise Operator
- স্পেশিয়াল অপারেটর - Special Operator
সি এরিথমেটিক অপারেটর
এরিথমেটিক অপারেটর গাণিতিক হিসাব নিকাশ যেমন- যোগ, বিয়োগ, গুন এবং ভাগ ইত্যাদি কার্য সম্পন্ন করে।
অপারেটর | অপারেটেরের অর্থ | উদাহরণ(int a=11, b=5) | ফলাফল |
---|---|---|---|
+ | যোগ বা ইউনারী(unary) যোগ | a + b | 16 |
- | বিয়োগ বা ইউনারী বিয়োগ | a - b | 6 |
* | গুন | a * b | 55 |
/ | ভাগ | a / b | 2 |
% | ভাগের পরে ফলাফল ভাগশেষ(মডিউলো অপারেটর) | a % b | 1 |
সি এসাইনমেন্ট অপারেটর
ভ্যারিয়েবলে ভ্যালু এসাইন করা বা জমা রাখার জন্য এসাইনমেন্ট(assignment) অপারেটর ব্যবহৃত হয়। সবচেয়ে বেশী ব্যবহৃত এসাইনমেন্ট অপারেটর হলো =
অপারেটর | উদাহরন(int a=11, b=5) | একই রকম | ফলাফল |
---|---|---|---|
= | a = b | a = b | 5 |
+= | a += b | a = a+b | 16 |
-= | a -= b | a = a-b | 6 |
*= | a *= b | a = a*b | 55 |
/= | a /= b | a = a/b | 2 |
%= | a %= b | a = a%b | 1 |
সি রিলেশনাল অপারেটর
সি প্রোগ্রামিং এ রিলেশনাল অপারেটর(relational operator) দুটি অপারেন্ডের মধ্যে সম্পর্ক যাচাই করে। রিলেশন সত্যি(true) হলে 1 রিটার্ন করে; রিলেশন মিথ্যা(false) হলে 0 রিটার্ন করে।
সিদ্ধান্ত গ্রহণ(decision making) এবং লুপ(loop) এ রিলেশনাল অপারেটর ব্যবহৃত হয়।
অপারেটর | অপারেটরের অর্থ | উদাহরণ(int a=11, b=5) | ফলাফল |
---|---|---|---|
== | Equal to | a == b | False |
> | Greater than | a > b | True |
< | Less than | a < b | False |
!= | Not equal to | a != b | True |
>= | Greater than or equal to | a >= b | True |
<= | Less than or equal to | a <= b | False |
সি লজিক্যাল অপারেটর
সি প্রোগ্রামিং এ &&, || এবং ! অপারেটরসমূহকে লজিক্যাল(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 AND | x& y = 0 (0000 0000) | 0 |
| | Bitwise OR | x | y = 14 (0000 1110) | 14 |
^ | Bitwise exclusive OR | x ^ y = 14 (0000 1110) | 14 |
~ | Bitwise complement | ~x = -11 (1111 0101) | -11 |
<< | Shift left | x<< 2 = 42 (0010 1000) | 42 |
>> | Shift right | x>> 2 = 2 (0000 0010) | 2 |
বিটওয়াইজ অপারেটর সম্মন্ধে আরোও জানতে আমাদের সি বিটওয়াইজ অপারেটর অধ্যায় ভিজিট করুন
অন্যান্য অপারেটর
কমা অপারেটর
সম্পর্কযুক্ত এক্সপ্রেশনসমূহকে একইসঙ্গে ডিক্লেয়ার(declare) করার জন্য কমা(comma) অপারেটর ব্যবহৃত হয়। উদাহরনস্বরুপঃ
int a, b = 10, c = 5, d;
sizeof অপারেটর
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
}
No comments