الصنّاع العرب

مسجلات الإزاحة (Shift Registers)

نظرة عامة

هل سبق أن وجدت نفسك بحاجة للتحكم في عدة ديودات مُضيئة (LED’s) معاً؟ هل سبق أن وجدت نفسك بحاجة للمزيد من أطراف الإدخال والإخراج (I/O) على وجه العموم؟ حسناً، في هذا الدرس سنتحدث عن تقنية ضرورية ستحتاجها في حال أردت القيام بما سبق، ويُطلق عليها مُسجلات الإزاحة. ما هي مسجلات الإزاحة؟ لماذا تمثل أهمية لنا؟ وكيف نستخدمها؟ كل هذه الأسئلة وغيرها سنجيب عليها خلال درسنا هذا.

مواضيع مقترحة للقراءة

إليك بعض المفاهيم الأساسية التي نقترح عليك أن تقرأها قبل الخوض في هذا الدرس:

ما هو مسجل الإزاحة؟

مسجل الإزاحة هو عبارة عن شريحة الكترونية تسمح بزيادة عدد المدخلات (inputs) أو المخرجات (outputs) الخاصة بمتحكم دقيق (microcontroller).

مُسجل الإزاحة 74HC595 على شكل حزمة DIP

وهذا يتم من خلال تحويل البيانات بين الشكلين التسلسلي (serial) والمتوازي (parallel). حيث يقوم المعالج الدقيق (microprocessor) بالاتصال بمسجل الإزاحة باستخدام المعلومات التسلسلية، بينما يقوم مسجل الإزاحة بجمع أو إخراج المعلومات بشكل متوازي (عبر عدة منافذ).

لديك العديد من الأزرار؟ لم لا تفكر في استخدام مُسجل إزاحة!

تأتي مُسجلات الإزاحة في شكلين رئيسيين: الأول له دخل تسلسلي وخرج متوازي SIPO (Serial-In-Parallel-Out) مثل المُسجل 74HC595، والثاني له دخل متوازي وخرج تسلسلي PISO (Parallel-In-Serial -Out) مثل المسجل 74HC165. النوع الأول (SIPO) يفيد في التحكم في عدد كبير من المخرجات (بما في ذلك الديودات المضيئة)، بينما النوع الآخر (PISO) يفيد في تجميع عدد كبير من المدخلات معاً، مثل الأزرار.

نسخة مثبتة على لوح من مُسجل الإزاحة 74HC165.

لماذا إزاحة البتات (Bits)

في الغالب يتم استخدام مُسجلات الإزاحة بغرض توفير المنافذ (الأرجل) (pins) الموجودة على المتحكم الدقيق. فكل مُتحكم دقيق له عدد محدود من المنافذ من أجل المدخلات والمخرجات الرئيسية (general inputs and outputs (GPIO)).

إذا كان هناك أحد المشاريع بحاجة للتحكم بـ 16 ديود مضيء فسيطلب ذلك استخدام 16 منفذ من منافذ الدخل/الخرج الخاصة بالمتحكم الدقيق. في حال لم يكن لديك 16 منفذ مُتاح فهنا تأتي أهمية مُسجلات الإزاحة. فباستخدام اثنين من مُسجلات الإزاحة متصلين على التوالي يُمكننا التحكم بالديودات المضيئة الـ 16 من خلال أربعة منافذ دخل/خرج فقط. هذا يُشكل فرق كبير. ويمكن توفير المزيد من المنافذ عن طريق توصيل المزيد من مُسجلات الإزاحة معاً.

أحد الأمثلة من العالم الواقعي على استخدام مُسجل إزاحة لتجميع المدخلات هو جهاز التحكم الخاص بنينتندو. فالمتحكم الدقيق الأساسي الموجود بداخل جهاز نينتندو يحتاج للحصول على ضغطات الأزرار من جهاز التحكم، وللقيام بتلك المهمة يتم استخدام مُسجل إزاحة.

مثال على مُسجل إزاحة

العتاد (Hardware)

في هذا المثال سنقوم باستخدام لوح  74hc165 وبطاقة أردوينو أونو (Arduino Uno).

لوح  74hc165 مُوضحاً عليه المنافذ (pins) ووظائفها.

يحتاج مُسجل الإزاحة ذو الثمانية بتات (8 bit) لأربعة خطوط اتصال مع المُتحكم الدقيق. واحد من أجل الساعة (Clock) لتوقيت نقل البيانات، واحد لتمكين الساعة، واحد لتحميل/ تخزين/ إزاحة (loading/latching/shifting) البتات، وواحد من أجل النقل التسلسلي للبيانات.

