১১. সিরিয়াল কমিউনিকেশনের চারটি মোড এবং এদের ডিটেইল্‌স



এর আগের পোস্টে আমরা সিরিয়াল কমিউনিকেশন সম্পর্কে মোটামোটি ভাবে একটি ধারনা পেয়েছি এবং সেই সাথে 8051 মাইক্রোকন্ট্রোলারের সিরিয়াল কমিউনিকেশন পেরিফেরাল্‌স রিলেটেড রেজিস্টার, বিট এবং আর্কিটেকচার সম্পর্কেও ধারনা পেয়েছি। সেখান থেকেই আমারা জানতে পেরেছি যে 8051 মাইক্রোকন্ট্রোলারে সিরিয়াল কমিউনিকেশন চারটি ভিন্ন ভিন্ন মোডে হয়ে থাকে। সেই সাথে এটাও জেনেছিলাম যে UART প্রোটোকল অর্থাৎ অ্যাসিঙ্ক্রোনাস প্রোটোকলই প্রায় সব মাইক্রোকন্ট্রোলারের ক্ষেত্রে অধিক প্রচলিত। এটার কারন ছিলো কম কানেক্টিং ওয়্যার (২ টি TXD & RXD) লাগে।

আজকে আমরা এই চারটি মোড সম্পর্কে জানবো এবং UART প্রোটোকলের ডেটা প্যাকেট কীভাবে কাজ করে তা সম্পর্কেও জানবো।


UART প্রোটোকল কীভাবে কাজ করে প্রথমে, সেই বিষয়ে জেনে নেয়া যাক। UART হল অ্যাসিঙ্ক্রোনাস কমিউনিকেশন প্রোটোকল। অর্থাৎ এই প্রোটোকলে ক্লক পাল্‌স ব্যবহৃত হয়না। এক্ষেত্রে ক্লক পালসে্‌র বদলে ডেটা ট্রান্সফার রেট (bps) টার্মটি ব্যবহার করা হয়। যেহেতু ডেটা আদান-প্রদান নির্দিষ্ট ক্লক পালসে্‌ হয়না, সেহেতু ডেটাকে একটি নির্দিষ্ট সিকুয়েন্সে পাঠানো হয় যাতে মাইক্রোকন্ট্রোলার বুঝতে পারে যে কোথায় ডেটা বিট শেষ হল আর কোথায় ডেটা বিট শুরু হল। এরজন্যে  যে ডেটা সিরিয়ালি পাঠানো হবে সেই ডেটা বিটের সাথে আরও কিছু প্রয়োজনীয় বিট জুড়ে দিয়ে আগে ডেটা প্যাকেট তৈরি করা হয়। এই ডেটা প্যাকেটে থাকে একটি স্টার্ট বিট, একটি বা দুটি স্টপ বিট এবং একটি প্যারিটি বিট। তবে শেষোক্তটি অপশনাল, থাকতেও পারে অথবা না ও থাকতে পারে। এটা মূলত ডেটা প্যাকেটের এরর নির্ণয়ের জন্যে ব্যবহৃত হয়। মোটামোটি ভাবে ডেটা প্যাকেট দেখতে নিচের মত হয়।


মাঝের ডেটা-ফ্রেম অংশটুকু হল আমরা যেই ডেটা পাঠাতে চাই সেই ডেটা। যেমন : এক মাইক্রোকন্ট্রোলার থেকে আরেক মাইক্রোকন্ট্রোলারে 'A' ক্যারেক্টারটি পাঠাতে চাইলে ডেটা-ফ্রেম অংশে 'A' এর ASCII ভ্যালু হবে আবার  'B' ক্যারেক্টারটি পাঠাতে চাইলে ডেটা-ফ্রেম অংশে 'B' এর ASCII ভ্যালু হবে। আর প্রথম অংশের স্টার্ট বিট, শেষ অংশের প্যারিটি বিট এবং স্টপ বিট এগুলো সাহায্যকারী বিট হিসেবে জাস্ট সাহায্য করে। পুরো ডেটা-ফ্রেমকে ক্যাপসিউলের মত ঘিরে রাখে। এই বিটগুলো রিড করেই মাইক্রোকন্ট্রোলার বুঝতে পারে যে কখন ডেটা ট্রান্সফার শুরু হল এবং কখন শেষ হল। এই সাহায্যকারী বিটগুলো সম্পর্কে সংক্ষেপে জেনে নেয়া যাক।

start bit : এই বিটটি মাইক্রোকন্ট্রোলারকে বা UART ফিচার যুক্ত IC কে বলে দেয় যে ডেটা বিট ট্রান্সফার হওয়া বা রিসিভ হওয়া শুরু হয়েছে। এইজন্যেই এই বিটটি কে স্টার্ট বিট বলে। এই বিটটি সাধারণত লো (0) হয়। কোন ডেটা যখন আদান-প্রদান হয় না তখন TXD পিন এবং RXD  পিন উভয়ই হাই (1) থাকে। কোন বিট আদান-প্রদান হওয়ার ঠিক আগে একটি হাই টু লো সিগন্যাল ট্র্যানজিশন হয় এই পিনদ্বয়ে। এই যে হাই সিগন্যাল টু লো সিগন্যাল, এটাই আসলে স্ট্যার্ট বিট। অর্থাৎ স্ট্যার্ট বিটের মান হয় শূন্য।

stop bit : এই বিট একটি ও হতে পারে আবার দুটিও হতে পারে। অর্থাৎ ডেটা ফ্রেম এক স্টপ বিট বিশিষ্টও হতে পারে আবার দুই স্টপ বিট বিশিষ্টও হতে পারে। স্টপ বিট সাধারণত হাই বিট হয়ে থাকে। এই বিটের উপস্থিতির জন্যই মাইক্রোকন্ট্রোলার বুঝতে পারে যে ডেটা ট্রান্সফার শেষ হয়েছে। মানে ডেটা আদান-প্রদান শেষ হয়ে গেলে TXD এবং RXD পিনদ্বয় লো টু হাই হয়ে যায়। আর কোন ডেটা ট্রান্সফার যদি না হয় তাহলে এই পিনদ্বয় এই হাই স্টেট এই থেকে যায়।

parity bit : এই বিটটি অপশনাল। এই বিটটি দিয়ে আসলে আদান-প্রদানকৃত ডেটার এরর চেক করা হয়। এর মান 1 অথবা 0 হতে পারে। আমরা আগেই জেনেছি যে ডেটা আদান-প্রদান আসলে 0 এবং 1 এর সিকুয়েন্স ছাড়া আর কিছুই না। বিভিন্ন কারনে যেমন লং ডিস্টেন্স, নয়েজ বা ইলেক্ট্রোম্যাগনেটিক সিগন্যালের কারনে এই ডেটা হয় চেঞ্জ হয়ে যেতে পারে। যে ডেটা পাঠানো হয়েছে তা পরিবর্তন হয়েছে কিনা তা চেক করার জন্যেই এই বিটটি ব্যবহার করা হয়। কোন একটি ডেটা ফ্রেমে জোড় সংখ্যক 1 ও থাকতে পারে আবার বিজোড় সংখ্যক 1 ও থাকতে পারে। জোড় সংখ্যক 1 এর জন্যে প্যারিটি বিট 0 নির্ধারিত। একে বলে even parity. আর বিজোড় সংখ্যক 1 এর জন্যে প্যারিটি বিট 1 নির্ধারিত। একে বলে odd parity. এখন ধরা যাক আমরা যে ডেটা ট্রান্সফার করতে চাই সেখানে জোড় সংখ্যক 1 আছে এবং আমরা প্যারিটি বিট 0 করে দিয়েছি। তাহলে ডেটা রিসিভ হওয়ার পর হাই বিট এর নম্বর চেক হবে এবং জোড় সংখ্যক হাই (1) বিট পাওয়া গেলে প্যারিটি বিট অনুযায়ী তা ঠিক থাকবে। কিন্তু প্যারিটি বিট 0 থাকা সত্ত্বেও যদি রিসিভ করা ডেটায় বিজোড় সংখ্যক 1 পাওয়া যায় তাহলে ডেটায় এরর আছে বোঝা যাবে। 
ঠিক একই ভাবে আমরা যদি বিজোড় সংখ্যক হাই (1) বিটের ডেটা পাঠাই এবং এক্ষেত্রে প্যারিটি বিট 1 করে দিই। তাহলে রিসিভ হওয়ার পর ডেটা বিটে 1 এর সংখ্যা চেক করা হবে এবং বিজোড় সংখ্যক হাই (1) বিট পেলে প্যারিটি অনুযায়ী ডেটা ঠিক আছে বোঝা যাবে। কিন্তু যদি কোনক্রমে জোড় সংখ্যক হাই (1) বিট পাওয়া যায় তাহলে প্যারিটি অনুযায়ী রিসিভ্‌ড ডেটায় এরর আছে সেটি বোঝা যাবে। 

এই হল মোটামোটি ভাবে UART এর ডেটা প্যাকেটের পরিচয়। এই ডেটা প্যাকেটের প্রত্যেকটি বিট পর্যায়ক্রমে একটির পর একটি আদান-প্রদান হয়ে থাকে। চারটি মোডের কোনটিতে কীভাবে এসব ডেটা আদান-প্রদান হয়ে থাকে এবারে আমরা সে সম্পর্কে জেনে নিবো। 8051 মাইক্রোকন্ট্রোলারের সিরিয়াল কমিউনিকেশনের চারটি মোড আছে।

Mode-0 : এই মোডে 8051 মাইক্রোকন্ট্রোলার অনেকটা shift register এর মত কাজ করে। শিফট রেজিস্টার যেমন একটি নির্দিষ্ট ক্লক পালস্‌ অনুযায়ী বিট বাই বিট ট্রান্সফার করে থাকে, এই মোডেও ডেটা আদান-প্রদান অনেকটা তেমন ভাবেই হয়ে থাকে। ক্লক পালস্‌ অনুযায়ী কোন অপারেশান হলে সেটাকে সিঙ্ক্রোনাস অপারেশন বলে। তার মানে এই কমিউনিকেশনটি হল সিঙ্ক্রোনাস কমিউনিকেশন। এই কমিউনিকেশন সম্পর্কে আরেকটি অদ্ভুত বিষয় হল, এই কমিউনিকেশনে মাইক্রকন্ট্রোলারের TXD পিন দিয়ে ক্লক সিগন্যাল বের হয় এবং RXD পিন দিয়ে ডেটা আদান-প্রদান হয়। অর্থাৎ একটি মাত্র পিন দিয়েই ডেটা আদান প্রদান হয়। এক্ষেত্রে অবশ্যই ডেটা আদান-প্রদান সাইম্যাল্টিনিয়াসলি হতে পারে না। এজন্যে এই কমিউনিকেশন হল হাফ-ডুপ্লেক্স সিস্টেম। এই যে TXD পিন দিয়ে ক্লক পালস্‌ বের হয় এই ক্লক পালসে্‌র ফ্রিকুয়েন্সি হল ক্রিস্টাল অসসিলেটরের ১২ ভাগ, অর্থাৎ স্ট্যার্ন্ডাড ক্রিস্টাল অসসিলেটরের (১২ মেগাহার্টজ) জন্যে TXD পিনের ফ্রিকুয়েন্সি হল ১ মেগাহার্টজ। ডেটা আদান-প্রদানের ক্ষেত্রে RXD পিন ৮ বিটের ডেটা একবার ট্রান্সমিট করে এবং এরপর ৮ বিটের ডেটা রিসিভ করে।





Mode 1 :  এটা হল স্ট্যান্ডার্ড UART মোড। যেকোন ডিভাইসের সাথে মাইক্রোকন্ট্রোলার দিয়ে সিরিয়াল কমিউনিকেশন করতে হলে আমরা এই মোডেই আমাদের মাইক্রোকন্ট্রোলারকে কনফিগার করবো। এই মোডটি হল অ্যাসিঙ্ক্রোনাস মোড। অর্থাৎ এই মোডে কোন ক্লক সিগন্যাল দরকার হয়না। শুধু বিট ট্রান্সফার রেট কনফিগার (বড রেট) করে দিতে হয়। একটি বিট আদান-প্রদান হতে সময় লাগে = ১ / বডরেট পরিমান। এই বডরেট, টাইমার-১ এর মাধ্যমে সেট করে দিতে হয়। এই মোডে ১০ বিটের ডেটা প্যাকেট আদান-প্রদান করা হয়। এই ১০ টি ডেটা-বিটের মধ্যে ১টি স্টার্ট বিট, ৮টি ডেটা বিট এবং ১টি স্টপ বিট থাকে। ডেটা বিটের ক্ষেত্রে LSB ফাস্টে এবং MSB সবার পরে আদান-প্রদান হয়।



আমরা আগেই জেনেছি যে যখন কোন ডেটা ট্রান্সমিট হয়না তখন TXD পিন হাই হয়ে থাকে এবং যখন কোন ডেটা রিসিভ না হয় তখন RXD পিন হাই হয়ে থাকে। যখনই ডেটা ট্রান্সমিট হওয়া শুরু করে তখনি TXD পিন হাই-টু-লো হয়ে যায়। এবং একে একে এর পর ডেটা বিট (প্রথমে LSB, এবং সবার শেষে MSB) ট্রান্সমিট হয়। সবার শেষে TXD পিন আবার লো-টু-হাই হয়ে যায় এবং এটিই স্টপ বিট। ঠিক এই সিকুয়েন্সই RXD পিনে ডেটা প্রবেশ করে। প্রথমে RXD পিন হাই থাকে যখন কোন ডেটা প্রবেশ না করে। TXD পিনের হাই-টু-লো  সিগন্যাল যখন RXD পিন রিসিভ করে তখন বুঝতে পারে যে ডেটা রিসিভ শুরু হয়েছে। এরপরের বিটগুলোকে সে ডেটা বিট হিসেবে গণ্য করে এবং রিসিভ করে একে একে বাফার রেজিস্টারে জমা করে। এরপর যখনই TXD পিনের লো-টু-হাই সিগন্যাল RXD পিন রিসিভ করে তখনই বুঝতে পারে যে ডেটা রিসিভ শেষ হয়েছে। 
তাহলে হিসাব মতে ৮ টি ডেটা বিট শিফট রেজিস্টারে জমা হয়। এবং ৯ নম্বর অর্থাৎ শেষ স্টপ বিটটি SCON রেজিস্টারের RB8 বিটে জমা হয়। অর্থাৎ এই মোডে মাইক্রোকন্ট্রোলার RB8 বিটের ভ্যালু হাই পেলেই বুঝতে পারে যে ১ বাইট ডেটা রিসিভ সম্পূর্ণ হয়েছে। এই সময় শিফট রেজিস্টার থেকে ডেটা বিট গুলো প্যারালাল ভাবে SBUF রেজিস্টারে প্রবেশ করে। এবং SBUF রেজিস্টার ডেটা পূর্ণ হয়ে গেলে SCON রেজিস্টারের RI বিট হাই হয়ে যায়।  এই যে স্টপ বিটটি RB8 বিটে জমা হয়ে গেলো, এই বিটটি রিড করে প্রোগ্রামার আসলে যাচাই করতে পারে যে ডেটা রিসিপশন ঠিক আছে কিনা? যদি এই বিটটি রিড করে হাই না পায়, তাহলে বুঝতে পারে যে ডেটা ট্রান্সমিশনে ঝামেলা আছে। এইসব প্রক্রিয়াই সম্পূর্ণ হয় মাত্র কয়েক মাইক্রোসেকেন্ডে।


Mode 2 & Mode 3 : এই মোড দুটি আসলে মাল্টিপ্রসেসর মোড নামে পরিচিত এদের ফাংশনালিটি একই রকমের, একটি মাইক্রোকন্ট্রোলার (মাস্টার) অনেকগুলো মাইক্রোকন্ট্রোলারের (স্লেভ) সাথে কমিউনিকেট করতে পারে। তবে একই সাথে অবশ্য একটি স্লেভের সাথেই কমিউনিকেট করতে পারে।



মোড-২ এবং মোড-৩ এর মধ্যে পার্থক্য হল মোড-২ এর বডরেট ফিক্সড এবং সেটা হল- 
f_baud = f_osc /32 অথবা f_osc / 16.

এবং মোড-৩ এর বডরেট হল ভ্যারিয়েবেল। এই ভ্যারিয়েবেল বডরেট বের করার সুত্র হল- 
f_baud = (2^smod / 32) * (f_osc / 12*(256 - TH1))

এখানে smod হল PCON রেজিস্টারের মোস্ট সিগনিফিক্যান্ট বিট, f_osc হল 11.0592 Mhz, এবং TH1 হল টাইমার-১ এর টাইম কাউন্ট করার জন্যে আপার ৮ বিটের রেজিস্টার।

