กลับไปหน้ารวมไฟล์
shift-registers-tutorial-5-bank-interleaving-d9c19e.md

ชื่อโปรเจกต์: Shift Registers - Tutorial 5, Bank Interleaving

ถ้าหลงเข้ามาอ่านบทความนี้แบบงุ่มง่ามโดยไม่ได้เริ่มจากตอนแรก บอกเลยว่าอาจจะงงจนมึนตึ้บได้นะน้อง เพราะนี่คือหนึ่งในซีรีส์ Tutorial ทั้ง 6 ตอนที่จะช่วยให้พวกแกเข้าใจการใช้งาน Library ez_SIPO8_lib ในการจัดการและควบคุมไอซี Serial-in/Parallel-out (SIPOs) หรือที่พวกเราเรียกกันติดปากว่า shift registers อย่างพวกตระกูล 74HC595 นั่นแหละ

ถ้าอยากย้อนไปเริ่มนับหนึ่งใหม่ก็ตามไปที่ลิงก์ Tutorial Start ได้เลย แต่ถ้าพร้อมแล้วก็อ่านต่อสิวัยรุ่น...

Tutorial นี้จะช่วยเพิ่มความเซียนในการใช้ ez Serial-in/Parallel-out IC Library (ez_SIPO8_lib) ในตอนที่ 5 เรื่อง Bank Interleaving ใครจะเริ่มใหม่ก็ไปที่ Tutorial Start นะจ๊ะ
เอกสารคู่มือ User Guide, Crib Sheet หรือบทความต้นฉบับของ ez_SIPO8_lib ไปหาโหลดเอาเองนะน้อง ลิงก์อยู่ข้างล่างนี่:
- ez_SIPO8_lib User Guide
- ez_SIPO8_lib Crib Sheet
- อ่านบทความ ez_SIPO8_lib ตัวเต็ม

เกริ่นนำเข้าสู่ Tutorial

ใน Tutorial นี้เราจะมาดูเรื่อง Bank Interleaving กัน มันคือเทคนิคที่ช่วยให้เรากำหนด Bank ของ SIPO หลายๆ ชุดที่มีขนาดเท่ากันได้ โดยที่ทุกชุดใช้การเชื่อมต่อแบบ 3-wire Interface จาก Microcontroller ชุดเดียวกัน! วิธีนี้จะช่วยให้เราจัดการ Output Pins ของ SIPO ที่มีการตั้งค่าต่างกัน แล้ว xfer ข้อมูลไปยัง SIPO ของจริง ไม่ว่าจะตัวเดียวหรือต่อ Cascade กันหลายตัว ก็ทำได้ตามที่โปรเจกต์ต้องการเลย จัดว่าหล่อเท่มาก

เป้าหมาย

ใน Tutorial นี้เราจะมาจำลองโลก virtual software SIPO เพื่อเรียนรู้เรื่องพวกนี้กัน:

1. ถ้าใครยังไม่มีบอร์ดทดลองจากตอนเก่าๆ ก็จะได้รู้วิธีต่อวงจรไอซี 74HC595 (SIPO) ตัวเดียวเข้ากับ Microcontroller เพื่อลองฟีเจอร์ต่างๆ ในบทนี้

2. รู้วิธีสร้าง SIPO Banks หลายๆ ชุด โดยที่แต่ละชุดมีการตั้งค่าสถานะ Output Pin ที่ต่างกัน

3. เรียนรู้เทคนิค Bank Interleaving ให้เกิดประโยชน์สูงสุด โดยเราจะเอาตัวอย่างไฟวิ่ง (strobing LEDs) จาก User Guide มาทำใหม่ให้ดู

4. ดูผลลัพธ์การทำงานของ Code ทั้งจังหวะไฟวิ่งและค่าข้อมูลต่างๆ ในระบบ

ถ้าใครทำ Tutorial 1 กับ 2 มาแล้วและยังไม่ได้รื้อวงจรทิ้ง ก็ข้ามไปดูส่วน Code/Sketch ได้เลย แต่ถ้ามือใหม่กิ๊กๆ ก็อ่านข้างล่างต่อ

รายการของต้องเตรียม (Kit List)

ไปรื้อเก๊ะเตรียมของตามนี้เลยวัยรุ่น:

  • 1 x [Arduino](https://s.shopee.co.th/7fUgFAWSki) UNO - จริงๆ จะใช้บอร์ดอะไรก็ได้นะที่เป็น Arduino หรือ Clone ขอแค่มี Pin พอสั่งงาน SIPO และจ่ายไฟไหวก็พอ
  • 1 x Breadboard - เล็กหรือใหญ่ตามสะดวกที่มีในมือ
  • 1 x 74HC595 IC - ไอซี SIPO แบบ 8-bit หรือตัวเทียบเคียงที่ขาตรงกัน
  • 8 x LEDs - มีสีอะไรก็ขุดมาใช้ให้หมด
  • 8 x Resistors 220 ohm - ตัวละหนึ่งดวงนะน้อง ใช้ 220 ohm พอ ไม่ต้องไปบ้าจี้ตาม 180 ohm ในไดอะแกรมมากก็ได้
  • สายจัมป์ (Connecting wires) - จะสั้นจะยาวตามใจน้องเลย เอาให้ต่อถึงกันเป็นพอ

การดูขา 74HC595 (Orientation and Pin Outs)

ดูหัวดูหางให้ดีนะน้อง ตรงไหนมีบาก (notch) คือด้านบนตามรูปเลย การนับ Pin จะเริ่มที่เลข 1 ตรงบนซ้าย ไล่ลงมาข้างล่าง แล้ววนขึ้นไปจบที่ Pin 16 ตรงบนขวา อย่าจิ้มผิดล่ะเดี๋ยวไอซีไหม้!

Pin Outs 1 - 74HC595

การตั้งค่า Pin ระหว่าง Microcontroller กับ SIPO

ทุกๆ Bank ของ SIPO ที่น้องต่อเข้ากับ Microcontroller จะต้องใช้ Digital Interface แบบ 3 สาย (3WI) เนื่องจากรอบนี้เราใช้ SIPO แค่ตัวเดียว ก็เลยใช้แค่ 3WI ชุดเดียวพอ ตารางข้างล่างคือแนวทางการต่อขาสำหรับ Tutorial นี้ แต่ถ้าใครอยากโชว์พาวเปลี่ยน Pin เองก็ได้นะ แต่อย่าลืมไปแก้ใน Code ตรงฟังก์ชัน create_bank ใน setup() ด้วยล่ะ

  • UNO pin 8 ไปที่ SIPO pin 14 - SIPO Data Pin
  • UNO pin 9 ไปที่ SIPO pin 12 - SIPO Latch Pin
  • UNO pin 10 ไปที่ SIPO pin 11 - SIPO Clock Pin
  • UNO pin +5v ไปที่ SIPO pins 10, 16 - ไฟเลี้ยงไอซี
  • UNO GND pin ไปที่ SIPO pins 8, 13 - สายกราวด์ (0v)

ต่อวงจรกันเลย

ดูไดอะแกรมแล้วต่อตามให้ไว เช็คดีๆ ว่า Output/Input ไม่สลับกันนะน้อง:

Wiring Scheme 1- Single SIPO IC, 8 outputs

สังเกตนะว่าขาเดียวที่ไม่ได้ต่ออะไรเลยคือ Pin 9 (QH’) เพราะขานี้เอาไว้ต่อ Serial Output ไปเข้าขา 14 (SER) ของไอซี SIPO ตัวถัดไปเวลาเราต่อแบบพ่วงกัน (cascade)

Code/Sketch (ของจริงมาแล้ว)

เอาล่ะ มาดูโค้ดที่จะทำให้ LED วิ่งไปวิ่งมาบน SIPO ตัวเดียว โดยรอบนี้เราจะใช้เทคนิค Bank Interleaving แบบเทพๆ:

1. เราจะสร้าง Virtual SIPO Banks ขึ้นมา 8 ชุด จำไว้ว่า Banks พวกนี้เป็นโลกเสมือน (Virtual) เพราะทั้งหมดจะถูกส่งไปที่ SIPO ตัวจริงตัวเดียวกัน (Physical IC) ผ่าน 3WI ชุดเดิม

2. แต่ละ Bank (เสมือน) จะตั้งค่าให้มีแค่ Pin เดียวที่เป็น HIGH เช่น Bank ID 0 ให้ Pin 0 สว่างตัวเดียว, Bank ID 1 ให้ Pin 1 สว่างตัวเดียว ไล่ไปเรื่อยๆ จนครบ 8 ตัว รูปแบบข้อมูลจะเป็นแบบนี้:

  • bank id 0 SIPO pattern: 0b00000001
  • bank id 1 SIPO pattern: 0b00000010
  • bank id 2 SIPO pattern: 0b00000100
  • bank id 3 SIPO pattern: 0b00001000
  • bank id 4 SIPO pattern: 0b00010000
  • bank id 5 SIPO pattern: 0b00100000
  • bank id 6 SIPO pattern: 0b01000000
  • bank id 7 SIPO pattern: 0b10000000

3. เราก็แค่สั่ง xfer แต่ละ Bank เรียงลำดับกันไปเพื่อให้เกิดเอฟเฟกต์ไฟวิ่ง พอครบ 8 รอบก็สลับทิศทาง Shift Out ซะ จะได้ไฟวิ่งกลับไปกลับมาอย่างหล่อ

4. สังเกตผลลัพธ์ทั้งที่ตัว LED และข้อมูลใน Serial Monitor ดูด้วยล่ะ

ก๊อปโค้ดไปลองได้เลยวัยรุ่น:

//
// Tutorial 5 - การใช้ Library ez_SIPO8,
// สาธิตเรื่อง SIPO bank interleaving - 8 x SIPOs เสมือน
// แต่ละตัวแมปเข้ากับ Bank ของตัวเองแต่ใช้ Interface 3 สายชุดเดียวกัน
//
#include <ez_SIPO8_lib.h>
int bank_id;
#define Num_SIPOs 8
#define Num_timers 0
SIPO8 my_SIPOs(Num_SIPOs, Num_timers); // เริ่มต้นใช้งาน Class
uint8_t bank_ids[Num_SIPOs]; // เก็บ ID ของแต่ละ Bank
uint8_t bank;
void setup() {
Serial.begin(9600);
// สร้าง Bank ละ 1 SIPO ทั้งหมดใช้ Pin 8, 10, 9 เหมือนกัน
// และใส่ค่า Pattern ไฟวิ่งรอไว้เลย
for (bank = 0; bank < Num_SIPOs; bank++) {
bank_ids[bank] = my_SIPOs.create_bank(8, 10, 9, 1);
if (bank_ids[bank] == create_bank_failure) {
Serial.println(F("failed to create bank"));
Serial.flush();
exit(0);
}
// ตั้งค่า Pattern ใน SIPO (address 0 ของ bank นั้นๆ)
my_SIPOs.set_bank_SIPO(bank_ids[bank], 0, 1 << bank);
}
// ปรินท์ข้อมูลยืนยันความถูกต้องหน่อย
my_SIPOs.print_SIPO_data();
my_SIPOs.print_pin_statuses();
}
void loop() {
// วนลูปสลับ Bank (interleave) แล้วส่งข้อมูลออกไปตามทิศทางที่กำหนด
bool msb_or_lsb = MSBFIRST; // เริ่มที่ทิศทางนี้ก่อน
do {
for (bank = 0; bank < Num_SIPOs; bank++) {
my_SIPOs.xfer_bank(bank, msb_or_lsb); // ส่งข้อมูลออกไปเลยวัยรุ่น!
delay(50);
}
msb_or_lsb = !msb_or_lsb; // สลับทิศทาง Shift Out
} while (true);
}

เห็นไหมว่าโค้ดสั้นและคลีนมากน้อง งานที่ดูเหมือนซับซ้อนก็จบได้ด้วย Library ตัวนี้ แถมยังแสดงให้เห็นพลังของ MSBFIRST และ !MSBFIRST (หรือ LSBFIRST) ในการสลับทิศทางด้วย หัวใจสำคัญคือการประกาศ Virtual Banks ที่ชี้ไปที่ 3WI เดียวกันนั่นเอง

เช็ค Serial Monitor นะ ถ้าขึ้นประมาณนี้แสดงว่ามาถูกทาง:

SIPO global values:
pins_per_SIPO = 8
max_SIPOs = 8
bank_SIPO_count = 8
num_active_pins = 64
num_pin_status_bytes = 8
next_free bank = all SIPOs used
Number timers = 0
Bank data:
bank = 0 (latch=9, clock=10, data=8)
bank = 1 (latch=9, clock=10, data=8)
...จนถึง bank 7...
Pin status byte data –
Bank 0: MS00000001LS
Bank 1: MS00000010LS
Bank 2: MS00000100LS
Bank 3: MS00001000LS
Bank 4: MS00010000LS
Bank 5: MS00100000LS
Bank 6: MS01000000LS
Bank 7: MS10000000LS

ก่อนจบวันนี้:

ลองไปแก้พวก Pattern ของ SIPO ดูนะน้อง จะได้รู้ว่ามันทำเอฟเฟกต์แปลกๆ ได้อีกเยอะ

คำถามวัดกึ๋น: ถ้าเปลี่ยน my_SIPOs.xfer_bank(bank, msb_or_lsb) เป็น my_SIPOs.xfer_banks(bank, bank, msb_or_lsb) หรือ my_SIPOs.xfer_array(msb_or_lsb) ผลจะต่างกันยังไง?
คำตอบ: my_SIPOs.xfer_banks(bank, bank, msb_or_lsb) จะทำงานได้เหมือนเดิมเป๊ะ เพราะมันสั่ง Shift Out แค่ Bank เดียวตัวเดิม แต่ my_SIPOs.xfer_array(msb_or_lsb) จะพังทันที! เพราะมันจะพยายามส่งข้อมูลของทุก Virtual Banks (ทั้ง 8 อัน) ออกไปพร้อมกัน ซึ่งไม่ใช่สิ่งที่เราต้องการในโปรเจกต์นี้

จบแล้วสำหรับ Tutorial 5 หวังว่าพวกแกจะได้ความรู้ไปอัปเกรดโปรเจกต์นะ ใครอยากได้ PDF เก็บไว้ก็ไปโหลดใน GitHub ได้

ถ้าไฟยังแรงและอยากต่อตอนหน้าก็ตามไปที่: Tutorial 6, Questions & Answers แต่ถ้าใครเริ่มงงแล้วอยากไปทวนใหม่ก็กลับไปที่ Tutorial Start ซะนะน้อง!

ข้อมูลเชิงเทคนิคเพิ่มเติม (EXPANDED TECHNICAL DETAILS)

การจัดการข้อมูล SPI ขั้นสูง

Tutorial นี้เน้นไปที่การส่งข้อมูลความเร็วสูงไปยัง 74HC595 Shift Registers หลายตัว

  • Bank Interleaving: แทนที่จะต้องอัปเดต Register ทั้งหมดในสาย Serial ยาวเหยียดเพียงชุดเดียว เทคนิคนี้จะแบ่งพวกมันออกเป็น "Banks" โดยการสลับสัญญาณ Latch และ Clock ทำให้ระบบสามารถลดค่า Latency ในการอัปเดต และเพิ่ม Refresh Rate สำหรับการทำแอนิเมชัน LED ที่ซับซ้อนหรือการแสดงผลที่มีความหนาแน่นสูง
  • Circuit Architecture: ใช้สาย Clock และ Data ร่วมกันแต่แยกขา Latch (ST_CP) อิสระต่อกัน หรือใช้อัลกอริทึมซอฟต์แวร์พิเศษในการจัดการกระบวนการ Bit-banging ข้าม Data Banks หลายชุดพร้อมกัน จัดว่าโหด!

ข้อมูล Frontmatter ดั้งเดิม

title: "Shift Registers - Tutorial 5, Bank Interleaving"
description: "ez_SIPO8_lib - Tutorial 5, Bank Interleaving, to promote and assist in implementing the ez_SIPO8_lib library."
author: "ronbentley1"
category: "Lab Stuff"
tags:
  - "tutorials"
  - "sipo"
  - "74hc595"
  - "shift registers"
views: 947
likes: 0
price: 299
difficulty: "Intermediate"
components:
  - "8x Resistor 220 ohm"
  - "8x LED (generic)"
  - "1x Breadboard (generic)"
  - "1x Shift Register- Serial to Parallel"
  - "1x Arduino UNO"
  - "1x Jumper wires (generic)"
tools: []
apps:
  - "1x Arduino IDE"
downloadableFiles:
  - "https://projects.arduinocontent.cc/59dda691-a771-4d5a-9573-f04c8dc64eb6.ino"
documentationLinks: []
passwordHash: "ede545bffd4a38b69daaf70886973c2e97d61080cf576a1ed3bee91852d27188"
encryptedPayload: "U2FsdGVkX19+9P0D+dmS0TIJnter+2SQTfPyFKzRFr3yeyhqmodkrKiyubc8WwjoZfXG9crc63uGc0XyaS+/HYhPmEcB2ffC9Mnsun3PVIs="
seoDescription: "Learn Bank Interleaving for Shift Registers with ez_SIPO8_lib Tutorial 5. Simplify your project implementation with this library guide."
videoLinks: []
heroImage: "https://cdn.jsdelivr.net/gh/bigboxthailand/arduino-assets@main/images/projects/shift-registers-tutorial-5-bank-interleaving-d9c19e_cover.jpg"
lang: "th"