شكل التوصيلات على برنامج Fritzing.

قم بتوصيل منفذ الساعة (CLK) بالمنفذ 12، ومنفذ تمكين الساعة (clock enable) (CE) بالمنفذ 9. تقوم الساعة بتحديد التردد الذي يتم عبره إزاحة البتات، بينما خط تمكين الساعة يسمح لإشارة الساعة بالانتشار عبر دائرة الإزاحة.

قم بتوصيل منفذ الإزاحة/التحميل (SH/LD) بالمنفذ 8. انتقال منفذ التحميل إلى الحالة المنخفضة low يأمر مُسجل الإزاحة بإمساك الحالة الحالية لمنافذ الدخل الثمانية (من A حتى H). يُمكن توصيل المنافذ A-H بأي نوع من المدخلات مثل الأزرار أو المفاتيح أو دائرة ترانزستور رقمية. وإذا أردت اختبارها يُنصح بأن تقوم بتوصيلها مباشرة بمصدر الطاقة أو بالأرضي (ground) للتأكد من أن كل شيء يسير على ما يرام. في هذا المثال سنقوم بتوصيل إحداها بزر باستخدام مقاوم رفع (pull up resistor) وتوصيل الباقي بمصدر الطاقة أو بالأرضي.

قم بتوصيل منفذ الخرج التسلسلي (SER_Out) بالمنفذ رقم 11. هذا المنفذ هو حيث يتم استقبال المعلومات التسلسلية من مُسجل الإزاحة. كذلك قم بتوصيل منفذ الدخل التسلسلي (SER_IN) بالأرضي. إذا كنت تريد توصيل عدة مُسجلات إزاحة معاً فيجب أن تقوم بتوصيل منفذ الدخل التسلسلي للمُسجل بمنفذ الخرج التسلسلي لمُسجل الإزاحة السابق له. أما المُسجل الأول في السلسلة فيجب أن يبقى منفذ الدخل الخاص به مُتصلاً بالأرضي، بينما يتم توصيل منفذ الخرج التسلسلي لآخر مُسجل ضمن السلسلة بالمُعالج الدقيق بدلاً من توصيله بمُسجل إزاحة آخر.

لا تنسى توصيل منفذي الطاقة (2-6V) والأرضي أيضاً. بعد أن قمنا بتوصيل كل شيء دعونا نلقي نظرة على البرنامج المُستخدم.

البرنامج

إليكم ملخص ما يقوم هذا الكود بفعله. حيث يقوم بتهيئة جميع المنافذ التي قمنا بتوصيلها بالمخرجات باستثناء المنفذ الذي يتم من خلاله استقبال المعلومات التسلسلية. نقوم بضبط منفذ الساعة والإزاحة على قيم ابتدائية (مرتفع high) كما هو مُدون في صحيفة البيانات.

من أجل قراءة حالة المنافذ من A إلى H نحتاج لأن نأمر مُسجل الإزاحة بإمساك حالة المنافذ، ويتم ذلك عبر جعل منفذ التحميل في حالة منخفضة لفترة وجيزة (5 ميكرو ثانية). وعندما يتم تحميل المنافذ يجب التأكد أن جميع المنافذ الباقية في الوضع الابتدائي المنصوص عليه في صحيفة البيانات واستخدام دالة shiftIn الخاصة بالأردوينو لإمساك قيم المنافذ الثمانية A-H بداخل بايت يُسمى incoming. يتم طباعة البيانات بوضوح على المنفذ التسلسلي. بعد ذلك يتم الانتظار ومن ثم تكرار العملية مرة أخرى. إذا كنت قد وصلت المنافذ بالشكل الذي استخدمناه في الصورة التخطيطية بالأعلى فسيكون من السهل القيام باختبار للتأكد من عمل العتاد بشكل صحيح.

حان وقت الكود:

// HARDWARE CONNECTIONS
// Connect the following pins between your Arduino and the 74HC165 Breakout Board
// Connect pins A-H to 5V or GND or switches or whatever
const int data_pin = 11; // Connect Pin 11 to SER_OUT (serial data out)
const int shld_pin = 8; // Connect Pin 8 to SH/!LD (shift or active low load)
const int clk_pin = 12; // Connect Pin 12 to CLK (the clock that times the shifting)
const int ce_pin = 9; // Connect Pin 9 to !CE (clock enable, active low)

