منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر
هل تريد التفاعل مع هذه المساهمة؟ كل ما عليك هو إنشاء حساب جديد ببضع خطوات أو تسجيل الدخول للمتابعة.

شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الأحد سبتمبر 08, 2019 9:54 pm

[SIZE="4"]شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة وتقنيات البرمجة بلغة السى مع المترجم ميكروسى برو وبرنامج المحاكاة بروتيس

المرجع :

mediafire.com file/hozzp495cy8yta1/ClockHand-7Seg.rar/file[/SIZE]

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الإثنين سبتمبر 09, 2019 12:01 pm

مقدمة :
خطوات تنفيذ البرنامج (الخوارزمية) :

بعد إعدادات المنافذ والمقاطعة وتهيئة الناقل I2C :
1- كتابة (إرسال) الزمن والتاريخ الابتدائى StartTime إلى الشريحة DS1307 .
2- عمل حلقة غير منتهية وفيها يتم :
أ‌- قراءة الزمن والتاريخ ReadI2C من الشريحة DS1307 ، البيانات بالثنائى المكود عشرى BCD .
ب‌- تحويل البيانات من BCD إلى العشرى TransformTime .
ت‌- تهيئة الساعة لتعمل بنظام 12 ساعة مع وضع AM-PM ، Hour12_AM_PM .
ث‌- استخلاص قيم الآحاد والعشرات لكل بند والحصول على القيم السداسية عشرى الخاصة بكود السفن سيجمنت المقابل تمهيدا لوضعها على المنفذ PORTB لعرضها باستخدام المقاطعة DisplayTime .
ج‌- عرض الزمن Time (Hour & Minute) باستخدام المقاطعة GotoTime .
ح‌- القيام باختيار أحد المفاتيح واتخاذ القرار بناء على هذا الاختيار :
1- الضغط على المفتاح Button1 : يؤدى إلى
• عرض التاريخ GotoDate .
• الضغطة الثانية تعرض الثوانى GotoSecond .
• الضغطة الثالثة تعرض التاريخ مرة أخرى GotoTime .
2- الضغط على المفتاح Button2 يؤدى إلى :
• عرض الزمن GotoTime .
• الضغطة الثانية تؤدى إلى الدخول فى نظام تغيير الزمن والتاريخ حيث يتم البدء بوميض الساعة hour عندئذ يمكن بالستخدام المفتاح Button1 زيادة قيمة الساعة ، والضغطة الثانية تعرض وميض الدقائق وهكذا ، حتى نصل إلى السنة year وفى النهاية يتم حفظ التغييروالعودة إلى الوضع العادى بعرض الزمن . فى حالة الضغط على المفتاح Button3 أثناء إجراء التغيير يتم إلغاء التغيير والعودة إلى عرض الزمن من دون حفظ التغيير .
3- الضغط على المفتاح Button3 يؤدى إلى : عرض الزمن علاوة على العمل السابق .
4- الضغط على المفتاح Button4 يؤدى إلى عرض السنة .

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الإثنين سبتمبر 09, 2019 12:52 pm

أولا : الإعلان عن المتغيرات العمومية Global واستخدام موجه قبل المعالج #define فى تعريف بعض الثوابت بأسماء ذات معنى :

الكود:

char second, minute, hour, day, date, month, year;
char second_d1, second_d2, minute_d1, minute_d2, hour_d1, hour_d2;
char date_d1, date_d2, month_d1, month_d2, year_d1, year_d2, year_d3, year_d4;
char convert, hold;
char seg[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //Segment 0-9
//----Buttons-----------------------------//
#define Button1  PORTC.f0  //Show Date & Second, Date & Second ++
#define Button2  PORTC.f1  //Change Time & Date
#define Button3  PORTC.f2  //Show Time & No Save Time & Date
#define Button4  PORTC.f5  //Show Year
//----In Interrupt-----------------------------------//
#define GotoTime    0
#define GotoSecond  1
#define GotoDate    2
#define GotoYear    3
//#define GotoClear    4
//----Hour 12 (AM-PM)---------------------//
#define AM  PORTE.f0  //Hour12(AM)
#define PM  PORTE.f1  //Hour12(PM)


ملاحظات :
• جميع المتغيرات صغيرة الحجم ولذلك يتم إعلانها من نوع الحرف char ، كما يمكن استخدام النوع unsigned short فكلاهما بحجم واحد بايت أى مداه 0-255 .
• عبارة التوجيه #define لا تنتهى بفاصلة منقوطة .

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الإثنين سبتمبر 09, 2019 10:01 pm

ثانيا : الدالة الرئيسية main
أ‌- فى البداية يتم :
• إعداد وتهيئة منافذ الميكروكونترولر : المنفذ PORTB مخارج ، والمنفذ PORTC مداخل ، والمنفذ PORTD مخارج ، والمنفذ PORTE مخارج .
• إعداد سجلات التحكم فى المقاطعة ، ففى سجل التحكم فى المقاطعة INTCON يتم تحديد بت المقاطعة بالمؤقت TMR0 ( البت BIT5 ) T0IE وكذلك تحديد set بت عموم المقاطعات (BIT7 ) GIE ، ومسح clear بت علم المقاطعة بالمؤقت TMR0 (BIT2) T0IF . وفى سجل الخيارات OPTION_REG يتم مسح الثلاثة بتات الأولى لاختيار معامل قسمة التردد prescaler بالقيمة 2 وبهذه الطريقة تحدث المقاطعة بسجل المؤقت TMR0 كل 255 ميكروثانية (باعتبار تردد الكريستال المستخدم 4 ميجا هرتز ) مضروبا فى 2 أى كل حوالى نصف ملى ثانية  .عند حدوث المقاطعة يتم تحديد بت علم المقاطعة حيث يتم مسحها يدويا فى نهاية دالة المقاطعة تمهيدا للمقاطعة التالية .    
• تهيئة الناقل I2C للإتصال بتردد 100 كيلو هرتز .
• وإرسال (كتابة) زمن وتاريخ ابتدائى إلى الشريحة DS1307 باستخدام الدالة StartTime.


 

الكود:
   trisB = 0;   trisC = 0xff;   trisD = 0;   trisE = 0;
     option_reg = 0b10000000; intcon = 0b10100000;       //Registers
     i2c1_init(100000);   //Init I2C(IC DS1307)
     StartTime(0x00, 0x19, 0x09, 5, 0x05, 0x09, 0x19);   //Start Time


دالة الكتابة إلى الشريحة DS1307 :



الكود:
//----Start Time for IC DS1307------------------------------//
void StartTime(char second, char minute, char hour, char day, char date, char month, char year)
{
     i2c1_start();
     i2c1_wr(0xd0);
     i2c1_wr(0);

     i2c1_wr(second);
     i2c1_wr(minute);
     i2c1_wr(hour);
     i2c1_wr(day);
     i2c1_wr(date);
     i2c1_wr(month);
     i2c1_wr(year);
     i2c1_wr(0x10); // 1Hz
     i2c1_stop();
}


هذه الدالة وسائطها المتغيرات المحلية local من نوع الحرف second و minute و hourو day و dateو month و year .
خطوات كتابة الوقت والتاريخ
• إصدار حالة البداية i2c1_start() .
• إرسال (كتابة) عنوان الشريحة DS1307 وهو 0xd0  مع جعل البت الأدنى LSB بصفر لتحديد وضع الكتابة     i2c1_wr(0xd0) .
• أرسال عنوان السجل المطلوب الكتابة إليه  (على سبيل المثال 0x00 للكتابة إلى سجل الثوانى second ). يضبط (يعين) هذا النقل مؤشر السجل داخل الشريحة i2c1_wr(0) .

• إرسال قيمة الثواني بتنسيق BCD i2c1_wr(second) . باتباع إجراء الكتابة إلى سجل الثواني ، سيزداد المؤشر في RTC تلقائيًا. ستتم كتابة البيانات التالية في موقع 0x01 وهو سجل الدقيقة minute i2c1_wr(minute).
• الأرسال حتى يتم كتابة سجل العام year  i2c1_wr(year) . السجل الأخير يمكن عن طريقة الحصول على نبضات خرج من الشريحة بتردد 1Hz i2c1_wr(0x10) .  
• قم بإنهاء الاتصال بإصدار حالة التوقف i2c1_stop( .

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الثلاثاء سبتمبر 10, 2019 12:42 pm

ب‌- الحلقة الغير منتهية :
يمكن تقسيم ما بداخل الحلقة الغير منتهية إلى قسمين
القسم الأول : قسم إنشاء الساعة ، والقسم الثانى : قسم مفاتيح التحكم .

القسم الأول : قسم إنشاء الساعة :


الكود:
while(1)
    {
        ReadI2C();         //I2C Read for IC DS1307 in BCD format
        Hour12_AM_PM();      //Hour 12 (AM-PM)
        TransformTime();//Transform Time for IC DS1307 from BCD TO Decimal format
      DisplayTime(); // get ten and one part of each item then get 7 segment code value that applied to PORTB 
        convert = GotoTime;  //Goto Time in Interrupt , Show Time(Hour & Minute)
 


1- نبدأ بدالة قرأء بيانات الزمن والتاريخ ReadI2C() من الشريحة DS1307 من خلال الناقل I2C وتكون بالشكل الثنائى المكود عشرى BCD :

الكود:

//----I2C Read for IC DS1307----------------//
void ReadI2C()
{
    i2c1_start();      // start condition

    i2c1_wr(0xd0);      // slave address with write mode
    i2c1_wr(0);      // address of seconds register written to the pointer

    i2c1_repeated_start();

    i2c1_wr(0xd1);      // slave address with read mode

    second = i2c1_rd(1);   // Read the slave with ACK
    minute = i2c1_rd(1);
    hour  = i2c1_rd(1);
    day    = i2c1_rd(1);
    date  = i2c1_rd(1);
    month  = i2c1_rd(1);
    year  = i2c1_rd(0);   // Read the slave with not-ACK
   
    i2c1_stop();         //i2c stop condition
}

خطوات قراءة الزمن والتاريخ :
• إصدار حالة البدء START . i2c1_start()
• إرسال عنوان الشريحة RTC مع جعل البت الأدنى بصفر (0xD0) للوصول إلى RTC في وضع الكتابة . i2c1_wr(0xd0)
• إرسال عنوان أول سجل وهو سجل الثوانى لتحديد وضع المؤشر . i2c1_wr(0)
• إعادة حالة البدء . i2c1_repeated_start()
• إرسال عنوان الشريحة RTC مع جعل البت الأدنى بواحد (0xD1) للوصول إلى RTC في وضع القراءة.
• الآن ستقوم RTC بإرسال البيانات من سجلاتها واحد تلو الآخر . يجب الانتباه إلى أنه سيتم إخراج البيانات في السجل الذي يتم تخزين عنوانه حاليًا في المؤشر. إذا احتاج المستخدم إلى قراءة سجل معين ، فيجب أولاً الوصول إلى RTC في وضع الكتابة ويجب كتابة عنوان السجل المطلوب على المؤشر. ثم مرة أخرى ، يجب معالجة RTC في وضع القراءة بعد إصدار إعادة حالة البدء
• يجب أن يعترف ACK الماستر بكل بايت يستقبله (يقرأه) لاستقبال البايت التالية ، متمثلا بالواحد كوسيط لدالة القراءة .
• بعد استلام آخر بايت فإن الماستر يجب أن يرسل إشارة NACK إلى RTC متمثلا بالصفر كوسيط لدالة القراءة.
• إنهاء الاتصالات بإصدار حالة STOP على الناقل I2C .

ملاحظات :
• جميع قيم سجلات الزمن والتاريخ تكون بتنسيق ثنائى مكود عشرى BCD ، لذلك تحتاج إلى تحويلها التنسيق العشرى / السداسى عشرى لبدء المعالجة .
• جميع المتغيرات المذكورة فى هذه الدالة هى متغيرات عمومية global أى يمكن الوصول إليها ومعالجتها من جميع الدوال .

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الثلاثاء سبتمبر 10, 2019 10:06 pm

2- دالة العمل بنظام 12 ساعة مع بيان AM/PM باستخدام ليدات :


الكود:
 //----Hour 12 (AM-PM)----------------------//
void Hour12_AM_PM()
{
    if (hour < 0x12)//case 1 hour<12
    {
        if (hour == 0)
        {
          hour = 0x12;
          AM = 1;
        }
        else AM = 1;
    }
   
    else if (hour == 0x12)//case 2 hour=12
    {
        PM = 1;
    }
   
    else if (hour > 0x12 && hour < 0x20)//case 3 hour>12 && hour < 20
    {
        hour = hour - 0x12;
        PM = 1;
    }
   
    else if (hour == 0x20)//case 4
    {
        hour = 0x08;
        PM = 1;
    }
   
    else if (hour == 0x21)//case 5
    {
        hour = 0x09;
        PM = 1;
    }
   
    else if (hour == 0x22)//case 6
    {
        hour = 0x10;
        PM = 1;
    }
   
    else if (hour == 0x23)//case 7
    {
        hour = 0x11;
        PM = 1;
    }
   
   
}

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الأربعاء سبتمبر 11, 2019 6:30 pm


3- دالة تحويل بيانات الزمن والتاريخ من ثنائى مكود عشرى BCD إلى عشرى لنتمكن من معالجتها

الكود:

TransformTime();//Transform Time for IC DS1307 from BCD TO Decimal format

//----Transform Time for IC DS1307------------------//
void TransformTime()
{
    second =((second & 0xf0)>>4)* 10 +(second & 0x0f);
    minute =((minute & 0xf0)>>4)* 10 +(minute & 0x0f);
    hour  =((hour & 0xf0)>>4)* 10 +(hour & 0x0f);
    day    =((day & 0xf0)>>4)* 10 +(day & 0x0f);
    date  =((date & 0xf0)>>4)* 10 +(date & 0x0f);
    month  =((month & 0xf0)>>4)* 10 +(month & 0x0f);
    year  =((year & 0xf0)>>4)* 10 +(year & 0x0f);
}
 

تحويل من النظام BCD المكون من رقمين إلى النظام العشرى :
عند قراءة بيانات الزمن والتاريخ من الشريحة DS1307 تكون بالنظام BCD ويلزم تحويلها إلى النظام العشرى لاستخدامها بعد ذلك فى دالة العرض DisplayTime للحصول على القيم المناظرة لكود السفن سيجمنت .
المترجم ميكروسى برو يوفر دالة جاهزة للتحويل من BCD إلى عشرى وهى Bcd2Dec ولكن استخدامها يستهلك الذاكرة المتواضعة ، لذلك يفضل عدم استخدامها ولكن تستخدم طريقة التحويل المبينة أعلاه .
فى هذه الطريقة يتم التحويل على خطوات :
• للحصول على الرقم المناظر لرقم العشرات يتم إجراء عملية AND بين متغير البيانات ( وليكن second ) والقيمة 0xf0 للحصول على الاربع بتات (النبل) العلوية وإزاحة النتيجة 4 أماكن ثم الضرب فى 10 (second & 0xf0)>>4)* 10 .
• وللحصول على الرقم المناظر لرقم الآحاد يتم إجراء عملية AND بين متغير البيانات second والقيمة 0x0f للحصول على الأربع بتات السفلية .
• أخيرا يتم جمع رقم العشرات ورقم الآحاد .
ملحوظة : عند استخدام الدالة الجاهزة تكون دالة التحويل بالشكل التالى :

الكود:
 //----Transform Time for IC DS1307------------------//
void TransformTime()
{
    second = Bcd2Dec(second);   
    minute = Bcd2Dec(minute);
    hour  = Bcd2Dec(hour);
    day    = Bcd2Dec(day);
    date  = Bcd2Dec(date);
    month  = Bcd2Dec(month);
    year  = Bcd2Dec(year);
}

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الأربعاء سبتمبر 11, 2019 6:33 pm


4- دالة العرض DisplayTime

الكود:
 //-----Display Time------------------//
void DisplayTime()
{
    // char x;
    second_d1 = seg[second /10]; // Ten digit >> Segment code from seg[] array
    second_d2 = seg[second %10];// One digit >> Segment code from seg[] array

    minute_d1 = seg[minute /10];
    minute_d2 = seg[minute %10];

    hour_d1 = seg[hour /10];
    hour_d2 = seg[hour %10];

    date_d1 = seg[date /10];
    date_d2 = seg[date %10];

    month_d1 = seg[month /10];
    month_d2 = seg[month %10];

    year_d1 = seg[year /10];
    year_d2 = seg[year %10];
    year_d3 = seg[year /10];
    year_d4 = seg[year %10];
}

من هذه الدالة نحصل على كود السفن سيجمنت (الموجود فى المصفوفة seg ) لكل من وحدة رقم العشرات (_d1) ووحدة رقم الآحاد (_d2) .
فى الدالة السابقة حصلنا على عدد عشرى مكون من رقمين ، وفى هذه الدالة نستخلص رقم العشرات second /10 ورقم الآحاد second %10 وهو عبارة عن رقم عشرى من 0 إلى 9 . هذا الرقم نضعة مكان فهرس index المصفوفة seg ، وهى أيضا مرتبة من 0 إلى 9 وبالتالى نحصل على كود السفن سيجمنت المقابل للرقم seg[second /10] , seg[second %10 .

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الأربعاء سبتمبر 11, 2019 6:40 pm


5- عرض الزمن ( الساعات والدقائق) convert = GotoTime على السفن سيجمنت

الكود:
convert = GotoTime;  //Goto Time in Interrupt , Show Time(Hour & Minute) 


الكود:
if (convert == GotoTime)    //Show Time(Hour & Minute)
    {
        portd = 1;  portb = hour_d1;      delay_ms(1);
        portd = 2;  portb = hour_d2 + 128; delay_ms(1);
        portd = 4;  portb = minute_d1;    delay_ms(1);
        portd = 8;  portb = minute_d2;    delay_ms(1);
    }

فى الدالة الرئيسية نستدعى عبارة عرض الزمن :

الكود:
convert = GotoTime;  //Goto Time in Interrupt , Show Time(Hour & Minute) 
هذا الاستدعاء سوف يتم تنفيذه عند حدوث كل مقاطعة بالمؤقت TMR0 أى كل نصف ثانية حيث يتم الاستجابة لهذا الشرط وعرض كود السفن سيجمنت الخاص بالزمن بطريقة Multiplexing (الانتخاب من متعدد) حيث يتم عرض بيانات الزمن على المنفذ PORTB وانتخاب توصيل وحدات السفن سيجمنت بتوصيل مصعدها المشترك بالجهد الموجب من خلال المنفذ PORTD واحدة تلو الأخرى مع تأخير واحد ملى ثانية ويتكرر ذلك عند كل مقاطعة إى كل نصف ثانية .

وهكذا نكون قد وصلنا إلى نهاية القسم الأول وحصلنا على عرض للزمن (ساعة ودقيقة) .

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الخميس سبتمبر 12, 2019 7:18 pm

القسم الثانى : استخدام المفاتيح للتحكم فى العرض
يحتوى البرنامج على أربعة مفاتيح : المفتاح Button1 يعمل بنظام القائمة لعرض التاريخ (يوم وشهر) ، وعرض الثوانى ، والعودة لعرض الزمن (ساعة ودقائق) . والمفتاح Button2 يساعد فى عملية ضبط الساعة وهو يعمل أيضا بنظام القائمة لعرض كل من الزمن والتاريخ والعام فى شكل وامض لتغييرها عن طريق المفتاح Button1 ، وحفظ التغييرات . والمفتاح Button3 لعرض الزمن أو الخروج من عملية ضبط الساعة من دون حفظ التغييرات . والمفتاح Button4 لعرض العام year .

1- المفتاح Button1 :


الكود:
 if (Button1 == 0 && Button2 == 0){hold = 1;}
      //Button1////////////////////
if (Button1 == 1 && hold == 1)  //Show Date & Second
        {
          hold = 0;
          convert = GotoDate;  //Goto Interrupt
          MenuDateSecond();  //Goto MenuDateSecond();
          //break;
        }
/////////////////////////////////////

if (convert == GotoDate)    //A-Show Date(Date & Month)
    {
        portd = 1;  portb = date_d1;      delay_ms(1);
        portd = 2;  portb = date_d2 + 128; delay_ms(1);//128 to DP on  d1d2.m1m2
        portd = 4;  portb = month_d1;      delay_ms(1);
        portd = 8;  portb = month_d2;      delay_ms(1);
    }


• فى الحالة الابتدائية يكون دخل كل من المفتاح Button1 و Button2 فى الحالة المنخفضة ويتم تذكر هذه الحالة بجعل المتغير hold=1 :

الكود:
if (Button1 == 0 && Button2 == 0){hold = 1;}

• عند الضغط على المفتاح Button1 يتحقق شرط العبارة :

الكود:
if (Button1 == 1 && hold == 1)  //Show Date & Second

نتيجة لذلك يتم تصفير المتغير hold=0 ثم يتم :
أ‌- عرض بيانات التاريخ (يوم وشهر) . لاحظ إضافة العدد 128 لإضاءة ليد النقط العشرية DP لتوضيح العرض:

الكود:
 if (convert == GotoDate)    //A-Show Date(Date & Month)
    {
        portd = 1;  portb = date_d1;      delay_ms(1);
        portd = 2;  portb = date_d2 + 128; delay_ms(1);//128 to DP on  d1d2.m1m2
        portd = 4;  portb = month_d1;      delay_ms(1);
        portd = 8;  portb = month_d2;      delay_ms(1);
    }


ب‌- بعد ذلك يتم الدخول إلى دالة عرض قائمة التاريخ والثوانى :

الكود:
 MenuDateSecond();  //Goto MenuDateSecond();

فى هذه الدالة يتم إعلان متغير العداد set وتعينه بالصفر (تصفيره)
char set;

الكود:
  set = 0;

ثم الدخول إلى حلقة غير منتهية وفيها يتم :
• تحديث البيانات باستدعاء دوال إنشاء الساعة :

الكود:
  ReadI2C();
  Hour12_AM_PM();
 TransformTime();
 DisplayTime();


• عند الضغط على المفتاح Button1 يتم تزايد العداد set بواحد وبناء على ذلك يتم اتخاذ القرارات :
1- إذا كان set=0 يتم عرض التاريخ Date .
2- إذا كان set=1 أى الضغطة التالية يتم عرض الثوانى Second .
3- إذا كانت set>1 إى بعد الضغطة التالية يتم العودة لعرض الزمن والخروج من الحلقة الغير منتهية .
4- إذا كانت set>=1 وتم الضغط على المفتاح Button2 يتم تصفير الثوانى وحفظ الزمن والتاريخ والسنة .

الكود:
//----Show Date & Second for Button1-------------------//
void MenuDateSecond()
{
    char set;
    set = 0;
    while(1)
    {
        ReadI2C();
        Hour12_AM_PM();
        TransformTime();
        DisplayTime();
        //DateSecond(set);//set=0 >> GotoDate , set=1 >> GotoSecond , set>1 >> GotoTime

        if (Button1 == 0){hold = 1;}
        if (Button1 == 1 && hold == 1)
        {
          hold = 0;
          set++;
        /////////////
if(set==0) convert = GotoDate;
if(set==1) convert = GotoSecond;
        ///////////
          if (set > 1)
          {
              delay_ms(2);
              convert = GotoTime;  //Goto Time in Interrupt
              break;
          }
        }
        //-----------------------------//
        if (set >= 1)
        {
          if (Button2 == 1) //---Second = 0
          {
              second = 0;
              SaveTime();  //---Save Time
          }
        }
    }
}

• دالة حفظ الزمن هى دالة كتابة إلى الشريحة ds1307 بعد تحويل البيانات المحدثة من النظام العشرى إلى النظام الثنائى المكود عشرى :

الكود:

//----Save Time & Date for Change------------------//
void SaveTime()
{
    i2c1_start();
    i2c1_wr(0xd0);
    i2c1_wr(0);

    i2c1_wr(dec2bcd(second));
    i2c1_wr(dec2bcd(minute));
    i2c1_wr(dec2bcd(hour));
    i2c1_wr(dec2bcd(day));
    i2c1_wr(dec2bcd(date));
    i2c1_wr(dec2bcd(month));
    i2c1_wr(dec2bcd(year));
    i2c1_stop();
}

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

شرح ساعة وقت وتاريخ تستخدم  PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة   Empty رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة

مُساهمة من طرف Admin في الجمعة سبتمبر 13, 2019 1:02 pm

2- المفتاح Button2 :
فى البداية يعمل مثل المفتاح Button1 حتى يتم استدعاء دالة قائمة تغيير الزمن والتاريخ والعام MenuChangeTime .


الكود:

if (Button1 == 0 && Button2 == 0){hold = 1;}

//Button2////////////////////////////
        if (Button2 == 1 && hold == 1)
        {
          hold = 0;
          convert = GotoTime;  //Goto Time in Interrupt
          MenuChangeTime();

////////////////////////////////////////////////////////////////////////////////////////////////////
//----Change Time & Date for Button2----------------------//
void MenuChangeTime()
{
    char set;
    set = 0;
    while(1)
    {
        DisplayTime();// update after off for flashing item 
        SetChangeTime(set);////flashing item >>> set=0:hour, set=1:minute, set=2:date, set=3:month, set=4:year

        if (Button2 == 0){hold = 1;}
        if (Button2 == 1 && hold == 1)
        {
          hold = 0;
          set ++;
       
          if (set > 4)  //Save Time
          {
              convert = GotoTime;  //Goto Time in Interrupt
              second = 0;
              SaveTime();
              break;
          }
       
          if (set > 1) convert = GotoDate;  //Goto Interrupt
          if (set > 3) convert = GotoYear;  //Goto Interrupt
        }
      
        if (Button1 == 1)      //Time & Date ++
        {
          //SetChangeTime(set);//flashing item >>> set=0:hour, set=1:minute, set=2:date, set=3:month, set=4:year
          ChangeTime(set, 0); //Time & Date ++ sccording to set value : hr, min , date ,....
        }

        if (Button3 == 1)  //No Save, Goto Normal Time
        {
          convert = GotoTime;  //Goto Time in Interrupt
          break;
        }
    }
}

//////////////////////////////////////////////////////////////////////////////////////
 

• فى بداية هذه الدالة يتم إعلان متغير عداد القائمة set وتصفيره والدخول إلى حلقة غير منتهية .

الكود:
 //----Change Time & Date for Button2----------------------//
void MenuChangeTime()
{
    char set;
    set = 0;
    while(1)
    {

• فى هذه الحلقة يتم استدعاء دالة عرض الزمن DisplayTime() لتحديث العنصر المعروض لتوصيل بياناته بعد عمل عملية فصلها لنحصل على وميض العنصر المطلوب بالدالة SetChangeTime(set)

الكود:
DisplayTime();// update after off for flashing item 

SetChangeTime(set);////flashing item >>> set=0:hour, set=1:minute, set=2:date, set=3:month, set=4:year

• عند الضغط على المفتاح Button2 يتم زيادة عداد القائمة set بواحد عند كل ضغطة

الكود:
  if (Button2 == 0){hold = 1;}
        if (Button2 == 1 && hold == 1)
        {
          hold = 0;
          set ++;

• تبعا لقيمة المتغير set ( تساوى القيمة 1 أو 2 أو 3 أو 4 ) يتم اتخاذ القرارات وفقا للدالة SetChangeTime(set) حيث يتم فصل العنصر المحدد والتأخير لمدة 500 ملى ثانية ثم إعادة توصيله بالدالة DisplayTime() لنحصل على وميض هذا العنصر (الساعات على سبيل المثال)

الكود:
//----Change Time & Date for Button2----------------------//
void SetChangeTime(char set)
{
    switch(set)
    {
        case 0:
            hour_d1 = hour_d2 = 0xff;    delay_us(500);
            break;
        case 1:
            minute_d1 = minute_d2 = 0xff; delay_us(500);
            break;
        case 2:
            date_d1 = date_d2 = 0xff;    delay_us(500);
            break;
        case 3:
            month_d1 = month_d2 = 0xff;  delay_us(500);
            break;
        case 4:
            year_d3 = year_d4 = 0xff;    delay_us(500);
            break;
    }

• إذا كانت set > 4 يتم العودة لعرض الزمن (ساعة ودقيقة) ، وتصفير الثوانى second وحفظ التغيرات والخروج من الحلقة الغير منتهية .

الكود:
if (set > 4)  //Save Time
          {
              convert = GotoTime;  //Goto Time in Interrupt
              second = 0;
              SaveTime();
              break;
          }

• إما إذا حدث أثناء الوميض (set =1 : set =4) أن تم الضغط على المفتاح Button1 فإنه يتم إستدعاء دالة تغيير العنصر المعروض ChangeTime لزيادة قيمته بواحد عند كل ضغطة :

الكود:
            if (set > 1) convert = GotoDate;  //Goto Interrupt
          if (set > 3) convert = GotoYear;  //Goto Interrupt
        }
      
        if (Button1 == 1)      //Time & Date ++
        {
          //SetChangeTime(set);//flashing item >>> set=0:hour, set=1:minute, set=2:date, set=3:month, set=4:year
          ChangeTime(set, 0); //Time & Date ++ sccording to set value : hr, min , date ,....
        }

• فى أى لحظة يتم فيها الضغط على المفتاح Button3 يتم العودة لعرض الزمن (ساعة ودقائق) من دون حفظ التغييرات والخروج من الحلقة الغير منتهية :

الكود:
 if (Button3 == 1)  //No Save, Goto Normal Time
        {
          convert = GotoTime;  //Goto Time in Interrupt
          break;
        }


////////////////////////////////////////////////////////////////////////////////////////////////////////
المفتاح Button3 والمفتاح Button4 تعمل بالطريقة العادية :
• الضغط على المفتاح Button3 يعرض الزمن (الساعة والدقائق) .
• الضغط على المفتاح Button4 يعرض العام year .

الكود:
if (Button3 == 1)
        {
          convert = GotoTime;  //Goto Time in Interrupt
        }
      /////////////////////
        if (Button4 == 1)
        {
          convert = GotoYear;  //Goto Year in Interrupt
          delay_ms(10);
        }

Admin
Admin

عدد المساهمات : 1187
تاريخ التسجيل : 28/01/2014

https://fathallaabdelaziz.forumarabia.com

الرجوع الى أعلى الصفحة اذهب الى الأسفل

الرجوع الى أعلى الصفحة


 
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى