วันอาทิตย์ที่ 26 กุมภาพันธ์ พ.ศ. 2560

I2C

  I2C ย่อมาจาก Inter IC Communication คิดค้นโดย  Philip semiconductor  หรือ  NXP  semiconductorจุดประสงค์เพื่อรับส่งข้อมูลความเร็วต่ำระหว่างอุปกรณ์ ต่างๆ เช่นเครื่องบันทึกเสียง โทรศัพท์มือถือ  รวมถึงหน่วยความจำอย่าง EEPROM เป็นต้น การสื่อสารแบบ I2C มีจุดเด่นคือ การเชื่อมต่อกันเป็นระบบบัสและรับส่งข้อมูลระหว่างอุปกรณ์ได้เป็นจำนวนมาก โดยใช้สายสัญญาณเพียงสองเส้นดังรูป  1-1  ซึ่งสามารถลดจำนวนสายสัญญาณและขนาดของอุปกรณ์ จึงเป็นที่นิยมในระบบสมองกลฝังตัวขนาดเล็ก

รูป 1-1 การเชื่อมต่ออุปกรณ์ แบบ I2C บัส [2, p.1]

 เป็นการสื่อสารแบบอนุกรมแบบ Synchronous ด้วยสายสัญญาณเพียง 2 เส้น คือ สายสัญญาณข้อมูล SDA (Serial Data Line) และสายสัญญาณนาฬิกา SCL (Serial Clock Line) โดย I2C แบ่งการทำงานออกเป็น 4 โหมดตามความเร็วในการรับส่งข้อมูลดังนี้
        1. Normal Mode: 100Kbps
        2. Fast Mode: 400Kbps
        3. Fast Mode Plus: 1Mbps
        4. High Speed Mode: 3.4 Mbps


ตัวอย่างการต่อใช้งาน I2C
        จากภาพแสดงให้เห็นว่าในการใช้งาน I2C สามารถต่อใช้งานกับอุปกรณ์ได้มากกว่าหนึ่งตัวบนสายสัญญาณ 1 ชุด (2 เส้น) โดยเลือกติดต่อกับอุปกรณ์ใดได้ด้วยการกำหนดแอดเดรสทางฮาร์ดแวร์ให้กับ อุปกรณ์ตัวนั้นและต้องมีการ Pull-Up ให้กับสายสัญญาณทั้ง 2 เส้น
 ภาวะที่เกิดขึ้นบนบัส I2C 



มีด้วยกัน 5 สภาวะดังนี้
1. บัสว่าง เป็นสภาวะที่มาสเตอร์ทำให้ SDA และ SCL เป็น“1” ทั้งคู่ เพื่อที่จะเริ่มต้นการสื่อสาร
2. สภาวะเริ่มต้น Start เกิดขึ้นเมื่อมาสเตอร์ทำให้ SDA เปลี่ยนจาก“1” เป็น “0” ก่อน แล้วจึงเปลี่ยน SCL จาก “1” เป็น“0”
3. สภาวะบิตข้อมูล  เกิดขึ้นโดยตัวส่งทำให้ SDA เป็นบิตข้อมูล “0” หรือ “1” ก่อน แล้วมาสเตอร์ทำให้เกิดสัญญาณนาฬิกาขึ้นที่ SCL ตัวรับจึงรับข้อมูลในช่วงดังกล่าว
4. สภาวะบิตรับรู้ ้ ACK หรือ Acknowledge เกิดขึ้นโดยตัวส่งทำให้ SDA เป็น “1” ก่อนแล้วมาสเตอร์ทำให้เกิดสัญญาณนาฬิกาขึ้นที่ SCL เมื่อตัวรับรับรู้แล้วก็จะทำให้ SDA เป็น “0”
5. สภาวะหยุด  Stop เกิดขึ้นเมื่อมาสเตอร์ทำให้ SCL เปลี่ยนจาก“0” เป็น “1” ก่อน แล้วจึงเปลี่ยน SDA จาก “0” เป็น
“1”


รูปแบบสถานะในการรับ-ส่งข้อมูล

095
       Start เป็นสถานะที่บอกเริ่มต้นการรับ-ส่งข้อมูล โดยการเปลี่ยนสัญญาณของ SDA จาก High ไปเป็น Low โดยที่ SCL ยังคงเป็น High อยู่
       Control Byte ประกอบไปด้วย 3 ส่วน คือ
       - ID ของอุปกรณ์จำนวน 4 บิต ซึ่งถูกกำหนดมาโดยผู้ผลิต IC หรืออุปกรณ์ I2C
       - Device Address ขนาด 3 บิต สามารถกำหนดได้เองจากการจ่าย Logic หรือต่อขาให้กับ IC
       - Mode ขนาด 1 บิต ใช้กำหนดว่าเป็นการ Read หรือ Write Data กับอุปกรณ์ IC
       ACK หรือ Acknowledge เป็นบิตที่ใช้บอกว่า IC มีการตอบสนองต่อคำสั่งที่ได้รับมาแล้ว
       DATA คือ ข้อมูลที่ต้องการเขียนหรืออ่านออกมาจาก IC ขึ้นกับ Mode ที่เราได้ตั้งค่าเอาไว้
       STOP เป็นสถานะที่บอกให้อุปกรณ์รู้ว่าสิ้นสุดการรับส่งข้อมูลแล้ว โดย SDA จะเปลี่ยนจาก Low เป็น High ในขณะที่ SCL ยังเป็น High อยู่
096


การสื่อสารแบบ I2C มีรูปแบบดังรูป 1-2 และมีขั้นตอนการรับส่งข้อมูลเป็นลำดับ ดังนี้
  1. เพื่อเริ่มต้นสถานะการสื่อสารแบบ  I2C  อุปกรณ์  Master เริ่มจะส่งคำสั่ง  START  ซึ่งจะทำให้อุปกรณ์Slave ทุกตัวที่อยู่ใน Bus เตรียมพร้อมรับข้อมูลจากสายส่งข้อมูล (SDA)
  2. อุปกรณ์  Master  ส่ง  Address  ขนาด  7  บิตและตามด้วยคำสั่งอ่านหรือเขียน (Read/Write)  อีก  1บิต
  3. อุปกรณ์  Slave  ทุกตัวใน  Bus  จะตรวจสอบ  Address  ในสายส่งข้อมูลว่าตรงกับ  Address  ของตนหรือไม่หากตรงกัน  จะส่งสัญญาณ  ACK  ขนาด  1  บิต  กลับไปยังอุปกรณ์  Master เพื่อเตรียมพร้อมด่าเนินการต่อไป
  4. การรับส่งข้อมูลระหว่าง  Master และ Slave ที่ระบุ Address จะด่าเนินการอย่างต่อเนื่อง  ในกรณีที่Master  ส่งคำสั่ง  Read  อุปกรณ์  Slave  จะส่งข้อมูลเป็นชุดๆ ชุดละ  8  บิต (1  ไบต์)  เมื่ออุปกรณ์Master จะส่งสัญญาณ ACK เมื่อได้รับทุกๆ ไบต์
  5. อุปกรณ์  Master จะส่งคำสั่ง STOP เพื่อสิ้นสุดสถานะการสื่อสารแบบ I2C

 รูป 1-2 รูปแบบการสื่อสารแบบ I2C

การเข้าถึงแบบ 7 บิต(7-bit addressing)






      ข้อมูลไบต์แรกที่เกิดขึ้นหลังจากสภาวะเริ่มต้นคือ ข้อมูลที่ใช้อ้างอุปกรณ์ที่ต้องการติดต่อโดยมีรูปแบบแสดงในรูป
      ใน 7 บิตบนรวมทั้งบิต LSB ด้วยจะเป็นข้อมูลแอดเดรสของอุปกรณ์สเลฟที่ต้องการติดต่อ โดยแบ่งเป็น บิตกำหนดแอดเดรสคงที่(fix address bit) จำนวน 4 บิต ซึ่งข้อมูลนี้อุปกรณ์แต่ละตัวจะถูกกำหนดมาจากผู้ผลิต ไม่สามารถเปลี่ยนแปลงแก้ไขได้ ถัดมาอีก 3 บิตเป็นบิตกำหนดแอดเดรสที่สามารถโปรแกรมได้(programmable address bit) โดยผู้ใช้งานต้องกำหนดสถานะลอจิกให้แก่ขา A0-A2 ของอุปกรณ์ที่มีการเชื่อมต่อแบบบัส I2C ส่วนในบิต LSB ที่ใช้กำหนดการอ่านหรือเขียนข้อมูลกับอุปกรณ์สเลฟตัวนั้น ๆ หากบิต LSB เป็น "0" หมายถึงต้องการเขียนข้อมูลไปยังอุปกรณ์นั้น ถ้าเป็น "1" จะเป็นการอ่านข้อมูลจากอุปกรณ์สเลฟ
      ข้อมูลในไบท์ต่อมาคือ ข้อมูลควบคุม(control byte) ในอุปกรณ์แต่ละตัวจะมีการกำหนดข้อมูลควบคุมที่แตกต่างกันไป ยกตัวอย่างเช่น ไอซีเมมโมรีของทีวีตระกูล 24Cxx จะต้องส่งข้อมูลแอดเดรสของหน่วยความจำก่อนที่จะทำการส่งข้อมูลไป
      ข้อมูลในไบท์ต่อมาคือ ข้อมูลที่ทำการถ่ายทอดจริง(data)