এই মোডে TXD পিন দিয়ে ১১ বিটের ডেটা প্যাকেট বের হয় এবং RXD পিন দিয়ে ১১ বিটের ডেটা প্যাকেট রিসিভ হয়। এই ১১ বিটের মধ্যে ১টি হল স্টার্ট বিট, ৮ টি ডেটা বিট, ১টি প্রোগ্রামাবেল 9th  বিট এবং ১টি স্টপ বিট। এই প্রোগ্রামাবেল ৯ম বিটটি SCON রেজিস্টারের TB8 বিটে 0 অথবা 1 রাইটের মাধ্যমে নির্ধারণ করে দেয়া হয়। অর্থাৎ এই TB8 বিটে আমরা যে ডেটা লিখে দিব সেই ডেটাটিই ৯ম বিট হিসেবে ট্রান্সমিট হবে। আর যদি এই ৯ম বিটটি কে প্যারিটি বিট হিসেবে ব্যবহার করতে হয় তাহলে PSW রেজিস্টারের P বিটের ভ্যালুকে TB8 বিটে নিয়ে আসতে হয়। এই প্রোগ্রামাবেল ৯ম বিট এটি আসলে নির্ধারণ করে দেয় যে মাস্টার মাইক্রোকন্ট্রোলার , কোন স্লেভ মাইক্রোকন্ট্রোলারের সাথে কমিউনিকেট করবে? এই বিটটি 1 হলে, উক্ত ডেটা বাইট দ্বারা স্লেভ মাইক্রোকন্ট্রোলারের এড্রেস বোঝায়। এবং এই বিটটি 0 হলে, উক্ত ডেটা বাইট দ্বারা ডেটা বোঝায়। এই মোডে মাইক্রোকন্ট্রোলারকে কাজ করাতে হলে SCON রেজিস্টারের SM2 বিটটি সেট করে দিতে হবে। তারমানে সবগুলো স্লেভ মাইক্রোকন্ট্রোলারেই এই বিট টি সেট করা থাকবে।  এখন মাস্টার মাইক্রোকন্ট্রোলার এড্রেস বাইট পাঠালে তা সব স্লেভ মাইক্রোকন্ট্রোলার রিসিভ করবে। এবং যার এড্রেসের সাথে উক্ত এড্রেস মিলে যাবে সেই মাইক্রোকন্ট্রোলার SM2 বিট ক্লিয়ার করে নিবে যাতে করে এরপর যে ডেটা বাইট আসবে সেটা সে রিসিভ করতে পারে।

এখানে একটি বিষয় একটু ভালো করে বোঝা দরকার। সেটি হল-

যখন আমরা SM2 বিট ব্যবহার করছিলাম না অর্থাৎ MODE-1 এ তখন শেষ বিটটি (৯ম বিট) ছিল আমাদের স্টপ বিট। স্টার্ট বিট পাওয়ার পর থেকে বিট গণনা শুরু হয়। তাহলে ৮টি ডেটা বিটের পরে শেষ স্টপ বিটটি ৯ম বিট-ই হচ্ছে। এই ৯ম বিট সর্বদা যায় SCON রেজিস্টারের RB8 বিটে। এবং RB8 বিট হাই (1) হয়ে যাওয়ার অর্থই ছিল ডেটা রিসিপশন কমপ্লিট হয়েছে। কিন্তু MODE-2 এবং MODE-3 এ SM2 বিট ব্যবহার করার ফলে এই কেসটি চেঞ্জ হয়ে যায়। এক্ষেত্রে ৯ম বিটটি হয় প্রোগ্রামাবেল বিট যেটা আমাদের নিজেদেরকে প্রোগ্রাম করতে হয়। এবং এটা প্রোগ্রাম করার প্রধান উদ্দেশ্যই হল মাইক্রোকন্ট্রোলারকে বুঝানো যে কোন বাইটটি ডেটা বাইট আর কোন বাইট এড্রেস বাইট। তাই ডেটা রিসিভের ক্ষেত্রে এবার কিন্তু আমরা নিশ্চিত ভাবে বলতে পারবনা যে আমাদের ৯ম বিটটি হাই (1) হলেই ডেটা আদান-প্রদান থেমে যাবে। কারন এবারের RB8 বিট, যে ৯ম বিটটি রিসিভ করেছে সেটি স্টপ বিট না বরং প্রোগ্রামাবেল বিট।  এই ঝামেলা এড়ানোর জন্যে সর্বদা SM2 বিট ক্লিয়ার (0) রাখাই ভালো যাতে করে RB8 বিটে সর্বদা স্টপ বিট 1 জমা হয়।
এই মোড নিয়ে হয়ত এখনও অনেক ঝামেলা থেকেই গেলো। বাকি ঝামেলা টুকু আমরা পরবর্তী কোন পোস্টে প্র্যাক্টিকালই কিছু ইমপ্লেমেন্ট করে সল্ভ করার চেষ্টা করব। আর MODE-1 যেহেতু বেশি প্রয়োজনীয় সেহেতু এরপরের কোন পোস্টে আমরা এটার প্র্যাক্টিকাল ইমপ্লিমেন্ট দেখব এবং সেইসাথে এটার বডরেট হিসাব করাও শিখে নিব।

মন্তব্যসমূহ

এই ব্লগটি থেকে জনপ্রিয় পোস্টগুলি