- ما هو بروتوكول الاتصال I2C؟
- كيف تعمل I2C Communication؟
- أين تستخدم اتصالات I2C؟
- I2C مع PIC16F877a باستخدام مترجم XC8
- البرمجة باستخدام ملفات الرأس I2C:
- محاكاة Proteus:
المتحكمات الدقيقة PIC هي منصة قوية توفرها الرقائق الدقيقة للمشاريع المدمجة ، وطبيعتها المتعددة الاستخدامات جعلت من إيجاد طرق في العديد من التطبيقات وما زالت المرحلة مستمرة. إذا كنت تتابع دروس الموافقة المسبقة عن علم الخاصة بنا ، فستلاحظ أننا قمنا بالفعل بتغطية مجموعة واسعة من البرامج التعليمية حول الميكروكونترولر PIC بدءًا من الأساسيات. منذ الآن ، قمنا بتغطية الأساسيات التي يمكننا الدخول فيها إلى أشياء أكثر إثارة للاهتمام مثل بوابة الاتصالات.
في النظام الواسع للتطبيقات المضمنة ، لا يمكن لأي متحكم تنفيذ جميع الأنشطة بمفرده. في مرحلة ما من الوقت ، يتعين عليه الاتصال بأجهزة أخرى لمشاركة المعلومات ، وهناك العديد من أنواع بروتوكولات الاتصال المختلفة لمشاركة هذه المعلومات ، ولكن أكثرها استخدامًا هي USART و IIC و SPI و CAN. كل بروتوكول اتصال له ميزته وعيوبه. دعنا نركز على جزء IIC في الوقت الحالي لأن هذا هو ما سنتعلمه في هذا البرنامج التعليمي.
ما هو بروتوكول الاتصال I2C؟
يشير المصطلح IIC إلى " الدوائر المتكاملة المشتركة ". يُشار إليه عادةً باسم I2C أو I تربيع C أو حتى على أنه بروتوكول واجهة بسلكين (TWI) في بعض الأماكن ، لكن كل هذا يعني نفس الشيء. I2C هو بروتوكول اتصال متزامن بمعنى أن كلا الجهازين اللذين يتشاركان المعلومات يجب أن يشتركان في إشارة ساعة مشتركة. يحتوي على سلكين فقط لمشاركة المعلومات ، أحدهما يستخدم لإشارة الديك والآخر يستخدم لإرسال واستقبال البيانات.
كيف تعمل I2C Communication؟
تم تقديم اتصال I2C لأول مرة بواسطة Phillips. كما ذكرنا سابقًا أنه يحتوي على سلكين ، سيتم توصيل هذين السلكين عبر جهازين. هنا جهاز واحد يسمى رئيسي والجهاز الآخر يسمى عبد. يجب أن يحدث الاتصال وسيحدث دائمًا بين اثنين من السيد والعبد. ميزة اتصال I2C هي أنه يمكن توصيل أكثر من عبد واحد بالسيد.
يتم الاتصال الكامل من خلال هذين السلكين وهما الساعة التسلسلية (SCL) والبيانات التسلسلية (SDA).
Serial Clock (SCL): يشارك إشارة الساعة التي تم إنشاؤها بواسطة السيد مع التابع
Serial Data (SDA): يرسل البيانات من وإلى السيد والعبد.
في أي وقت من الأوقات ، لن يتمكن سوى السيد من بدء الاتصال. نظرًا لوجود أكثر من عبد واحد في الحافلة ، يتعين على السيد أن يشير إلى كل عبد باستخدام عنوان مختلف. عند تناول المرهم فقط بهذا العنوان المعين سوف يرد بالمعلومات بينما يستمر الآخرون في الإقلاع بهذه الطريقة يمكننا استخدام نفس الناقل للتواصل مع أجهزة متعددة.
أين تستخدم اتصالات I2C؟
يستخدم اتصال I2C فقط للاتصال قصير المدى. إنه بالتأكيد موثوق إلى حد ما لأنه يحتوي على نبض ساعة متزامن لجعله ذكيًا. يستخدم هذا البروتوكول بشكل أساسي للتواصل مع المستشعر أو الأجهزة الأخرى التي يتعين عليها إرسال المعلومات إلى السيد. يكون مفيدًا جدًا عندما يتعين على المتحكم الدقيق الاتصال بالعديد من الوحدات التابعة الأخرى باستخدام الحد الأدنى من الأسلاك فقط. إذا كنت تبحث عن اتصال بعيد المدى ، فعليك تجربة RS232 وإذا كنت تبحث عن اتصال أكثر موثوقية ، فعليك تجربة بروتوكول SPI.
I2C مع PIC16F877a باستخدام مترجم XC8
ما يكفي من المقدمات ، دعنا ندخلها ونتعلم كيف يمكننا استخدام متحكم لإجراء اتصالات I2C. قبل أن نبدأ في توضيح أن هذا البرنامج التعليمي يتحدث فقط عن I2C في PIC16F877a باستخدام مترجم XC8 ، ستكون العملية هي نفسها بالنسبة للميكروكونترولر الأخرى ولكن قد يلزم إجراء تغييرات طفيفة. تذكر أيضًا أنه بالنسبة للميكروكونترولر المتقدمة مثل سلسلة PIC18F ، قد يحتوي المحول البرمجي نفسه على مكتبة مدمجة لاستخدام ميزات I2C ، ولكن بالنسبة إلى PIC16F877A ، لا يوجد شيء من هذا القبيل ، لذلك دعونا نبني واحدة بمفردنا. سيتم تقديم المكتبة الموضحة هنا كملف رأس للتنزيل في الأسفل ويمكن استخدامه في PIC16F877A للتواصل مع أجهزة I2C الأخرى.
كما هو الحال دائمًا ، فإن أفضل مكان لبدء أي شيء هو ورقة البيانات الخاصة بنا. ابحث عن تفاصيل حول I2C في ورقة البيانات وتحقق من السجلات التي يجب تكوينها. لن أشرح بالتفصيل لأن ورقة البيانات قد فعلت ذلك بالفعل من أجلك. علاوة على ذلك ، سأشرح أدناه الوظائف المختلفة الموجودة في ملف الرأس ومسؤوليتها في البرنامج.
I2C_Initialize باطل ()
تُستخدم وظيفة التهيئة لإخبار المتحكم الدقيق بأننا سنستخدم بروتوكول I2C. يمكن القيام بذلك عن طريق تعيين البتات المطلوبة في سجل SSPCON و SSPCON2. ستكون الخطوة الأولى هي إعلان دبابيس IIC على أنها دبابيس إدخال ، وهنا يجب استخدام المسامير RC3 و RC4 لاتصالات I2C حتى نعلن أنها دبابيس إدخال. بعد ذلك ، يجب علينا تعيين SSPCON و SSPCON2 وهو عبارة عن سجلات تحكم MSSP. نحن نقوم بتشغيل الموافقة المسبقة عن علم في الوضع الرئيسي IIC بتردد ساعة FOSC / (4 * (SSPADD + 1)). ارجع إلى أرقام صفحات ورقة البيانات المذكورة في سطور التعليق أدناه لفهم سبب تعيين هذا السجل المعين بهذه الطريقة.
لذلك علينا بعد ذلك ضبط تردد الساعة ، قد يختلف تردد الساعة للتطبيقات المختلفة ، ومن ثم نحصل على الاختيار من المستخدم من خلال المتغير feq_k ونستخدمه في الصيغ الخاصة بنا لتعيين سجل SSPADD.
I2C_Initialize باطلة (const unsigned long feq_K) // Begin IIC as master { TRISC3 = 1؛ TRISC4 = 1 ؛ // تعيين دبابيس SDA و SCL كدبابيس إدخال SSPCON = 0b00101000 ؛ // pg84 / 234 SSPCON2 = 000000000 ؛ // 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 ND قليلا على SSPSTAT صفر وبالمثل بت 0-4 صفر على SSPCON2. ثم نجمع كل هذه القيم للتحقق من أن النتيجة صفر. إذا كانت النتيجة صفرًا ، فسيستمر البرنامج إذا لم يكن كذلك ، فسيظل ثابتًا حتى يحصل على صفر نظرًا لاستخدامه في حلقة while .
باطل 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 ؛ // Begin IIC pg85 / 234 } void I2C_End () { I2C_Hold () ؛ // امسك البرنامج I2C مشغول PEN = 1 ؛ // End IIC pg85 / 234 }
I2C_Write () باطل
تُستخدم وظيفة الكتابة لإرسال أي بيانات من الوحدة الرئيسية إلى وحدة salve. تُستخدم هذه الوظيفة عادةً بعد وظيفة بدء I2C وتليها وظيفة I2C End. يتم تمرير البيانات التي يجب كتابتها إلى ناقل IIC عبر البيانات المتغيرة. ثم يتم تحميل هذه البيانات في سجل المخزن المؤقت SSPBUF لإرسالها عبر ناقل I2C.
عادة قبل كتابة البيانات ، سيتم كتابة العنوان ، لذا سيتعين عليك استخدام وظيفة الكتابة مرتين ، مرة لإعداد العنوان والوقت الآخر لإرسال البيانات الفعلية.
I2C_Write (بيانات غير موقعة) باطلة { I2C_Hold () ؛ // امسك البرنامج I2C مشغول SSPBUF = بيانات ؛ // pg82 / 234 }
I2C_Read قصير بدون إشارة ()
الوظيفة الأخيرة التي يجب أن نعرفها هي وظيفة I2C_Read . تُستخدم هذه الوظيفة لقراءة البيانات الموجودة حاليًا في ناقل I2C. يتم استخدامه بعد طلب العبد لكتابة بعض القيمة إلى الحافلة. ستكون القيمة المستلمة في SSPBUF ، ويمكننا نقل هذه القيمة إلى أي متغير لعملياتنا.
أثناء اتصال I2C ، سيرسل العبد بعد إرسال البيانات المطلوبة من قبل السيد بتًا آخر وهو بت الإقرار ، ويجب أيضًا فحص هذا البت من قبل السيد للتأكد من نجاح الاتصال. بعد التحقق من بت ACKDT للإقرار ، يجب تمكينه عن طريق ضبط بت ACKEN.
I2C_Read قصير بدون إشارة (ack قصير بدون توقيع) { وارد قصير بدون توقيع ؛ I2C_Hold () ، RCEN = 1 ؛ I2C_Hold () ، وارد = SSPBUF ؛ // احصل على البيانات المحفوظة في SSPBUF I2C_Hold () ؛ ACKDT = (ack)؟ 0: 1 ؛ // تحقق مما إذا كان ack bit قد تلقى ACKEN = 1 ؛ // ص 85/234 عودة واردة ؛ }
هذا كل شيء ، يجب أن تكون هذه الوظائف كافية لإعداد اتصال I2C وكتابة أو قراءة البيانات من الجهاز. لاحظ أيضًا أن هناك العديد من الوظائف الأخرى التي يمكن أن يؤديها اتصال I2C ولكن من أجل البساطة ، لا نناقشها هنا. يمكنك دائمًا الرجوع إلى ورقة البيانات لمعرفة العمل الكامل لملف
يمكن تنزيل الكود الكامل مع ملف الرأس للاتصال PIC16F877A I2C من الارتباط.
البرمجة باستخدام ملفات الرأس I2C:
الآن بعد أن تعلمنا كيف يعمل اتصال I2C وكيف يمكننا استخدام ملف الرأس الذي تم إنشاؤه له ، دعونا نصنع برنامجًا بسيطًا سنستخدم فيه ملف الرأس ونكتب بعض القيم إلى سطور I2C. سنقوم بعد ذلك بمحاكاة هذا البرنامج والتحقق مما إذا كانت هذه القيم مكتوبة على الحافلة.
كما هو الحال دائمًا ، يبدأ البرنامج بإعداد بتات التكوين وضبط تردد الساعة على 20 ميجا هرتز كما هو موضح أدناه
#pragma config FOSC = HS // Oscillator Selection bits (HS مذبذب) #pragma config WDTE = OFF // Watchdog Timer تمكين بت (WDT معطل) #pragma config PWRTE = ON // Power-up Timer تمكين بت (تمكين PWRT) # pragma config BOREN = ON // Brown-out إعادة تعيين تمكين بت (تمكين BOR) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circial Programming Enable bit (RB3 هو إدخال / إخراج رقمي ، 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 control) #pragma config CP = OFF // بت حماية رمز ذاكرة برنامج Flash (إيقاف حماية الرمز) #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 (1000) ؛ }
و برنامج كامل ويمكن الاطلاع على الجزء السفلي من الصفحة، يمكنك استخدام هذا أو تحميل ملف مضغوط كاملة من البرنامج من هنا. بعد الحصول على البرنامج قم بتجميعه والاستعداد للمحاكاة.
محاكاة Proteus:
يحتوي Proteus على أداة لطيفة تسمى مصحح أخطاء I2C والتي يمكن استخدامها لقراءة البيانات الموجودة على ناقل I2C ، لذلك دعونا نبني دائرة باستخدامها ونتحقق مما إذا كانت البيانات تتم كتابتها بنجاح. يظهر مخطط الدائرة الكاملة أدناه
قم بتحميل الملف السداسي الذي تم إنشاؤه بواسطة برنامجنا بالنقر المزدوج على متحكم دقيق. ثم قم بمحاكاة البرنامج. ستلاحظ نافذة منبثقة تعرض جميع المعلومات حول ناقل I2C. تظهر نافذة برنامجنا أدناه.
إذا ألقيت نظرة فاحصة على البيانات التي تتم كتابتها ، يمكنك ملاحظة أنها هي نفسها التي كتبناها في برنامجنا. القيم هي D0 و 88 و FF. تتم كتابة القيم لكل ثانية واحدة لذلك يتم تحديث الوقت أيضًا كما هو موضح أدناه. يشير السهم الأزرق إلى أنه مكتوب من السيد إلى العبد ، فإنه يشير إلى الاتجاه المعاكس إذا كان الأمر كذلك. يتم عرض نظرة فاحصة على البيانات التي يتم إرسالها أدناه.
هذه مجرد لمحة عما يمكن أن تفعله I2C ، يمكنها أيضًا قراءة البيانات وكتابتها على أجهزة متعددة. سنغطي المزيد حول I2C في دروسنا القادمة من خلال ربط الوحدات المختلفة التي تعمل مع بروتوكول I2C.
أتمنى أن تكون قد فهمت المشروع وتعلمت منه شيئًا مفيدًا. إذا كانت لديك أي شكوك ، فقم بنشرها في قسم التعليقات أدناه أو استخدم المنتديات للحصول على المساعدة الفنية.
تم إعطاء رمز كامل أدناه ؛ يمكنك تنزيل ملفات الترويسة بجميع الأكواد من هنا.