หลังจากการถ่ายทอดข้อมูลในแต่ละไบท์ อุปกรณ์สเลฟที่ได้รับการติดต่อต้องส่งสัญญาณรับรู้ตอบกลับมาด้วยทุกครั้ง
การเข้าถึงแบบ 10 บิต(10-bit addressing)



      จะมีข้อมูลเพิ่มเติิมขึ้นมาเล็กน้อย โดยในไบท์แรกหลักจากสภาวะเริ่มต้น ต้องกำหนดให้ 5 บิตบนมีข้อมูลเป็น 11110 ส่วนอีก 2 บิตถัดมาเป็นบิตแอดเดรสของอุปกรณ์ที่ต้องการติดต่อ ในบิต LSB ของข้อมูลไบท์แรกยังคงเป็นการกำหนดว่า ต้องการอ่านหรือเขียนข้อมูลกับอุปกรณ์สเลฟตัวที่ต้องการติดต่อด้วย ข้อมูลไบท์ต่อมาเป็นข้อมูลแอดเดรสในไบท์ที่ 2 ของอุปกรณ์ที่ต้องการติดต่อด้วย ข้อมูลไบท์ถัดไปจึงเป็นข้อมูลควบคุม ข้อมูลหลังจากนี้ก็จะเป็นข้อมูลจริงที่ใช้ในการติดต่อ
เช่นเดียวกัน กับการเข้าถึงแบบ 7 บิตหลังจากถ่ายทอดข้อมูลครบทุกไบท์ ต้องมีสภาวะรับรู้เกิดขึ้น เพื่อให้ขบวนการถ่ายทอดข้อมูลสามารถดำเนินต่อไปได้

  ลำดับการทำงาน (Timing Diagram) ก็จะเริ่มต้นด้งนี้ครับ

   1. ในสภาวะที่ยังไม่เริ่มทำงาน  อุปกรณ์ทุกตัวจะมีแรงดันระดับสูง (H) 

   2. เมื่อเริ่มจะส่งข้อมูล  SDA จะลดลงไปที่ระดับแรงดันศูนย์  (L)  ในขณะที่ SCL ยังอยู่ที่ ็H  จะเห็นในช่องที่แรงเงาสีเหลืองซ้ายสุด  โดย SCL จะค้างที่ H นาน 0.6 ไมโครวินาที (tHDSTA: Hold Time to Start Condition)  ผ่านช่วงเวลานี้ไปเป็นอันรู้กันว่า Master จะเริ่มสั่งการ  (แต่ตอนนี้ยังไม่รู้นะครับว่าจะสั่ง Slave ตัวไหน เพราะอาจมีหลายตัวต่ออยู่บนบัส)

   3. ตอนนี้ SCL จะลงไปที่ L  จาก นั้น ระหว่างที่รอสัญญาณขาขึ้นของ Clock แรกอีก 1.3 ไมโครวินาที SDA จะเริ่มกำหนดค่า Bit แรก  โดย Master จะส่งค่าบิตแรกไปพร้อมกับสัญญาณ Clock  และไอซีที่เป็น Slave บนบัสจะเริ่มอ่านค่าในจังหวะที่ SCL เป็น H

   4. จากนั้นก็จะเป็นอย่างนี้ไปอีกเพื่อส่งค่า Address ของไอซีที่ต้องการจะติดต่อด้วยไปรวมทั้งสิ้น 7 บิตและตามด้วยบิตที่ 8 ซึ่งจะระบุว่าจะสั่งให้ Slave รอคำสั่ง (Write ระบุโดย SDA เป็น H) หรือจะรออ่านค่าที่ส่งมาจาก Slave (Read ระบุค่าโดย SDA เป็น L)

  5. บิตที่ 9 จะเป็นการตอบรับจาก Slave ที่มี Address ตรงกับที่ Master ส่งไป  ถ้ามี Slave ตอบรับ (Acknoledge) โดยการดึงสัญญาณ SDA ลง L  ก็แปลได้ว่ามี Slave พร้อมจะสื่อสารด้วย  แต่ถ้าไม่มี คือ SDA ค้างที่ H แปลว่า (Not Acknowledge)  Master ไม่มีใครคุยด้วย 

 6. หลังจาก Acknowledge กันเรียบร้อย (สมมุติว่ามีสัญญาณตอบรับ) จะเป็นช่วงเวลาที่ SCL ถูกดึงลง L เป็นเวลาสั้นๆ และ SDA จะถูกปล่อยว่าง  ก่อนที่ Slave ที่ติดต่อด้วยจะเริ่มส่งค่า Bit แรกมาที่ SDA

 7. จากนั้นสัญญาณ SCL จาก Master จะปล่อยออกมาเพื่ออ่านค่าสัญญาณบนสาย SDA ในจังหวะที่ SCL เป็น H และรับค่าเช่นนี้ไปเรื่อยๆ จน Data ครบ 8 บิตแรก ตามจังหวะสัญญาณ SCL

 8. เมื่อ Data ครบ 8 บิตแรกแล้ว Master จะให้สัญญาณ Acknowledge โดยดึงสัญญาณเป็น L เพื่อแสดงให้ Slave รู้ว่า Master จะรอ Data อีก 8 บิตต่อไป  (ในกรณีที่ข้อมูลที่ Slave ต้องการส่งเป็นแบบ 16 บิต)

 9. จะกลับเข้าการทำงานในข้อ 6 และอ่านข้อมูลไปจนครบบิตที่ 9 - 16