byte incoming; // Variable to store the 8 values loaded from the shift register

// The part that runs once
void setup() 
{                
  // Initialize serial to gain the power to obtain relevant information, 9600 baud
  Serial.begin(9600);

  // Initialize each digital pin to either output or input
  // We are commanding the shift register with each pin with the exception of the serial
  // data we get back on the data_pin line.
  pinMode(shld_pin, OUTPUT);
  pinMode(ce_pin, OUTPUT);
  pinMode(clk_pin, OUTPUT);
  pinMode(data_pin, INPUT);

  // Required initial states of these two pins according to the datasheet timing diagram
  digitalWrite(clk_pin, HIGH);
  digitalWrite(shld_pin, HIGH);

}

// The part that runs to infinity and beyond
void loop() {

  incoming = read_shift_regs(); // Read the shift register, it likes that

  // Print out the values being read from the shift register
  Serial.println("\nThe incoming values of the shift register are: ");
  Serial.print("ABCDEFGH : ");
  print_byte(incoming); // Print every 1 and 0 that correlates with A through H
  //Serial.println(incoming,BIN); // This way works too but leaves out the leading zeros

  delay(2000); // Wait for some arbitrary amount of time

}

// This code is intended to trigger the shift register to grab values from it's A-H inputs
byte read_shift_regs()
{
  byte the_shifted = 0;  // An 8 bit number to carry each bit value of A-H

  // Trigger loading the state of the A-H data lines into the shift register
  digitalWrite(shld_pin, LOW);
  delayMicroseconds(5); // Requires a delay here according to the datasheet timing diagram
  digitalWrite(shld_pin, HIGH);
  delayMicroseconds(5);

  // Required initial states of these two pins according to the datasheet timing diagram
  pinMode(clk_pin, OUTPUT);
  pinMode(data_pin, INPUT);
  digitalWrite(clk_pin, HIGH);
  digitalWrite(ce_pin, LOW); // Enable the clock

  // Get the A-H values
  the_shifted = shiftIn(data_pin, clk_pin, MSBFIRST);
  digitalWrite(ce_pin, HIGH); // Disable the clock

  return the_shifted;

}

// A function that prints all the 1's and 0's of a byte, so 8 bits +or- 2
void print_byte(byte val)
{
    byte i;
    for(byte i=0; i<=7; i++)
    {
      Serial.print(val >> i & 1, BIN); // Magic bit shift, if you care look up the <<, >>, and & operators
    }
    Serial.print("\n"); // Go to the next line, do not collect $200
}

وهذا مثال على الخرج:

القيم الآتية من مُسجل الإزاحة هي:

ABCDEFGH  :  11110000

والآن قم بتجربة توصيل كل منافذ الدخل بأزرار أو إضافة مُسجل إزاحة آخر إلى الدائرة. إذا قمت بتوصيل أكثر من مسجل إزاحة معاً فسيكون عليك تعديل الكود قليلاً من خلال القيام بالتحميل مرة واحدة ومن ثم تطبيق دالة shiftIn لكل مُسجل إزاحة لديك قبل التحميل مُجدداً.

المصادر والمضي قُدماً

حسناً، لقد تعرفت الآن على الشريحة التي تحتاجها لاستخدامها عندما تقابل مُشكلة نقص خطوط الإدخال/الإخراج. نأمل أن يكون هذا الدرس قد ساعدك في توصيل المزيد من المدخلات إلى مشروعك. إذا كنت تريد المزيد من المساعدة للتعرف على كيفية إضافة المزيد من المُخرجات فهناك درس رائع من مدونة Bildr من شأنه أن يساعدك لعمل ذلك.

إذا كان لديك فضول لمعرفة كيفية عمل هذه الأجهزة نقترح عليك دراسة بعض المنطق الرقمي، وفي النهاية ستقوم بدراسة جهاز يُسمى القلاب (flip-flop) والذي هو مفتاح التعرف على كيفية عمل هذه الأجهزة. من الجيد كذلك أن تقوم بالاطلاع على الرسم البياني للتوقيت (timing diagram) بإحدى صحف البيانات للتعرف على ما يحدث خلال عملية الإزاحة. نتمنى لك وقتاً مُمتعاً!

تمّت ترجمة هذه المادّة من موقع sparkfun تحت تصريح كرييتف كومّونز 3 (Creative Commons 3.0)

عبدالله خيري

أضف تعليق

اترك رد

تابعنا