أصدقاء PCF8563 في الوقت الحقيقي على مدار الساعة من اردوينو إلى I2C

مرحبا يا هبر. لقد صادفت استخدام 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 كيلو هرتز

Source: https://habr.com/ru/post/ar463265/


All Articles