مرحبا يا هبر. لقد صادفت استخدام RTC على شريحة PCF 8563 باستخدام I2C. نظرًا لأنني لم أجد الوظائف العادية للعمل الأكثر ملاءمة مع Arduino ، كان علي العمل مباشرة من خلال I2C. لقد وجدت برنامج
تعليمي توضيحي على الإنترنت باللغة الإنجليزية
مع وصف مفصل للعملية . هذه المقالة جزء من الترجمة في جزء من تجربتها مع RTC.

ضبط التاريخ والوقت
أول ما نصعد به إلى الدليل (
إنه هنا ) وابحث عن جدول لتنظيم السجلات هناك.

لتعيين التاريخ والوقت ، نحتاج إلى سجلات من 02h إلى 08h. يتم تخزين البيانات في هذه السجلات بالتنسيق العشري الثنائي (BCD) ، وبالتالي ، لتسجيل الثواني والدقائق ، إلخ. أولاً ننفذ وظيفة الترجمة (من التنسيق العشري إلى BCD والعكس بالعكس) ومن ثم باستخدام الأمر Wire.write () نكتبها في سجلات تبدأ من 02h. نقرأ بنفس الطريقة ، وننقل من BCD مرة أخرى إلى النظام العشري ، بدءًا من نفس السجل 02h. كما ترون من الجدول ، لا يتم استخدام البتات في بعض السجلات (المشار إليها بالحرف x) ، حتى لا يتم التحميل الزائد للمعلومات عند القراءة ، سنستخدم العملية bitwise AND (المنطقية "AND") التي ستعيد ضبط البتات التي لا نحتاج إليها. على سبيل المثال ، في أيام الشهر (الأيام) ، نحتاج إلى البتات من 0 إلى 5 ، باستخدام العملية (dayOfMonth & B00111111) التي نعيد ضبط البتات 6 و 7 ، وكل شيء آخر لم يمس.
مباشرة الكود نفسه مع إخراج المعلومات على جهاز تسلسلي:
#include "Wire.h" #define PCF8563address 0x51 // byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; // - . byte bcdToDec(byte value) { return ((value / 16) * 10 + value % 16); } // byte decToBcd(byte value){ return (value / 10 * 16 + value % 10); } // PCF8563 void setPCF8563() { Wire.beginTransmission(PCF8563address); Wire.write(0x02); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } // PCF8563 void readPCF8563() { Wire.beginTransmission(PCF8563address); Wire.write(0x02); Wire.endTransmission(); Wire.requestFrom(PCF8563address, 7); second = bcdToDec(Wire.read() & B01111111); // minute = bcdToDec(Wire.read() & B01111111); hour = bcdToDec(Wire.read() & B00111111); dayOfMonth = bcdToDec(Wire.read() & B00111111); dayOfWeek = bcdToDec(Wire.read() & B00000111); month = bcdToDec(Wire.read() & B00011111); year = bcdToDec(Wire.read()); } void setup() { Wire.begin(); Serial.begin(9600); // second = 0; minute = 28; hour = 9; dayOfWeek = 2; dayOfMonth = 13; month = 8; year = 13; setPCF8563(); } void loop() { readPCF8563(); Serial.print(days[dayOfWeek]); Serial.print(" "); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/20"); Serial.print(year, DEC); Serial.print(" - "); Serial.print(hour, DEC); Serial.print(":"); if (minute < 10) { Serial.print("0"); } Serial.print(minute, DEC); Serial.print(":"); if (second < 10) { Serial.print("0"); } Serial.println(second, DEC); delay(1000); }
ضبط المنبه
في PCF 8563 ، يمكنك تمكين التنبيه وضبطه لفترة محددة أو يوم من الأسبوع أو الشهر. توجد إعدادات التنبيه في السجل من الساعة 9 صباحًا وحتى الساعة 0 صباحًا بالتنسيق العشري الثنائي.

لتمكين التنبيه من خلال بعض الإعدادات ، على سبيل المثال ، الدقائق والساعات ، تحتاج إلى ضبط البت السابع (بت تمكين) على واحد ، لذلك ، استخدم العملية المنطقية OR (OR) والقيمة B10000000.
يمكن التحقق من تشغيل المنبه بطريقتين: صلبة وناعمة. باستخدام الطريقة اللينة ، نتحقق من البت الثالث للتسجيل 0x01 (بت إشارة التنبيه AF) عند تشغيله ، فإنه يساوي واحدًا ، ونضبطه على 0 ، وينطفئ التنبيه.