10. จากนั้นเมื่อถึงจังหวะการ Acknowledge ในบิตที่ 9  คราวนี้ Slave ไม่ต้องการส่งข้อมูลต่อแล้ว เพราะครบ 16 บิตแล้ว  Slave จะ ไม่ตอบสนองแล้ว สาย SDA จะถูกปล่อยให้เป็น H 

11. จากนั้น Master จะรู้แล้วว่าข้อมูลมาครบถ้วน 16 บิต Master ก็จะสั่งหยุดโดยการส่งสัญญาณ ขาขึ้นในสาย SDA พร้อมๆกับ SCL เป็น H  ก็เป็นอันรู้กันว่าคือ Stop bit หมายถึงส่งข้อมูลครบ Byte แรก ซึ่งเป็น Address ของ Slave ตัวที่ Master ต้องการคุยด้วย  


 มันก็เข้าใจยากอยู่ครับ ลองอ่านดูช้าๆ และดูรูป timing diagram ด้านบนประกอบนะครับ
 ทีนี้ถ้าต้องการอ่านคู่มือจริง ต้นตำหรับจาก NXP Semiconductor ก็ไปที่นี่เลยครับ
สังเกตอีกนิดจะเห็นว่า สัญญาณ Start และ Stop จะส่งโดย Master เท่านั้น  โดย Start คือ ให้ SDA เปลี่ยนจาก H เป็น L ในจังหวะที่ SCL เป็น H  ส่วนการ Stop ก็คิอให้ SDA เปลี่ยนจาก L เป็น H ในจังหวะที่ SCL เป็น H    และที่ว่ามาทั้งหมด Master จะเป็นตัวปล่อยสัญญาณ SCL ครับ
 อ่านแล้วคงจะรู้สึกยาก  ก็ไม่ต้องกังวลครับ เพราะเราไม่ต้องเขียนโปรแกรมที่คุมสัญญาณแต่ละเส้นเอง  Arduino เขาทำ Library ที่ชื่อว่า Wire มาให้แล้ว  สบายครับ เราแค่เลือก Address ของอุปกรณ์ให้ถูก แล้วปล่อยให้ Wire.h จัดการส่ง รับค่าให้เราครับ   
  Library ที่ชื่อ wire.h ก็ไม่ต้องไปหา download ให้ยุ่งครับ มันมีอยู่แล้วใน Arduino IDE  เรียกใช้กันได้เลย เพียงแค่ Add ชื่อไว้ตอนเริ่มต้น Sketch ที่จะใช้ก็เท่านั้น  รายละเอียดวิธีใช้งาน Library wire.h ก็ดดูได้ที่นี่ครับ
  Functions ต่างๆ ของ wire.h ก็ดูตามนี้เลยครับ
ทีนี้ I2C หรือ TWI บนบอร์ด Arduino นั้น ก็ต้องเรียกให้ถูกขาที่เขากำหนดนะครับ (ไม่สามารถ Assign เป็นขาอื่นๆ)  ลองดูรายละเอียดตามนีครับ
Board I2C / TWI pins
Uno,Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1SCL1

1 ความคิดเห็น: