- I2C Communication Protocol คืออะไร?
- I2C Communication ทำงานอย่างไร?
- จะใช้การสื่อสาร I2C ได้ที่ไหน?
- I2C กับ PIC16F877a โดยใช้ XC8 Compiler
- การเขียนโปรแกรมโดยใช้ไฟล์ส่วนหัว I2C:
- การจำลอง Proteus:
PIC Microcontrollers เป็นแพลตฟอร์มที่มีประสิทธิภาพที่ไมโครชิพจัดเตรียมไว้สำหรับโครงการฝังตัวลักษณะที่หลากหลายทำให้สามารถค้นหาวิธีการใช้งานได้หลายอย่าง หากคุณติดตามบทช่วยสอน PIC ของเราแล้วคุณจะสังเกตเห็นว่าเราได้กล่าวถึงบทช่วยสอนมากมายเกี่ยวกับไมโครคอนโทรลเลอร์ PIC โดยเริ่มตั้งแต่พื้นฐาน ตั้งแต่นี้เป็นต้นมาเราได้กล่าวถึงพื้นฐานที่เราสามารถเข้าไปในสิ่งที่น่าสนใจมากขึ้นเช่นพอร์ทัลการสื่อสาร
ในระบบแอพพลิเคชั่นฝังตัวมากมายไม่มีไมโครคอนโทรลเลอร์ที่สามารถทำกิจกรรมทั้งหมดได้ด้วยตัวเอง ในขั้นตอนของเวลาที่มันมีการสื่อสารกับอุปกรณ์อื่น ๆ ที่จะแบ่งปันข้อมูลบางส่วนมีหลายประเภทแตกต่างกันของโปรโตคอลการสื่อสารที่จะแบ่งปันข้อมูลเหล่านี้ แต่คนที่ใช้มากที่สุดคือUSART, IIC, SPI และ CAN โปรโตคอลการสื่อสารแต่ละแบบมีข้อดีและข้อเสียของตัวเอง มาเน้นที่ส่วน IIC กันก่อนเพราะนั่นคือสิ่งที่เราจะเรียนรู้ในบทช่วยสอนนี้
I2C Communication Protocol คืออะไร?
ระยะ IIC ย่อมาจาก“ วงจรอินเตอร์แบบบูรณาการ ” โดยปกติจะแสดงเป็น I2C หรือ I กำลังสอง C หรือแม้กระทั่งเป็นโปรโตคอลอินเทอร์เฟซ 2 สาย (TWI) ในบางแห่ง แต่ก็มีความหมายเหมือนกัน I2C เป็นโปรโตคอลการสื่อสารแบบซิงโครนัสซึ่งหมายความว่าอุปกรณ์ทั้งสองที่ใช้ข้อมูลร่วมกันจะต้องใช้สัญญาณนาฬิการ่วมกัน มีสายไฟเพียงสองสายในการแบ่งปันข้อมูลซึ่งสายหนึ่งใช้สำหรับสัญญาณไก่และอีกสายหนึ่งใช้สำหรับการส่งและรับข้อมูล
I2C Communication ทำงานอย่างไร?
การสื่อสาร I2C เป็นครั้งแรกโดย Phillips ดังที่ได้กล่าวไว้ก่อนหน้านี้ว่ามีสายไฟสองเส้นสายไฟทั้งสองนี้จะเชื่อมต่อกับอุปกรณ์สองเครื่อง นี่คืออุปกรณ์หนึ่งที่เรียกว่าต้นแบบและอุปกรณ์อื่น ๆ จะเรียกว่าเป็นทาสการสื่อสารควรจะเกิดขึ้นระหว่างสองนายและทาสเสมอ ข้อดีของการสื่อสารแบบ I2C คือสามารถเชื่อมต่อกับ Master ได้มากกว่าหนึ่ง Slave
การสื่อสารที่สมบูรณ์เกิดขึ้นผ่านสายไฟทั้งสองนี้คือ Serial Clock (SCL) และ Serial Data (SDA)
Serial Clock (SCL):แชร์สัญญาณนาฬิกาที่สร้างโดยต้นแบบกับทาส
Serial Data (SDA):ส่งข้อมูลไปและกลับระหว่าง Master และ Slave
ในช่วงเวลาที่กำหนดมีเพียงผู้เชี่ยวชาญเท่านั้นที่จะสามารถเริ่มการสื่อสารได้ เนื่องจากมีทาสมากกว่าหนึ่งคนในรถบัสนายจึงต้องอ้างถึงทาสแต่ละคนโดยใช้ที่อยู่ที่แตกต่างกัน เมื่อระบุเฉพาะคำตอบที่มีที่อยู่นั้นจะตอบกลับพร้อมข้อมูลในขณะที่คนอื่น ๆ ยังคงปิด วิธีนี้เราสามารถใช้บัสเดียวกันเพื่อสื่อสารกับอุปกรณ์หลายเครื่อง
จะใช้การสื่อสาร I2C ได้ที่ไหน?
การสื่อสาร I2C ใช้สำหรับการสื่อสารระยะสั้นเท่านั้น แน่นอนว่าเชื่อถือได้ในระดับหนึ่งเนื่องจากมีพัลส์นาฬิกาที่ซิงโครไนซ์เพื่อให้สมาร์ท โปรโตคอลนี้ส่วนใหญ่ใช้ในการสื่อสารกับเซ็นเซอร์หรืออุปกรณ์อื่น ๆ ที่ต้องส่งข้อมูลไปยังผู้เชี่ยวชาญ มีประโยชน์มากเมื่อไมโครคอนโทรลเลอร์ต้องสื่อสารกับโมดูลทาสอื่น ๆ จำนวนมากโดยใช้สายไฟขั้นต่ำเท่านั้น หากคุณกำลังมองหาการสื่อสารระยะไกลคุณควรลองใช้ RS232 และหากคุณกำลังมองหาการสื่อสารที่เชื่อถือได้มากขึ้นคุณควรลองใช้โปรโตคอล SPI
I2C กับ PIC16F877a โดยใช้ XC8 Compiler
มีคำแนะนำเพียงพอให้เข้าสู่มันและเรียนรู้วิธีที่เราสามารถใช้ไมโครคอนโทรลเลอร์สำหรับการสื่อสาร I2C ก่อนที่เราจะเริ่มทำให้ชัดเจนว่าบทช่วยสอนนี้พูดถึงI2C ใน PIC16F877a โดยใช้คอมไพเลอร์ XC8เท่านั้นกระบวนการนี้จะเหมือนกันสำหรับไมโครคอนโทรลเลอร์อื่น ๆ แต่อาจต้องมีการเปลี่ยนแปลงเล็กน้อย โปรดจำไว้ว่าสำหรับไมโครคอนโทรลเลอร์ขั้นสูงเช่นซีรีส์ PIC18F คอมไพเลอร์เองอาจมีไลบรารีบางตัวในตัวเพื่อใช้คุณสมบัติ I2C แต่สำหรับ PIC16F877A ไม่มีอะไรเหมือนเช่นนั้นมาสร้างขึ้นมาด้วยตัวเอง ไลบรารีที่อธิบายไว้ที่นี่จะได้รับเป็นไฟล์ส่วนหัวสำหรับดาวน์โหลดที่ด้านล่างซึ่งสามารถใช้สำหรับ PIC16F877A เพื่อสื่อสารกับอุปกรณ์ I2C อื่น ๆ
เช่นเคยจุดเริ่มต้นที่ดีที่สุดคือเอกสารข้อมูลของเรา ค้นหารายละเอียดเกี่ยวกับ I2C ในแผ่นข้อมูลและตรวจสอบว่าต้องกำหนดค่าการลงทะเบียนใด ฉันจะไม่อธิบายรายละเอียดเนื่องจากเอกสารข้อมูลได้ดำเนินการให้คุณแล้ว ด้านล่างฉันจะอธิบายฟังก์ชั่นต่าง ๆ ที่มีอยู่ในไฟล์ส่วนหัวและความรับผิดชอบในโปรแกรม
เป็นโมฆะ I2C_Initialize ()
ฟังก์ชัน initialize ใช้เพื่อบอกไมโครคอนโทรลเลอร์ว่าเรากำลังจะใช้โปรโตคอล I2C สามารถทำได้โดยการตั้งค่าบิตที่ต้องการบนทะเบียน SSPCON และ SSPCON2 ขั้นตอนแรกคือการประกาศพิน IIC เป็นพินอินพุตที่นี่ควรใช้พิน RC3 และ RC4 สำหรับการสื่อสาร I2C ดังนั้นเราจึงประกาศเป็นพินอินพุต ต่อไปเราควรตั้งค่า SSPCON และ SSPCON2 ซึ่งเป็นทะเบียนควบคุม MSSP เรามีการดำเนินงานในโหมด PIC ต้นแบบ IIC ด้วยความถี่สัญญาณนาฬิกาของ FOSC / (4 * (SSPADD + 1)) อ้างอิงหมายเลขหน้าของแผ่นข้อมูลที่กล่าวถึงในบรรทัดความคิดเห็นด้านล่างเพื่อทำความเข้าใจว่าเหตุใดจึงมีการตั้งค่าทะเบียนนั้น
ต่อไปเราต้องตั้งค่าความถี่สัญญาณนาฬิกาความถี่สัญญาณนาฬิกาสำหรับแอปพลิเคชันต่างๆอาจแตกต่างกันไปดังนั้นเราจึงได้รับตัวเลือกจากผู้ใช้ผ่านตัวแปร feq_k และใช้ในสูตรของเราเพื่อตั้งค่าการลงทะเบียน SSPADD
เป็นโมฆะ I2C_Initialize (const ไม่ได้ลงนาม long feq_K) // เริ่ม IIC เป็น master { TRISC3 = 1; TRISC4 = 1; // ตั้งค่าพิน SDA และ SCL เป็นพินอินพุต SSPCON = 0b00101000; // pg84 / 234 SSPCON2 = 0b00000000; // pg85 / 234 SSPADD = (_XTAL_FREQ / (4 * feq_K * 100)) - 1; // การตั้งค่าความเร็วนาฬิกา pg99 / 234 SSPSTAT = 0b00000000; // pg83 / 234 }
โมฆะ I2C_Hold ()
ฟังก์ชั่นที่สำคัญต่อไปคือ I2C_hold ฟังก์ชั่นที่ใช้จะถือการดำเนินการของอุปกรณ์จนกว่าการดำเนินการ I2C ปัจจุบันเป็นที่เรียบร้อยแล้ว เราจะต้องตรวจสอบว่าต้องมีการดำเนินการ I2C ก่อนที่จะเริ่มดำเนินการใหม่หรือไม่ สามารถทำได้โดยตรวจสอบรีจิสเตอร์ SSPSTAT และ SSPCON2 SSPSTAT มีข้อมูลเกี่ยวกับสถานะของบัส I2C
โปรแกรมอาจดูซับซ้อนเล็กน้อยเนื่องจากเกี่ยวข้องกับตัวดำเนินการ“ และ” และ“ หรือ” เมื่อคุณทำลายมันเป็น
SSPSTAT & 0b00000100 SSPCON2 & 0b00011111
มันหมายความว่าเราจะทำให้แน่ใจว่า 2 ครั้งบิตบน SSPSTAT เป็นศูนย์และในทำนองเดียวกันบิต 0-4 เป็นศูนย์ใน SSPCON2 จากนั้นเรารวมสิ่งเหล่านี้เพื่อตรวจสอบผลลัพธ์ที่เป็นศูนย์ หากผลลัพธ์เป็นศูนย์โปรแกรมจะดำเนินการต่อหากไม่ค้างไว้ที่นั่นจนกว่าจะได้ศูนย์เนื่องจากมีการใช้ใน while loop
เป็นโมฆะ I2C_Hold () { while ((SSPCON2 & 0b00011111) - (SSPSTAT & 0b00000100)); // ตรวจสอบสิ่งนี้ในการลงทะเบียนเพื่อให้แน่ใจว่า IIC ไม่อยู่ระหว่างดำเนินการ }
โมฆะ I2C_Begin () และโมฆะ I2C_End ()
ทุกครั้งในขณะที่เราเขียนหรืออ่านข้อมูลใด ๆ ที่ใช้บัส I2C เราควรจะเริ่มต้นและสิ้นสุดการเชื่อมต่อ I2C ในการเริ่มต้นการสื่อสาร I2C เราต้องตั้งค่าบิต SEN และเพื่อยุติการสื่อสารเราต้องตั้งค่าบิตสถานะ PEN ก่อนที่จะสลับบิตเหล่านี้เราควรตรวจสอบด้วยว่าบัส I2C ไม่ว่างหรือไม่โดยใช้ฟังก์ชัน I2C_Hold ตามที่กล่าวไว้ข้างต้น
เป็นโมฆะ I2C_Begin () { I2C_Hold (); // ค้างโปรแกรมคือ I2C ไม่ว่าง SEN = 1; // เริ่มต้น IIC pg85 / 234 } เป็นโมฆะ I2C_End () { I2C_Hold (); // ค้างโปรแกรมคือ I2C ไม่ว่าง PEN = 1; // สิ้นสุด IIC pg85 / 234 }
โมฆะ I2C_Write ()
ฟังก์ชั่นการเขียนที่ใช้ในการส่งข้อมูลใด ๆ จากโมดูลหลักไปยังโมดูลบรรเทา โดยปกติจะใช้ฟังก์ชันนี้หลังจากฟังก์ชันเริ่มต้น I2C และตามด้วยฟังก์ชันสิ้นสุด I2C ข้อมูลที่ต้องเขียนไปยังบัส IIC จะถูกส่งผ่านข้อมูลตัวแปร จากนั้นข้อมูลนี้จะถูกโหลดลงในทะเบียนบัฟเฟอร์ SSPBUF เพื่อส่งผ่านบัส I2C
โดยปกติก่อนที่จะเขียนข้อมูลจะมีการเขียนที่อยู่ดังนั้นคุณจะต้องใช้ฟังก์ชันเขียนสองครั้งครั้งหนึ่งสำหรับการตั้งค่าที่อยู่และเวลาอื่นสำหรับการส่งข้อมูลจริง
เป็นโมฆะ I2C_Write (ข้อมูลที่ไม่ได้ลงชื่อ) { I2C_Hold (); // ค้างโปรแกรมคือ I2C ไม่ว่าง SSPBUF = data; // pg82 / 234 }
I2C_Read () แบบสั้นที่ไม่ได้ลงชื่อ
ฟังก์ชันสุดท้ายที่เราต้องรู้คือฟังก์ชัน I2C_Read ฟังก์ชันนี้ใช้เพื่ออ่านข้อมูลที่อยู่บนบัส I2C ใช้หลังจากขอให้ทาสเขียนค่าบางอย่างลงในบัส ค่าที่ได้รับจะอยู่ใน SSPBUF เราสามารถโอนค่านั้นไปยังตัวแปรใดก็ได้สำหรับการดำเนินการของเรา
ในระหว่างการสื่อสารแบบ I2C ทาสหลังจากส่งข้อมูลที่มาสเตอร์ร้องขอจะส่งบิตอีกบิตซึ่งเป็นบิตการตอบรับส่วนบิตนี้ควรได้รับการตรวจสอบโดยมาสเตอร์เพื่อให้แน่ใจว่าการสื่อสารนั้นประสบความสำเร็จ หลังจากตรวจสอบบิต ACKDT เพื่อรับทราบแล้วควรเปิดใช้งานโดยการตั้งค่าบิต ACKEN
ไม่ได้ลงนาม I2C_Read สั้น ๆ (ไม่ได้ลงนามแอ๊สั้น) { ได้ลงนามสั้นที่เข้ามา; I2C_Hold (); RCEN = 1; I2C_Hold (); ขาเข้า = SSPBUF; // รับข้อมูลที่บันทึกไว้ใน SSPBUF I2C_Hold (); ACKDT = (แอค)? 0: 1; // ตรวจสอบว่าได้รับบิต ack หรือไม่ ACKEN = 1; // pg 85/234 ส่งกลับขาเข้า; }
นั่นคือฟังก์ชั่นเหล่านี้ควรเพียงพอสำหรับการตั้งค่าการสื่อสาร I2C และเขียนหรืออ่านข้อมูลจากอุปกรณ์ นอกจากนี้โปรดทราบว่ามีฟังก์ชันอื่น ๆ อีกมากมายที่การสื่อสาร I2C สามารถทำได้ แต่เพื่อความเรียบง่ายเราจะไม่พูดถึงพวกเขาที่นี่ คุณสามารถอ้างอิงแผ่นข้อมูลเพื่อทราบการทำงานที่สมบูรณ์ของไฟล์
คุณสามารถดาวน์โหลดโค้ดที่สมบูรณ์พร้อมไฟล์ส่วนหัวสำหรับการสื่อสาร PIC16F877A I2C ได้จากลิงค์
การเขียนโปรแกรมโดยใช้ไฟล์ส่วนหัว I2C:
ตอนนี้เราได้เรียนรู้แล้วว่าการสื่อสาร I2C ทำงานอย่างไรและเราจะใช้ไฟล์ส่วนหัวที่สร้างขึ้นมาได้อย่างไรให้เราสร้างโปรแกรมง่ายๆซึ่งเราจะใช้ไฟล์ส่วนหัวและเขียนค่าบางอย่างลงในบรรทัด I2C จากนั้นเราจะจำลองโปรแกรมนี้และตรวจสอบว่ามีการเขียนค่าเหล่านี้บนรถบัสหรือไม่
เช่นเคยโปรแกรมเริ่มต้นด้วยการตั้งค่าบิตการกำหนดค่าและตั้งค่าความถี่สัญญาณนาฬิกาเป็น 20 MHz ดังที่แสดงด้านล่าง
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (เปิดใช้งาน PWRT) # pragma config BOREN = ON // Brown-out Reset Enable bit (เปิดใช้งาน BOR) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 เป็น Digital I / O, HV บน ต้องใช้ MCLR ในการเขียนโปรแกรม) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory อาจเขียนถึงโดยการควบคุมของ EECON) #pragma config CP = OFF // บิตการป้องกันรหัสหน่วยความจำโปรแกรมแฟลช (ปิดการป้องกันรหัส) #define _XTAL_FREQ 20000000
ขั้นตอนต่อไปคือการเพิ่มไฟล์ส่วนหัวที่เราเพิ่งพูดถึง ไฟล์ส่วนหัวมีชื่อว่า PIC16F877a_I2C.h และสามารถดาวน์โหลดได้จากลิงค์ที่เรากล่าวถึงข้างต้น ตรวจสอบให้แน่ใจว่าได้เพิ่มไฟล์ส่วนหัวในไฟล์ส่วนหัวของรายการโปรเจ็กต์แล้วโครงสร้างไฟล์โปรเจ็กต์ของคุณควรมีลักษณะดังนี้
หลังจากตรวจสอบให้แน่ใจว่าได้เพิ่มไฟล์ส่วนหัวลงในไฟล์โปรเจ็กต์ของคุณแล้วรวมไฟล์ส่วนหัวในไฟล์ C หลัก
# รวม
ภายในลูป while เราจะเริ่มการสื่อสาร I2Cเขียนค่าสุ่มสองสามค่าไปยังบัส I2C จากนั้นจึงสิ้นสุดการสื่อสาร I2C ค่าสุ่มที่ฉันเลือกคือ D0, 88 และ FF คุณสามารถป้อนค่าใดก็ได้ที่คุณต้องการ แต่จำค่าเหล่านั้นไว้เนื่องจากเราจะตรวจสอบค่าในการจำลองของเรา
ในขณะที่ (1) { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0x88); I2C_Write (0xFF); I2C_End (); __delay_ms (1,000); }
โปรแกรมที่สมบูรณ์สามารถพบได้ที่ด้านล่างของหน้าคุณสามารถใช้หรือดาวน์โหลดไฟล์ซิปที่สมบูรณ์ของโปรแกรมจากที่นี่ หลังจากได้รับโปรแกรมรวบรวมและเตรียมพร้อมสำหรับการจำลอง
การจำลอง Proteus:
Proteus มีเครื่องมือที่ดีที่เรียกว่า I2C debugger ซึ่งสามารถใช้อ่านข้อมูลบนบัส I2C ได้ดังนั้นให้เราสร้างวงจรโดยใช้มันและตรวจสอบว่าข้อมูลถูกเขียนสำเร็จหรือไม่ สมบูรณ์วงจรแสดงอยู่ด้านล่าง
โหลดไฟล์ฐานสิบหกที่โปรแกรมของเราสร้างขึ้นโดยดับเบิลคลิกที่ไมโครคอนโทรลเลอร์ จากนั้นจำลองโปรแกรม คุณจะสังเกตเห็นหน้าต่างป๊อปอัปที่จะแสดงข้อมูลทั้งหมดเกี่ยวกับบัส I2C หน้าต่างสำหรับโปรแกรมของเราแสดงอยู่ด้านล่าง
หากคุณดูข้อมูลที่เขียนอย่างละเอียดคุณจะสังเกตได้ว่าข้อมูลเหล่านี้เหมือนกับที่เราเขียนไว้ในโปรแกรมของเรา ค่าคือ D0, 88 และ FF ค่าจะถูกเขียนทุก ๆ 1 วินาทีดังนั้นเวลาจึงอัปเดตตามที่แสดงด้านล่าง ลูกศรสีน้ำเงินแสดงว่ามันถูกเขียนจากต้นแบบถึงทาสซึ่งจะชี้ไปในทิศทางตรงกันข้ามหากเป็นอย่างอื่น ข้อมูลที่ถูกส่งอย่างใกล้ชิดแสดงอยู่ด้านล่าง
นี่เป็นเพียงภาพรวมของสิ่งที่ I2C ทำได้นอกจากนี้ยังสามารถอ่านและเขียนข้อมูลไปยังอุปกรณ์ต่างๆได้อีกด้วย เราจะกล่าวถึงเพิ่มเติมเกี่ยวกับ I2C ในบทช่วยสอนที่กำลังจะมาถึงโดยการเชื่อมต่อโมดูลต่างๆที่ทำงานกับโปรโตคอล I2C
หวังว่าคุณจะเข้าใจโครงการและเรียนรู้สิ่งที่เป็นประโยชน์จากโครงการนี้ หากคุณมีข้อสงสัยให้โพสต์ไว้ในส่วนความคิดเห็นด้านล่างหรือใช้ฟอรัมเพื่อขอความช่วยเหลือด้านเทคนิค
รหัสที่สมบูรณ์ได้รับด้านล่าง คุณสามารถดาวน์โหลดไฟล์ส่วนหัวพร้อมรหัสทั้งหมดได้จากที่นี่