شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 1 من اصل 1
شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
[SIZE="4"]شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة وتقنيات البرمجة بلغة السى مع المترجم ميكروسى برو وبرنامج المحاكاة بروتيس
المرجع :
https://www.mediafire.com/file/hozzp495cy8yta1/ClockHand-7Seg.rar/file[/SIZE]
المرجع :
https://www.mediafire.com/file/hozzp495cy8yta1/ClockHand-7Seg.rar/file[/SIZE]
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
مقدمة :
خطوات تنفيذ البرنامج (الخوارزمية) :
بعد إعدادات المنافذ والمقاطعة وتهيئة الناقل 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 يؤدى إلى عرض السنة .
خطوات تنفيذ البرنامج (الخوارزمية) :
بعد إعدادات المنافذ والمقاطعة وتهيئة الناقل 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 يؤدى إلى عرض السنة .
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
أولا : الإعلان عن المتغيرات العمومية Global واستخدام موجه قبل المعالج #define فى تعريف بعض الثوابت بأسماء ذات معنى :
ملاحظات :
• جميع المتغيرات صغيرة الحجم ولذلك يتم إعلانها من نوع الحرف char ، كما يمكن استخدام النوع unsigned short فكلاهما بحجم واحد بايت أى مداه 0-255 .
• عبارة التوجيه #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 لا تنتهى بفاصلة منقوطة .
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
ثانيا : الدالة الرئيسية 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.
دالة الكتابة إلى الشريحة DS1307 :
هذه الدالة وسائطها المتغيرات المحلية 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( .
أ- فى البداية يتم :
• إعداد وتهيئة منافذ الميكروكونترولر : المنفذ 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( .
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
ب- الحلقة الغير منتهية :
يمكن تقسيم ما بداخل الحلقة الغير منتهية إلى قسمين
القسم الأول : قسم إنشاء الساعة ، والقسم الثانى : قسم مفاتيح التحكم .
القسم الأول : قسم إنشاء الساعة :
1- نبدأ بدالة قرأء بيانات الزمن والتاريخ ReadI2C() من الشريحة DS1307 من خلال الناقل I2C وتكون بالشكل الثنائى المكود عشرى BCD :
خطوات قراءة الزمن والتاريخ :
• إصدار حالة البدء 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 أى يمكن الوصول إليها ومعالجتها من جميع الدوال .
يمكن تقسيم ما بداخل الحلقة الغير منتهية إلى قسمين
القسم الأول : قسم إنشاء الساعة ، والقسم الثانى : قسم مفاتيح التحكم .
القسم الأول : قسم إنشاء الساعة :
- الكود:
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 أى يمكن الوصول إليها ومعالجتها من جميع الدوال .
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
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;
}
}
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
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);
}
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
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 .
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
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)
وهكذا نكون قد وصلنا إلى نهاية القسم الأول وحصلنا على عرض للزمن (ساعة ودقيقة) .
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
القسم الثانى : استخدام المفاتيح للتحكم فى العرض
يحتوى البرنامج على أربعة مفاتيح : المفتاح Button1 يعمل بنظام القائمة لعرض التاريخ (يوم وشهر) ، وعرض الثوانى ، والعودة لعرض الزمن (ساعة ودقائق) . والمفتاح Button2 يساعد فى عملية ضبط الساعة وهو يعمل أيضا بنظام القائمة لعرض كل من الزمن والتاريخ والعام فى شكل وامض لتغييرها عن طريق المفتاح Button1 ، وحفظ التغييرات . والمفتاح Button3 لعرض الزمن أو الخروج من عملية ضبط الساعة من دون حفظ التغييرات . والمفتاح Button4 لعرض العام year .
1- المفتاح Button1 :
• فى الحالة الابتدائية يكون دخل كل من المفتاح Button1 و Button2 فى الحالة المنخفضة ويتم تذكر هذه الحالة بجعل المتغير hold=1 :
• عند الضغط على المفتاح Button1 يتحقق شرط العبارة :
نتيجة لذلك يتم تصفير المتغير hold=0 ثم يتم :
أ- عرض بيانات التاريخ (يوم وشهر) . لاحظ إضافة العدد 128 لإضاءة ليد النقط العشرية DP لتوضيح العرض:
ب- بعد ذلك يتم الدخول إلى دالة عرض قائمة التاريخ والثوانى :
فى هذه الدالة يتم إعلان متغير العداد set وتعينه بالصفر (تصفيره)
char set;
ثم الدخول إلى حلقة غير منتهية وفيها يتم :
• تحديث البيانات باستدعاء دوال إنشاء الساعة :
• عند الضغط على المفتاح Button1 يتم تزايد العداد set بواحد وبناء على ذلك يتم اتخاذ القرارات :
1- إذا كان set=0 يتم عرض التاريخ Date .
2- إذا كان set=1 أى الضغطة التالية يتم عرض الثوانى Second .
3- إذا كانت set>1 إى بعد الضغطة التالية يتم العودة لعرض الزمن والخروج من الحلقة الغير منتهية .
4- إذا كانت set>=1 وتم الضغط على المفتاح Button2 يتم تصفير الثوانى وحفظ الزمن والتاريخ والسنة .
• دالة حفظ الزمن هى دالة كتابة إلى الشريحة ds1307 بعد تحويل البيانات المحدثة من النظام العشرى إلى النظام الثنائى المكود عشرى :
يحتوى البرنامج على أربعة مفاتيح : المفتاح 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();
}
رد: شرح ساعة وقت وتاريخ تستخدم PIC16F877A و DS1307 و السفن سيجمنت مع المقاطعة
2- المفتاح Button2 :
فى البداية يعمل مثل المفتاح Button1 حتى يتم استدعاء دالة قائمة تغيير الزمن والتاريخ والعام MenuChangeTime .
• فى بداية هذه الدالة يتم إعلان متغير عداد القائمة set وتصفيره والدخول إلى حلقة غير منتهية .
• فى هذه الحلقة يتم استدعاء دالة عرض الزمن DisplayTime() لتحديث العنصر المعروض لتوصيل بياناته بعد عمل عملية فصلها لنحصل على وميض العنصر المطلوب بالدالة SetChangeTime(set)
• عند الضغط على المفتاح Button2 يتم زيادة عداد القائمة set بواحد عند كل ضغطة
• تبعا لقيمة المتغير set ( تساوى القيمة 1 أو 2 أو 3 أو 4 ) يتم اتخاذ القرارات وفقا للدالة SetChangeTime(set) حيث يتم فصل العنصر المحدد والتأخير لمدة 500 ملى ثانية ثم إعادة توصيله بالدالة DisplayTime() لنحصل على وميض هذا العنصر (الساعات على سبيل المثال)
• إذا كانت set > 4 يتم العودة لعرض الزمن (ساعة ودقيقة) ، وتصفير الثوانى second وحفظ التغيرات والخروج من الحلقة الغير منتهية .
• إما إذا حدث أثناء الوميض (set =1 : set =4) أن تم الضغط على المفتاح Button1 فإنه يتم إستدعاء دالة تغيير العنصر المعروض ChangeTime لزيادة قيمته بواحد عند كل ضغطة :
• فى أى لحظة يتم فيها الضغط على المفتاح Button3 يتم العودة لعرض الزمن (ساعة ودقائق) من دون حفظ التغييرات والخروج من الحلقة الغير منتهية :
////////////////////////////////////////////////////////////////////////////////////////////////////////
المفتاح Button3 والمفتاح Button4 تعمل بالطريقة العادية :
• الضغط على المفتاح Button3 يعرض الزمن (الساعة والدقائق) .
• الضغط على المفتاح Button4 يعرض العام year .
فى البداية يعمل مثل المفتاح 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);
}
مواضيع مماثلة
» ساعة وبيان درجة الحرارة وتقنية برمجة DS1307-DS18B20-LCD-PIC16F876
» تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects
» المدخل المباشر للتعامل مع وحدات السفن سيجمنت بطريقة Multiplexing من خلال تدريبات متعددة ومتدرجة
» الناقل 2IC وساعة التوقيت الحقيقى DS1307 ومشاريع الساعات الرقمية :
» المؤقتات والمقاطعة والميكروكونترولر PIC16F877A مع المترجم CCS C :
» تدريبات ومشاريع الأردوينو Arduino Tutorials and Projects
» المدخل المباشر للتعامل مع وحدات السفن سيجمنت بطريقة Multiplexing من خلال تدريبات متعددة ومتدرجة
» الناقل 2IC وساعة التوقيت الحقيقى DS1307 ومشاريع الساعات الرقمية :
» المؤقتات والمقاطعة والميكروكونترولر PIC16F877A مع المترجم CCS C :
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 1 من اصل 1
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى