- SPI Communication Protocol คืออะไร?
- SPI Protocol ทำงานอย่างไร
- ความแตกต่างระหว่าง I2C และ SPI Communication
- SPI กับ PIC16F877A โดยใช้ XC8 Compiler:
- คำอธิบายไฟล์ส่วนหัว SPI:
- คำอธิบายโปรแกรมหลัก:
- การจำลอง PIC ด้วยดีบักเกอร์ SPI:
PIC Microcontrollers เป็นแพลตฟอร์มที่มีประสิทธิภาพที่ไมโครชิพสำหรับโครงการฝังตัว ลักษณะที่ใช้งานได้หลากหลายทำให้สามารถค้นหาวิธีการใช้งานได้หลากหลายและยังไม่เติบโตอีกมาก หากคุณติดตามบทช่วยสอน PIC ของเราแล้วคุณจะสังเกตเห็นว่าเราได้กล่าวถึงบทช่วยสอนมากมายเกี่ยวกับไมโครคอนโทรลเลอร์ PIC โดยเริ่มตั้งแต่พื้นฐาน ในขั้นตอนเดียวกันเรากำลังดำเนินการต่อเพื่อเรียนรู้โปรโตคอลการสื่อสารที่มีให้กับ PICและวิธีการใช้งาน เราได้ครอบคลุม I2C ด้วยไมโครคอนโทรลเลอร์ PIC แล้ว
ในระบบแอพพลิเคชั่นฝังตัวมากมายไม่มีไมโครคอนโทรลเลอร์ที่สามารถทำกิจกรรมทั้งหมดได้ด้วยตัวเอง ในขั้นตอนของเวลาที่มันมีการสื่อสารกับอุปกรณ์อื่น ๆ ที่จะแบ่งปันข้อมูลบางส่วนมีหลาย ประเภทแตกต่างกันของโปรโตคอลการสื่อสาร ที่จะแบ่งปันข้อมูลเหล่านี้ แต่คนที่ใช้มากที่สุดคือ USART, IIC, SPI และ CAN โปรโตคอลการสื่อสารแต่ละแบบมีข้อดีและข้อเสียของตัวเอง มาเน้นที่ SPI Protocol ตั้งแต่ตอนนี้นั่นคือสิ่งที่เราจะเรียนรู้ในบทช่วยสอนนี้
SPI Communication Protocol คืออะไร?
คำว่าSPIย่อมาจาก " Serial Peripheral Interface " เป็นโปรโตคอลการสื่อสารทั่วไปที่ใช้ในการส่งข้อมูลระหว่างไมโครคอนโทรลเลอร์สองตัวหรือเพื่ออ่าน / เขียนข้อมูลจากเซ็นเซอร์ไปยังไมโครคอนโทรลเลอร์ นอกจากนี้ยังใช้เพื่อสื่อสารกับการ์ด SD, shift register, Display controllers และอื่น ๆ อีกมากมาย
SPI Protocol ทำงานอย่างไร
การสื่อสาร SPI เป็นการสื่อสารแบบซิงโครนัสซึ่งหมายความว่าสามารถทำงานได้ด้วยความช่วยเหลือของสัญญาณนาฬิกาซึ่งใช้ร่วมกันระหว่างอุปกรณ์ทั้งสองที่กำลังแลกเปลี่ยนข้อมูล นอกจากนี้ยังเป็นการสื่อสารแบบฟูลดูเพล็กซ์เนื่องจากสามารถส่งและรับข้อมูลโดยใช้บัสแยกต่างหาก สื่อสาร SPI ต้อง 5 สายที่จะดำเนินการ วงจรการสื่อสาร SPI อย่างง่ายระหว่างต้นแบบและทาสแสดงไว้ด้านล่าง
สายไฟห้าสายที่จำเป็นสำหรับการสื่อสาร ได้แก่ SCK (Serial Clock), MOSI (Master Out Slave In), MISO (Master In Slave Out) และ SS (Slave Select) การสื่อสาร SPI จะเกิดขึ้นระหว่าง Master และ Slave เท่านั้น ต้นแบบสามารถมีทาสหลายคนเชื่อมต่อกับมัน มาสเตอร์มีหน้าที่สร้างพัลส์นาฬิกาและใช้ร่วมกันกับทาสทั้งหมด นอกจากนี้การสื่อสารทั้งหมดสามารถเริ่มต้นได้โดยผู้เชี่ยวชาญเท่านั้น
พิน SCK (หรือที่เรียกว่านาฬิกาอนุกรม SCL) จะแบ่งปันสัญญาณนาฬิกาที่สร้างโดยต้นแบบกับทาส หมุด MOSI (หรือที่เรียกว่า SDA –Serial Data Out) ใช้เพื่อส่งข้อมูลจากต้นแบบไปยังหน่วยกู้ภัย MISO pin (aka SDI - Serial Data In) ใช้เพื่อรับข้อมูลจาก salve ไปยัง master คุณยังสามารถทำตามเครื่องหมายลูกศรในรูปด้านบนเพื่อทำความเข้าใจการเคลื่อนไหวของข้อมูล / สัญญาณ ในที่สุด SS pin (aka CS –Chip select) จะถูกใช้เมื่อมีโมดูล Slave มากกว่าหนึ่งโมดูลที่เชื่อมต่อกับมาสเตอร์ สิ่งนี้สามารถใช้เพื่อเลือกทาสที่ต้องการ วงจรตัวอย่างที่มากกว่าหนึ่งทาสเชื่อมต่อกับต้นแบบสำหรับการสื่อสาร SPI จะแสดงในวงจรด้านล่าง
ความแตกต่างระหว่าง I2C และ SPI Communication
เราได้เรียนรู้การสื่อสาร I2C กับ PIC แล้วดังนั้นเราจึงต้องคุ้นเคยกับวิธีการทำงานของ I2C และสถานที่ที่เราสามารถใช้เช่น I2C เพื่อเชื่อมต่อโมดูล RTC แต่ตอนนี้ทำไมเราต้องใช้โปรโตคอล SPI ในเมื่อเรามี I2C อยู่แล้ว เหตุผลก็คือทั้งการสื่อสาร I2C และ SPI เป็นข้อดีในแบบของมันเองและด้วยเหตุนี้จึงเป็นแอปพลิเคชันเฉพาะ
ในระดับหนึ่งการสื่อสาร I2C ถือได้ว่ามีข้อได้เปรียบเหนือการสื่อสาร SPI เนื่องจาก I2C ใช้พินจำนวนน้อยและมีประโยชน์มากเมื่อมีทาสจำนวนมากที่เชื่อมต่อกับบัส แต่ข้อเสียเปรียบของ I2C คือมีบัสเดียวกันในการส่งและรับข้อมูลดังนั้นจึงค่อนข้างช้า ดังนั้นจึงขึ้นอยู่กับแอปพลิเคชันในการตัดสินใจระหว่างโปรโตคอล SPI และ I2C สำหรับโครงการของคุณ
SPI กับ PIC16F877A โดยใช้ XC8 Compiler:
มีพื้นฐานเพียงพอแล้วตอนนี้ให้เราเรียนรู้ว่าเราสามารถใช้การสื่อสาร SPI บนไมโครคอนโทรลเลอร์PIC16F877Aโดยใช้คอมไพเลอร์ MPLABX IDE และ XC8 ได้อย่างไร ก่อนที่เราจะเริ่มทำให้ชัดเจนว่าบทช่วยสอนนี้พูดถึง SPI ใน PIC16F877a โดยใช้คอมไพเลอร์ XC8เท่านั้นกระบวนการนี้จะเหมือนกันสำหรับไมโครคอนโทรลเลอร์อื่น ๆ แต่อาจต้องมีการเปลี่ยนแปลงเล็กน้อย โปรดจำไว้ว่าสำหรับไมโครคอนโทรลเลอร์ขั้นสูงเช่นซีรีส์ PIC18F คอมไพเลอร์เองอาจมีไลบรารีบางตัวในตัวเพื่อใช้คุณสมบัติ SPI แต่สำหรับ PIC16F877A นั้นไม่มีอะไรเหมือนกันดังนั้นเรามาสร้างด้วยตัวเองกันเถอะ ไลบรารีที่อธิบายไว้ที่นี่จะได้รับเป็นไฟล์ส่วนหัวสำหรับการดาวน์โหลดที่ด้านล่างซึ่งสามารถใช้สำหรับ PIC16F877A เพื่อสื่อสารกับอุปกรณ์ SPI อื่น ๆ
ในการกวดวิชานี้เราจะเขียนโปรแกรมขนาดเล็กที่ใช้สื่อสาร SPI ในการเขียนและอ่านข้อมูลจากรถบัส จากนั้นเราจะตรวจสอบสิ่งเดียวกันโดยใช้การจำลอง Proteus รหัสทั้งหมดที่เกี่ยวข้องกับการลงทะเบียน SPI จะถูกสร้างขึ้นภายในไฟล์ส่วนหัวที่เรียกว่า PIC16f877a_SPI.h ด้วยวิธีนี้เราสามารถใช้ไฟล์ส่วนหัวนี้ในโครงการที่กำลังจะเกิดขึ้นทั้งหมดที่จำเป็นต้องมีการสื่อสาร SPI และภายในโปรแกรมหลักเราจะใช้ฟังก์ชันจากไฟล์ส่วนหัว คุณสามารถดาวน์โหลดโค้ดที่สมบูรณ์พร้อมกับไฟล์ส่วนหัวได้จากที่นี่
คำอธิบายไฟล์ส่วนหัว SPI:
ภายในไฟล์ส่วนหัวเราต้องเริ่มต้นการสื่อสาร SPI สำหรับ PIC16F877a เช่นเคยจุดเริ่มต้นที่ดีที่สุดคือแผ่นข้อมูล PIC16F877A รีจิสเตอร์ที่ควบคุมการสื่อสาร SPI สำหรับ PIC16F8777a คือSSPSTAT และ SSPCON Register คุณสามารถเกี่ยวกับพวกเขาได้ในหน้า 74 และ 75 ของแผ่นข้อมูล
มีตัวเลือกพารามิเตอร์มากมายที่ต้องเลือกขณะเริ่มต้นการสื่อสาร SPI ตัวเลือกที่ใช้บ่อยที่สุดคือความถี่สัญญาณนาฬิกาจะถูกตั้งค่าเป็น Fosc / 4 และจะทำตรงกลางและนาฬิกาจะถูกตั้งค่าให้ต่ำในสภาวะที่เหมาะสม ดังนั้นเราจึงใช้การกำหนดค่าเดียวกันสำหรับไฟล์ส่วนหัวของเราคุณสามารถเปลี่ยนได้อย่างง่ายดายโดยเปลี่ยนบิตตามลำดับ
SPI_Initialize_Master ()
ฟังก์ชัน SPI initialize Master ใช้เพื่อเริ่มการสื่อสาร SPI ในฐานะมาสเตอร์ ภายในฟังก์ชั่นนี้เราตั้งค่าพินตามลำดับ RC5 และ RC3 เป็นพินเอาต์พุต จากนั้นเรากำหนดค่า SSPTAT และ SSPCON register เพื่อเปิดการสื่อสาร SPI
โมฆะ SPI_Initialize_Master () { TRISC5 = 0; // SSPSTAT = 0b00000000; // หน้า 74/234 SSPCON = 0b00100000; // หน้า 75/234 TRISC3 = 0; // ตั้งเป็นเอาท์พุทสำหรับโหมดทาส }
SPI_Initialize_Slave ()
ฟังก์ชันนี้ใช้เพื่อตั้งค่าไมโครคอนโทรลเลอร์ให้ทำงานในโหมดทาสสำหรับการสื่อสาร SPI ในระหว่างโหมด Slave ควรตั้งค่าพิน RC5 เป็นเอาต์พุตและควรตั้งค่าพิน RC3 เป็นอินพุต SSPSTAT และ SSPCON ถูกตั้งค่าในลักษณะเดียวกันสำหรับทั้งทาสและมาสเตอร์
โมฆะ SPI_Initialize_Slave () { TRISC5 = 0; // ควรประกาศ PIN SDO เป็นเอาต์พุต SSPSTAT = 0b00000000; // หน้า 74/234 SSPCON = 0b00100000; // หน้า 75/234 TRISC3 = 1; // ตั้งค่าเป็นโหมดออกจากโหมดหลัก }
SPI_Write (ถ่านขาเข้า)
ฟังก์ชัน SPI Write ใช้เพื่อเขียนข้อมูลลงในบัส SPI รับข้อมูลจากผู้ใช้ผ่านตัวแปรขาเข้าจากนั้นใช้เพื่อส่งต่อไปยังทะเบียนบัฟเฟอร์ SSPBUF จะถูกล้างในพัลส์นาฬิกาติดต่อกันและข้อมูลจะถูกส่งไปยังบัสทีละบิต
โมฆะ SPI_Write (ถ่านขาเข้า) { SSPBUF = ขาเข้า; // เขียนข้อมูลที่ผู้ใช้กำหนดลงในบัฟเฟอร์ }
SPI_Ready2Read ()
ฟังก์ชัน SPI ready to Read ใช้เพื่อตรวจสอบว่าได้รับข้อมูลในบัส SPI ครบถ้วนหรือไม่และสามารถอ่านได้หรือไม่ การลงทะเบียน SSPSTAT มีชื่อบิตที่เรียกว่า BF ซึ่งจะตั้งค่าเมื่อได้รับข้อมูลครบถ้วนดังนั้นเราจึงตรวจสอบว่าบิตนี้ถูกตั้งค่าไว้หรือไม่หากยังไม่ได้ตั้งค่าเราต้องรอจนกว่าจะได้รับการตั้งค่าให้อ่านอะไรจากบัส SPI
SPI_Ready2Read ที่ไม่ได้ลงชื่อ () { if (SSPSTAT & 0b00000001) ส่งคืน 1; อื่น กลับ 0; }
SPI_Read ()
SPI Read ใช้เพื่ออ่านข้อมูลจากบัส SPI ไปยังไมโครคอนโทรลเลอร์ ข้อมูลที่มีอยู่ในบัส SPI จะถูกเก็บไว้ใน SSPBUF เราต้องรอจนกว่าข้อมูลทั้งหมดจะถูกเก็บไว้ในบัฟเฟอร์จากนั้นเราจึงสามารถอ่านเป็นตัวแปรได้ เราตรวจสอบบิต BF ของการลงทะเบียน SSPSTAT ก่อนที่จะอ่านบัฟเฟอร์เพื่อให้แน่ใจว่าการรับข้อมูลเสร็จสมบูรณ์
ถ่าน SPI_Read () // อ่านข้อมูลที่ได้รับ { while (! SSPSTATbits.BF); // กดค้างไว้จนกว่าจะตั้งค่าบิต BF เพื่อให้แน่ใจว่าข้อมูลที่สมบูรณ์ถูกอ่าน กลับมา (SSPBUF); // ส่งคืนข้อมูลการอ่าน }
คำอธิบายโปรแกรมหลัก:
ฟังก์ชันที่อธิบายในส่วนด้านบนจะอยู่ในไฟล์ส่วนหัวและสามารถเรียกเข้าไปในไฟล์ c หลักได้ ลองเขียนโปรแกรมเล็ก ๆ เพื่อตรวจสอบว่าการสื่อสาร SPI ทำงานหรือไม่ เราจะเขียนข้อมูลบางส่วนลงในบัส SPI และใช้การจำลองโปรตีอุสเพื่อตรวจสอบว่าได้รับข้อมูลเดียวกันในดีบักเกอร์ SPI หรือไม่
เช่นเคยเริ่มต้นโปรแกรมด้วยการตั้งค่าบิตการกำหนดค่าจากนั้นจึงเป็นเรื่องสำคัญมากที่จะต้องเพิ่มไฟล์ส่วนหัวที่เราเพิ่งอธิบายลงในโปรแกรมดังที่แสดงด้านล่าง
# รวม
หากคุณเปิดโปรแกรมจากไฟล์ zip ที่ดาวน์โหลดไว้ด้านบนโดยค่าเริ่มต้นไฟล์ส่วนหัวจะอยู่ในไดเร็กทอรีไฟล์ส่วนหัวของไฟล์โปรเจ็กต์ของคุณ มิฉะนั้นคุณต้องเพิ่มไฟล์ส่วนหัวด้วยตนเองภายในโครงการของคุณเมื่อเพิ่มไฟล์โครงการแล้วจะมีลักษณะดังนี้ด้านล่าง
ภายในไฟล์หลักเราต้องเริ่มต้น PIC ในฐานะ Master สำหรับการสื่อสาร SPIจากนั้นภายในลูปที่ไม่มีที่สิ้นสุดเราจะเขียนค่าฐานสิบหกแบบสุ่มลงในบัส SPIเพื่อตรวจสอบว่าเราได้รับสิ่งเดียวกันในระหว่างการจำลองหรือไม่
เป็นโมฆะ main () { SPI_Initialize_Master (); ในขณะที่ (1) { SPI_Write (0X0A); __delay_ms (100); SPI_Write (0X0F); __delay_ms (100); SPI_Write (0X15); __delay_ms (100); } }
สังเกตว่าค่าสุ่มที่ใช้ในโปรแกรมคือ 0A, 0F และ 15 และเป็นค่าฐานสิบหกดังนั้นเราจึงควรเห็นค่าเดียวกันในระหว่างการจำลอง นั่นคือรหัสเสร็จสิ้นทั้งหมดนี้เป็นเพียงตัวอย่าง แต่เราสามารถใช้วิธีการเดียวกันในการสื่อสารกับ MCU อื่นหรือกับโมดูลเซ็นเซอร์อื่นที่ทำงานบนโปรโตคอล SPI
การจำลอง PIC ด้วยดีบักเกอร์ SPI:
เมื่อโปรแกรมของเราพร้อมแล้วเราสามารถรวบรวมและดำเนินการจำลองต่อได้ Proteus มีคุณสมบัติที่มีประโยชน์ที่เรียกว่า ดีบักเกอร์ SPI ซึ่งสามารถใช้เพื่อตรวจสอบข้อมูลผ่านบัส SPI ดังนั้นเราจึงใช้สิ่งเดียวกันและสร้างวงจรดังที่แสดงด้านล่าง
เนื่องจากมีอุปกรณ์ SPI เพียงเครื่องเดียวในการจำลองเราจึงไม่ได้ใช้พิน SS และเมื่อไม่ใช้ควรต่อสายดินดังที่แสดงด้านบน เพียงแค่โหลดไฟล์ hex ลงในไมโครคอนโทรลเลอร์ PIC16F877A และคลิกที่ปุ่มเล่นเพื่อจำลองโปรแกรมของเรา เมื่อการจำลองเริ่มต้นขึ้นคุณจะได้หน้าต่างป็อปอัพซึ่งแสดงข้อมูลในบัส SPI ดังที่แสดงด้านล่าง
ลองมาดูข้อมูลที่เข้ามาอย่างละเอียดและตรวจสอบว่าเป็นข้อมูลเดียวกันกับที่เราเขียนในโปรแกรมหรือไม่
ข้อมูลจะได้รับตามลำดับเดียวกันกับที่เราเขียนไว้ในโปรแกรมของเราและข้อมูลเดียวกันนี้จะถูกไฮไลต์สำหรับคุณ คุณยังสามารถลองจำลองโปรแกรมเพื่อสื่อสารกับไมโครคอนโทรลเลอร์ PIC สองตัวโดยใช้โปรโตคอลSPI คุณต้องตั้งโปรแกรม PIC หนึ่งรายการเป็นหลักและอีกรายการเป็นทาส ไฟล์ส่วนหัวที่จำเป็นทั้งหมดสำหรับวัตถุประสงค์นี้จะได้รับในไฟล์ส่วนหัวแล้ว
นี่เป็นเพียงภาพรวมของสิ่งที่ SPI ทำได้นอกจากนี้ยังสามารถอ่านและเขียนข้อมูลไปยังอุปกรณ์ต่างๆ เราจะกล่าวถึงเพิ่มเติมเกี่ยวกับ SPI ในบทช่วยสอนที่กำลังจะมาถึงโดยการเชื่อมต่อโมดูลต่างๆที่ทำงานกับโปรโตคอล SPI
หวังว่าคุณจะเข้าใจโครงการและเรียนรู้สิ่งที่เป็นประโยชน์จากโครงการนี้ หากคุณมีข้อสงสัยให้โพสต์ไว้ในส่วนความคิดเห็นด้านล่างหรือใช้ฟอรัมเพื่อขอความช่วยเหลือด้านเทคนิค
รหัสหลักที่สมบูรณ์ได้รับด้านล่าง คุณสามารถดาวน์โหลดไฟล์ส่วนหัวพร้อมรหัสทั้งหมดได้จากที่นี่