للتحقق الثابت ، تحتاج إلى ترجمة 1 بت في نفس السجل (AIE) إلى واحد. عند إيقاف تشغيل المنبه ، ينتقل دبوس INT (المقاطعة) الموجود على اللوحة إلى وضع موصل ، كونه مخرج تصريف مفتوح ، بحيث يمكنك لحام مؤشر LED بأمان بمقاوم ، على سبيل المثال ، وتوصيله جميعًا بـ 5 فولت.
الآن رسم نفسه:
إدراج #include "Wire.h" #define PCF8563address 0x51 byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; byte alarmMinute, alarmHour, alarmDay, alarmDayOfWeek; String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; byte bcdToDec(byte value) { return ((value / 16) * 10 + value % 16); } byte decToBcd(byte value){ return (value / 10 * 16 + value % 10); } // void setPCF8563alarm() { byte am, ah, ad, adow; am = decToBcd(alarmMinute); am = am | 100000000; // ah = decToBcd(alarmHour); ah = ah | 100000000; // ad = decToBcd(alarmDay); ad = ad | 100000000; // adow = decToBcd(alarmDayOfWeek); adow = ad | 100000000; // // PCF8563 Wire.beginTransmission(PCF8563address); Wire.write(0x09); Wire.write(am); Wire.write(ah); // . /* Wire.write(ad); Wire.write(adow); */ Wire.endTransmission(); // . INT // PCF8563alarmOff() Wire.beginTransmission(PCF8563address); Wire.write(0x01); Wire.write(B00000010); Wire.endTransmission(); } void PCF8563alarmOff() // . { byte test; // 0x01h Wire.beginTransmission(PCF8563address); Wire.write(0x01); Wire.endTransmission(); Wire.requestFrom(PCF8563address, 1); test = Wire.read(); // 3 0 test = test - B00001000; // 0x01h Wire.beginTransmission(PCF8563address); Wire.write(0x01); Wire.write(test); Wire.endTransmission(); } void checkPCF8563alarm() // { byte test; // 0x01h test Wire.beginTransmission(PCF8563address); Wire.write(0x01); Wire.endTransmission(); Wire.requestFrom(PCF8563address, 1); test = Wire.read(); test = test & B00001000; if (test == B00001000) // { Serial.println("** alarm **"); delay(2000); // PCF8563alarmOff(); } } void setPCF8563() { Wire.beginTransmission(PCF8563address); Wire.write(0x02); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } void readPCF8563() { Wire.beginTransmission(PCF8563address); Wire.write(0x02); Wire.endTransmission(); Wire.requestFrom(PCF8563address, 7); second = bcdToDec(Wire.read() & B01111111); minute = bcdToDec(Wire.read() & B01111111); hour = bcdToDec(Wire.read() & B00111111); dayOfMonth = bcdToDec(Wire.read() & B00111111); dayOfWeek = bcdToDec(Wire.read() & B00000111); month = bcdToDec(Wire.read() & B00011111); year = bcdToDec(Wire.read()); } void setup() { Wire.begin(); Serial.begin(9600); second = 50; minute = 44; hour = 13; dayOfWeek = 1; dayOfMonth = 19; month = 8; year = 13; setPCF8563(); // alarmMinute = 45; alarmHour = 13; setPCF8563alarm(); } void loop() { readPCF8563(); Serial.print(days[dayOfWeek]); Serial.print(" "); Serial.print(dayOfMonth, DEC); Serial.print("/"); Serial.print(month, DEC); Serial.print("/20"); Serial.print(year, DEC); Serial.print(" - "); Serial.print(hour, DEC); Serial.print(":"); if (minute < 10) { Serial.print("0"); } Serial.print(minute, DEC); Serial.print(":"); if (second < 10) { Serial.print("0"); } Serial.println(second, DEC); delay(1000); // checkPCF8563alarm(); }
استخدام كمولد
مثل العديد من RTCs ، يمكن استخدام PCF8563 كمولد إشارة. دبوس COT (دبوس 7 من الدائرة الدقيقة) هو مصرف مفتوح ، حتى تتمكن من وميض مؤشر LED من خلال هذا الدبق بتردد مختلف ، سجل 0x0D مسؤول عن معلمات التردد.

يتم تشغيل الجزء السابع من هذا السجل (FE) على المولد ، حيث تقوم البتتان 0 و 1 بتعيين التردد المطلوب ، ولا يتم استخدام البتات من 6 إلى 2.
عند كتابة القيم التالية في السجل ، يمكنك الحصول على التردد المطلوب:
- 10000000 - 32.768 كيلو هرتز ؛
- 10000001 - 1.024 كيلو هرتز ؛
- 10000010 - 32 هرتز ؛
- 10000011 - 1 هرتز ؛
- 0 - تعطيل الإخراج ؛
مثال رسم:
#include "Wire.h" #define PCF8563address 0x51 void PCF8563oscOFF() // { Wire.beginTransmission(PCF8563address); Wire.write(0x0D); Wire.write(0); Wire.endTransmission(); } void PCF8563osc1Hz() // 1 Hz { Wire.beginTransmission(PCF8563address); Wire.write(0x0D); Wire.write(B10000011); Wire.endTransmission(); } void PCF8563osc32Hz() // 32 Hz { Wire.beginTransmission(PCF8563address); Wire.write(0x0D); Wire.write(B10000010); Wire.endTransmission(); } void PCF8563osc1024kHz() // 1.024 kHz { Wire.beginTransmission(PCF8563address); Wire.write(0x0D); Wire.write(B10000001); Wire.endTransmission(); } void PCF8563osc32768kHz() // 32.768 kHz { Wire.beginTransmission(PCF8563address); Wire.write(0x0D); Wire.write(B10000000); Wire.endTransmission(); } void setup() { Wire.begin(); } void loop() { PCF8563osc1Hz(); delay(2000); PCF8563osc32Hz(); delay(2000); PCF8563osc1024kHz(); delay(2000); PCF8563osc32768kHz(); delay(2000); PCF8563oscOFF(); delay(2000); }
أمثلة من الطول الموجي مأخوذة من الصمام1 هرتز
32 هرتز
1.024 كيلو هرتز
32.768 كيلو هرتز