كود تفعيل العضوية - الابلاغ عن روابط لاتعمل - صيانة التلفزيون - الحاسبة - الأعضاء المتميزين - البرامج و المخططات - بث مباشر للقنوات الفضائية - إذاعة - تردد القنوات - بحث
|
|||||||
| التسجيل | اجعل كافة المشاركات مقروءة |
| منتدى الإلكترونيات قسم الالكترونكس لمناقشة الافكار والمعلومات المتعلقة بالهندسة الالكترونية للمبتدئين والهواة والفنيين - Electronics |
![]() |
|
|
أدوات الموضوع |
|
|
#1 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
الناقل 2IC وساعة التوقيت الحقيقى DS1307 ومشاريع الساعات الرقمية :
1- مقدمة عن الناقل 2IC : الناقل I2C (اختصار Inter-Integrated Circuit ) هو ناقل شائع الاستخدام ، وهو ناقل اتصال متزامن ( أى يوجد نبضات ساعة تزامن) يستخدم خطين (سلكين) : • الخط SDA (اختصار Serial Data Line ) : هو خط بيانات ثنائى الاتجاه . • الخط SCL (اختصار Serial Clock Line ) : هو خط ساعة التزامن ثنائى الاتجاه . ![]() يتم التحكم فى الناقل I2C عن طريق الماستر (السيد) master ( غالبا ما يكون ميكروكونترولر مثل PIC16F877A ) . قد يكون للناقل I2C أكثر من ماستر ، لكننا سوف نتناول حالة وجود ماستر واحد فقط على متن الناقل يتحكم فيه. الناقل I2C قد يكون له تابع (خادم) slave واحد أو أكثر (الناقل I2C بدون توابع لاقيمة له ) . يتم التعرف على التابع slave عن طريق عنوان متفرد يكون فى أغلب الأحيان مكون من 7 بتات 7-bit address . مثال : ساعة التوقيت الحقيقى DS1307 : Address 7 bits (1 1 0 1 0 0 0) . ملحوظة : لا يمكن أبدا أن يكون لتابعين نفس العنوان . كما أن الماستر ليس له عنوان على الإطلاق . المحادثة (التخاطب ) أى الاتصال تتم فقط بين الماستر وتابع . دائما يتم بدء الحادثة عن طريق الماستر وبإطلاقه لحالة البدء (Start condition) . فى الميكروسى برو تستخدم الدالة I2C1_Start(); لتحقيق هذا الغرض . ثم يقوم الماستر باستخدام الناقل I2C لإرسال عنوان تعريف التابع الذى يرغب فى التواصل معه . فى الميكروسى برو تستخدم الدالة I2C1_Write(0xD0); لتحقيق هذا الغرض . دائما يتم إنهاء الاتصال عن طريق الماستر وذلك بإصدارة حالة التوقف (Stop condition) . فى الميكروسى برو تستخدم الدالة I2C1_Stop(); لتحقيق هذا الغرض . يتم توليد إشارة الساعة SCL بواسطة الماستر ، والوضع القياسى لها ، وهو ما سوف نستخدمه ،هو 100 kHz (100 kilobits per second) . فى الميكروسى برو تستخدم الدالة I2C1_Init(100000); لتحقيق هذا الغرض . هذه الدالة يجب أن تكتب فى بداية البرنامج حتى يمكن استخدام باقى دوال الناقل I2C الأخرى . تنتقل البيانات من المرسل إلى المستقبل . ومن ثم يكون لدينا حالتين : • انتقال البيانات من الماستر إلى التابع : فى هذه الحالة يكون المرسل هو الماستر والمستقبل هو التابع .يتم انتقال البيانات على الخط SDA على مسافات مع تزامن الماستر من خلال خط الساعة SCL clock . • انتقال البيانات من التابع إلى الماستر : فى هذه الحالة يكون المرسل هو التابع لمستقبل هو الماستر . يضع التابع البيانات على الخط SDA على مسافات مع تزامن الماستر من خلال خط الساعة SCL clock . ملاحظة : توفر الأجهزة بت الاعتراف والتسليم بالصحة Acknowledge bit لتحقيق انتقال بيانات سلس . 2- تقنية الناقل I2C من نوع خرج مفتوح المصب أو المجمع المفتوح : مخارج الدوائر التى يتم ربطها إلى الناقل I2C هى من نوع المصب المفتوح أو المجمع المفتوح ، لذلك يتم وضع مقاومتين رفع الخطين SDA و SCL ومصدر القدرة الموجب VDD . 3- مثال للاتصال بين الماستر (PIC16F877A) والتابع (DS1307) : ساعة التوقيت الحقيقى DS1307 توفر لبثوانى ،والدقائق،والساعات ، والأيام،والتاريخ ،والشهور،والسنين مع الأخذ فى الاعتبار السنين الكبيسة ، حتى عام 2100 . الساعة DS1307 تعمل فى الوضع القياسى ( تردد نبضات خط الساعة SCL هو 100 كيلوهرتز ) . عنوان ناقل I2C ذات السبع بتات والخاص بالساعة DS1307 هو 1 1 0 1 0 0 0 ( العنوان المحدد بمعرفة الصناع ولا يمكن تغييره ) . مثال للكتابة إلى الساعة DS1307 : المرسل هو الماستر والمستقبل هة التابع . السجل الذى عنوانه 0x04 فى الساعة DS1307 يحتوى على تاريخ اليوم DATE (راجع الداتا شيت ) . الشكل التالى يوضح ذلك . ![]() لضبط تاريخ اليوم من الشهر ليكون يوم 27 ، يجب عليك كتابة البيانات 0x27 ( شفرة ثنائية مكودة عشرى BCD ) فى السجل الذى عنوانه 0x04 بالساعة DS1307 . الناقل I2C يستخدم البروتوكول التالى : ![]() 1- لبدء الاتصال ، يقوم الماستر بإنشاء حالة البدء START . 2- ثم يقوم الماستر بإرسال عنوان التابع وهو(1010100) متبوعا بالبت (0) (بت الكتابة ) ليكون البايت 0xD0 . 3- يستجيب التابع ويرد ببت معلومية وتمام وصول وتنفيذ الأمر . 4- عندئذ يقوم الماستر بإرسال عنوان السجل المطلوب الكتابة إليه وهو (0x04) . 5- يستجيب التابع ويرد ببت معلومية وتمام وصول وتنفيذ الأمر . 6- عندئذ يقوم الماستر بإرسال البيانات المطلوب كتابتها إلى السجل ،ذات العنوان سالف الذكر ، وهى بيانات تاريخ اليوم (0x27) . 7- يقوم التابع بكتابة البيانات وبعد ذلك يرسل بت تمام التنفيذ . 8- فى النهاية ، يقوم الماستر بإنهاء الاتصال بإصدار حالة التوقف STOP . أليست سهلة ؟ يمكن تنفيذ ذلك بلغة السى والمترجم ميكروسى برو كما يلى : كود:
I2C1_Init(100000); // initialize I2C communication //////////////////////////// I2C1_Start(); //1- issue I2C start signal I2C1_Wr(0xD0); // 2-3-send byte via I2C (device address + W) I2C1_Wr(0x04); // 4-5-send byte (address of DATE location) I2C1_Wr(0x27); // 6-7send data (data to be written) I2C1_Stop(); //8- issue I2C stop signal ![]() مثال على القراءة من الساعة DS1307 : فى هذه الحالة يكون المرسل هو التابع والمستقبل هو الماستر . السجلات ذات العناوين من 0x00 إلى 0x06 بالساعة تحتوى على الترتيب على بيانات : الثوانى ، والدقائق ، والساعات ، والأيام (يوم الأسبوع) ، والتواريخ (يوم الشهر) ، والأشهر ، والسنين (راجع الداتا شيت) . هنا سوف نتعرف على كيفية قراءة محتويات العناوين من 0x00 إلى 0x06 للساعة DS1307 ، ودفعة واحدة : ![]() 1- لبدء الاتصال ، يقوم الماستر بإنشاء حالة بدء START . 2- يقوم الماستر بإرسال عنوان التابع (1010100) متبوعا بالبت (0) ، (بت الكتابة) . 3- يجيب التابع ببت المعلومية . 4- يرسل الماستر عنوان السجل المطلوب قراءته (0x00) . 5- يجيب التابع بالمعلومية . 6- يعطى الماستر حالة إعادة البدء Repeated Start . 7- يرسل الماستر عنوان التابع (1010100) متبوعا بالبت (1) (بت القراءة) . 8- يجيب التابع بالمعلومية . 9- يرسل التابع محتويات السجل الذى عنوانه 0x00 إلى الماستر . 10- يجيب الماستر بالمعلومية . 11- يرسل التابع محتويات السجل الذى عنوانه 0x01 (يتزايد تلقائيا) إلى الماستر . 12- يجيب الماستر بالمعلومية . 13- يرسل التابع محتويات السجل الذى عنوانه 0x02 (يتزايد تلقائيا) إلى الماستر . 14- يجيب الماستر بالمعلومية . ......................................... .................................................. ..... 21- يرسل التابع محتويات السجل الذى عنوانه 0x06 (يتزايد تلقائيا) إلى الماستر . 22- يجيب الماستر بالمعلومية . 23- يقوم الماستر بإنهاء الاتصال بإصدار حالة التوقف STOP . فعلى فرض أن محتويات السجل 0x00 هى 0x06 فهذا يعنى 6 ثوانى . وعلى فرض أن محتويات السجل 0x01 هى 0x56 فهذا يعنى 56 دقيقة . وعلى فرض أن محتويات السجل 0x02 هى 0x09 فهذا يعنى 9 ساعات . وعلى فرض أن محتويات السجل 0x03 هى 0x03 فهذا يعنى اليوم الثالث من أيام الإسبوع أى Tuesday . وعلى فرض أن محتويات السجل 0x04 هى 0x20 فهذا يعنى اليوم العشرين من الشهر . وعلى فرض أن محتويات السجل 0x05 هى 0x05 فهذا يعنى شهر May . وعلى فرض أن محتويات السجل 0x06 هى 0x08 فهذا يعنى عام 2008 . ويكون التوقيت والتاريخ : (Tuesday, May 20, 2008, 9 hours 56 minutes and 6 seconds) كود:
I2C1_Init(100000); // initialize I2C communication //////////////////////////// I2C1_Start(); //1- issue I2C start signal I2C1_Wr(0xD0); // 2-send byte via I2C (device address + W) I2C1_Wr(00); //3- send byte (data address) I2C1_Repeated_Start(); // 6-issue I2C signal repeated start I2C1_Wr(0xD1); // 7-send byte (device address + R) PORTB = I2C1_Rd(0u); // 9-Read the data (NO acknowledge) I2C1_Stop(); //23- issue I2C stop signal تنفيذ الكود السابق فى شكل برنامج : كود:
void main() {
TRISB=0;
I2C1_Init(100000); // initialize I2C communication
////////////////////////////
while(1){
I2C1_Start(); //1- issue I2C start signal
I2C1_Wr(0xD0); // 2-send byte via I2C (device address + W)
I2C1_Wr(00); //3- send byte (data address)
I2C1_Repeated_Start(); // 6-issue I2C signal repeated start
I2C1_Wr(0xD1); // 7-send byte (device address + R)
PORTB = I2C1_Rd(0u); // 9-Read the data (NO acknowledge)
I2C1_Stop();
}
}
![]()
__________________
مقالات المهندس فتح الله عبدالعزيز |
|
|
|
| اعلانات |
|
|
#2 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
ساعة التوقيت الحقيقى DS1307 وربطها مع الميكروكونترولر PIC بغرض إنشاء ساعة رقمية :
العديد من الميكروكونترولر PIC يمتلك ضمن بنائه الداخلى ناقل I C (Inter-Integrated Circuit) . هذا الناقل هو ناقل اتصال تسلسلى متزامن يعمل بواسطة 2- سلك(خط) . بعض الأجهزة ، مثل الحساسات ، تتصل بالميكروكونترولر باستخدام هذا الناقل التسلسلى . العديد من الأجهزة ، حتى وإن كانت من أنواع مختلفة ، يمكن ربطها على نفس خطى الناقل 2IC دون أن تسبب أى خطأ . كل جهاز يمتلك عنوان تعريف متفرد وهو ما يسمح بربط العديد من الأجهزة إلى نفس الناقل I2C . سوف نستخدم ساعة التوقيت الحقيقى DS1307 والتى يمكنها الاتصال خلال الناقل I2C لضبط set (write) التوقيت والتاريخ وكذلك القراءة منها . الدائرة المتكاملة DS1307 هى ساعة توقيت وتقويم تسلسلية ذو قدرة كهربية منخفضة وتعمل بالكامل بنظام الأعداد الثنائى المكود عشرى BCD لكل من بياات التوقيت والتقويم ، بالإضافة إلى أنها تمتلك 56 بايت من ذاكرة RAM الغير متطايرة نتيجة لاستخدام بطارية احتياطية للقدرة الكهربية . يتم نقل البيانات والعنوان تسلسليا من خلال ناقل 2IC ثنائى الاتجاه وهى توفر معلومات التوقيت (الثوانى والدقائق والساعات) والتقويم ( واليوم والشهر والسنة) ، يتم تعديل بيانات تاريخ نهاية الأشهر تلقائيا للشهر الأقل من 31 يوما بما في ذلك تعويض السنة الكبيسة حتى عام 2100 ، ويمكن أن تعمل إما في شكل 24 ساعة أو فى شكل 12 ساعة مع بيان AM/PM . وهى تأتي مع دائرة مدمجة لاستشعار انقطاع التيار الكهربائي والتحويل تلقائيا إلى المصدر الاحتياطي . وتستمر عملية ضبط الوقت أثناء العمل على المصدر الاحتياطى . كما أنها تستخدم مذبذب كريستال بتردد 32.768kHz ولا تحتاج أى مقاومات أو مكثفات خارجية للعمل . الساعة DS1307 تعمل كجهاز تابع slave على الناقل I2C . يتم الوصول إليها بواسطة تنفيذ الأمر SRART مع تقديم كود تعريف الجهاز يليه عنوان سجل . بعد ذلك يمكن الوصول إلى السجلات المتتابعة حتى يتم تنفيذ أمر STOP . توصيل ناقل I2C : ![]() يتم توصيل الطرف SCL للميكروكونترولر بالطرف 6 : DS1307/ SCL وتوصيل الطرف SDA للميكروكونترولر بالطرف 5 : DS1307/ SDA يتم توصيل مقاومتى رفع ، واحدة من "خط الساعة التسلسلية" SCL والأخرى من "خط البيانات التسلسلية" SDL إلى موجب مصدر القدرة . كما يتم توصيل كريستال 32768 إلى الطرف 1 والطرف 2 للساعة DS1307 . يمكن أيضا توصيل بطارية احتياطية إلى الطرف VBAT (pin 3) ، إذا لم ترغب فى ذلك يتم توصيل هذا الطرف إلى الأرضى . يوفر المترجم ميكروسى برو مكتبة مدمجة به خاصة بأجهزة I2C . الساعة DS1307 تعمل كجهاز تابع على الناقل I2C . الوصول إلى سجلات الساعة DS1307 يمكن أن نحصل عليه بواسطة تنفيذ (استدعاء)الدالة START ونتبعها بعنوان address تعريف هوية الجهاز . بعد ذلك يمكن الوصول لكل سجل على التتابع عن طريق استخدام عنوانه حتى يتم تنفيذ الدالة STOP . عنوان الجهاز الخاص بالساعة DS1307 هو 0x68 = 1101000 (صفحة 12 من الداتا شيت ) . هناك وظيفتان شائعتان الاستخدام مع الجهاز : وظيفة تحديد القيم بالذاكرة set values (كتابة البيانات إلى الساعة DS1307 ) ووظيفة الحصول على القيم من الذاكرة get values ( قراءة البيانات من الساعة ds1307 ) سوف نستعرض الوظيفتين باستخدام الأمثلة . القيم الرقمية فى هذا الجهاز يتم تخزينها على شكل 4 بتات ، بصيغة كود ثنائى مكود عشرى BCD . سوف نحتاج للتحويل من BCD إلى ثنائى BINARY ومن ثنائى إلى BCD حتى يتم عرض وتخزين القيم فى الميكروكونترولر PIC بشكل مناسب . ![]() عملية إرسال أو كتابة البيانات للساعة Set RTC Values (ضبط الساعة): فى البداية يتم برمجة الدائرة المتكاملة بالقيم الصحيحة للتوقيت والتقويم . فى المثال التالى ، سوف نقوم بتحديد (ضبط) الدقائق . وبمجرد ضبطها فإن جميع السجلات الأخرى (ساعة، يوم ...) يمكن ضبطها باستخدام نفس الخطوات . مثال على ضبط الدقائق Setting the Minutes : فيما يلى توقيت وتتابع الاتصال عن طريق الناقل I2C : كود:
I2C1_Init(100000); //DS1307 I2C is running at 100KHz /////////////////////////// I2C1_Start(); // begin I2C communications I2C1_Wr(0xD0); // addresses the chip I2C1_Wr( 0x01 ); // access register address for minutes check table 2 above. I2C1_Wr(0b00010011 ); // write value into minutes register I2C1_Stop(); /////////////////// 1- أول شىء نقوم بعمله هو بدء الاتصال عن طريق استخدام الدالة I2C1_Start() . 2- بعد ذلك نستدعى الدالة I2C1_Wr(0xD0) : هذه هى الدالة التى عن طريقها يتم الوصول جهاز تابع محدد عن طريق شفرة تعريف عنوانه الموجودة فى السبع بتات الأعلى لبارامتر هذه الدالة ، وهى هنا 1101000 . فنظرا لأنه يمكن ربط العديد من الأجهزة على نفس الناقل I2C ، فإن هذا العنوان "يوقظ" الجهاز الصحيح . وتتابعات البيانات التالية سوف تقوم فقط بالنظر فى هذا الجهاز فقط من ضمن الأجهزة الموجودة على متن نفس الناقل . عنوان أي جهاز على الناقل I2C عادة (وليس دائما) يتكون من جزئين . الجزء الأول عبارة عن مجموعة من البتات للعنوان الداخلى . ويتكون الجزء الثاني من بتات استخدام أطراف الدائرة المتكاملة ، لكن الساعة DS1307 تمتلك عنوانها بالكامل فى داخل الشريحة . وفقا للداتا شيت ، عنوان ذات الساعة ذات سبع بتات وهو‘1101000’ . فأين البت الثامنة ؟ بعد كل بايت عنوان يتم إرسالة بمعرفة الميكروكونترولر PIC مستخدما الناقل I2C ، فإن البت الثامنة تحدد ما إذا كانت البايت التالية تكون كتابة أو قراءة بمعرفة PIC : فإذا كانت البت الثامنة صفر (0) فهذا يعنى أن البايت التالى مخصص للكتابة أما إذا كانت واحد فهذا يعنى أن البايت التالى مخصص للقراءة . هنا البت ذات الأهمية الأدنى (البت الثامن ) هى الصفر ، لذلك فإن بيانات البايت الكامل سوف تكون ‘11010000 0xD0 . 3- بعد ذلك يتم استدعاء الدالة ة I2C1_Wr(0x01) : فوفقا للجدول أعلاه ، كل سجل من سجلات الساعة DS1307 يكون له عنوان address بقيمة سداسى عشرى سجل مرتبط به . فعلى سبيل المثال ، سجل الدقائق MINUTES register يكون عنوانه 01h (or 0x01) . ولذلك ، للوصول إلى هذا السجل ، فإن PIC يكتب(يرسل) 0x01. الخلاصة الدالة تقوم بتحديد عنوان السجل المراد الكتابة إليه . 4- بعد ذلك يتم استدعاء الدالة I2C1_Wr(0b00010011) أو بالصيغة I2C1_Wr(0x13): مرة أخرى وفقا للجدول أعلاة ، سجل الدقائق MINUTES register مكون من جزئين : النبل الأدنى ( من البت bit0 إلى البت bit3 أى أربعة بتات ) والنبل العلوى ( البت bit4 إلى البت bit6 أى ثلاثة بتات ) . وكلا النبلين تستخدم معا لتمثيل أعداد برقمين double-digit numbers . على سبيل المثال ، العدد “13” مكون من رقم الآحاد “3” ورقم العشرات “1” . كل رقم يتم تخزينه فى نبل مستقل . الرقم “1” يتم تخزينه كعدد ثنائى مكود عشرى فى النبل العلوى فى حين أن العدد “3” يتم تخزينه كعدد BCD فى النبل السفلى . على سبيل المثال ، لتخزين العدد “13” ، يجب ضبط سجل الدقائق MINUTES بالشكل ‘001 0011’ بالصيغة الثنائية . الثنائى “001” هو “1” بالشكل BCD والثنائى “0011” هو "3" بالشكل BCD . ونظرا لأنه لا يوجد دقائق ثنائية الأرقام أعلى من “59” فإننا نحتاج فقط إلى 7 بتات لتمثيل أى عدد مكون من رقمين من 00 إلى 59 . 5- بعد ذلك يتم استدعاء الدالة I2C1_Stop() : بعد القيام بعمل كل شىء يمكننا غلق الناقل I2C بواسطة هذه الدالة . لقد كتبنا الرقم الثنائي 0010011 في سجل الدقائق ، يمكننا أن نكرر نفس الإجراء أو كتابة الدالة التي يمكن أن تستدعى ضبط الساعات للليوم والشهر وهلم جرا. الآن، فإن ساعة التوقيت الحقيقى سوف تتبع مسار الدقائق وبعد 59min:59sec فإن ساعة التوقيت الحقيقى سوف تقوم بتزايد سجل الساعات HOURS register ويتم الدوران 00min:00secs . أطراف الساعة الرقمية DS1307 : الساعة الرقمية DS1307 لها ثمانى أطراف كما يلى : وصف الأطراف : • الطرف SQW/OUT : طرف الموجة المربعة / وتشغيل الخرج . • الطرف SCL : طرف الساعة التسلسلية المستخدمة من أجل الاتصال IC2 . • الطرف SDA : طرف البيانات التسلسلية من أجل الاتصال التسلسلى I2C . • الطرف GND : طرف أرضى مصدر القدرة . • الطرف VBAT : طرف توصيل البطارية الاحتياطية 3V ، وتستخدم فى حالة انهيار القدرة الرئيسية . • الأطراف X1 , X2 : أطراف توصيل الكريستال 32.768 . • الطرف Vcc : طرف توصيل موجب مصدر القدرة الرئيسى . ربط الساعة الرقمية DS1307 مع الميكروكونترولر : الشكل التالى يبين المخطط الصندوقى العام لربط الساعة الرقمية مع الميكروكونترولر: ![]() في الاتصال التسلسلي I2C ، يعمل أحد الأجهزة باعتبار تابع slave ويعمل الجهاز الأخر باعتبارة السيد master . الجهاز التابع يستجيب فقط لتعليمات الجهاز السيد . الجهاز التابع لا يمكنه أن يعطي تعليمات للجهاز السيد . الساعة الرقمية DS1307 تعمل باعتبارها تابع slave وتستجيب لتعليمات الميكروكونترولر . السجلات المبنية ضمن الساعة الرقمية DS1307 تستخدم للاستجابة (الرد على ) لتعليمات الميكروكونترولر . كما هو مبين في المخطط أعلاه ، يتم توصيل الطرف SCL بالساعة DS1307 إلى الطرف SCL بالميكروكونترولر. يستخدم هذا الطرف (طرف الساعة التسلسلية) لمزامنة البيانات التسلسلية على الخط التسلسلي . كلمة SCL تعنى مدخل الساعة التسلسلية . فى حين أن الكلمة SDA تعنى طرف مدخل/مخرج البيانات التسلسلية . يتم توصيل الطرف SDA بالساعة DS1307 مع الطرف SDA بالميكروكونترولر. يستخدم الطرف SDA كمدخل للبيانات التسلسلية أو كمخرج من أجل الاتصال التسلسلى بخطين . الأطراف SDA و SCL بالساعة DS1307 هى أطراف مصب مفتوح وهذا هو سبب الاحتياج لمقاومة رفع خارجية كما هو مبين بالشكل أعلاه . يستخدم كريستال عيارى32.876KHz مع ساعة الوقت الحقيقى DS1307 .
__________________
مقالات المهندس فتح الله عبدالعزيز |
|
|
|
| احصائية الشكر والاعجاب - 1 شكراً, 0 عدم اعجاب, 1 اعجاب |
احمد شهيد جواد ( شكر العضو على هذه المشاركة )
احمد شهيد جواد ( أعجبته المشاركة )
|
|
|
| اعلانات اضافية ( قم بتسجيل الدخول لاخفائها ) | |||
|
|
|
|
#3 |
|
مشرف منتدى الهندسة الكهربائية
الدولة: IRAQ
المشاركات: 10,061
معدل تقييم المستوى: 396
|
شكرا جزيلا ....
__________________
حيدر علاج حسن
|
|
|
|
| احصائية الشكر والاعجاب - 1 شكراً, 0 عدم اعجاب, 0 اعجاب |
F.Abdelaziz ( شكر العضو على هذه المشاركة )
|
|
|
|
|
#4 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
المشروع التمهيدى لساعة التوقيت الحقيقى DS1307 :
الغرض استعراض : • كيفية التعامل مع دوال مكتبة المترجم ميكروسى . • كيفية قراءة سجلات التوقيت والتقويم من DS1307 عن طريق الميكروكونترولر . • كيفية تحويل القراءة من BCD إلى أحرف يمكن عرضه على وحدة LCD . الدائرة الكهربية : ![]() البرنامج : كود:
/*
* Interfacing DS1307 RTC
*/
// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
unsigned short read_ds1307(unsigned short address)
{
unsigned short read_data;
I2C1_Start();
I2C1_Wr(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(address);
I2C1_Repeated_Start();
I2C1_Wr(0xD1); //0x68 followed by 1 --> 0xD1
read_data=I2C1_Rd(0);
I2C1_Stop();
return(read_data);
}
////////////
unsigned char MSB(unsigned char x) //Display Most Significant Bit of BCD number
{
return ((x >> 4) + '0');
}
////////
unsigned char LSB(unsigned char x) //Display Least Significant Bit of BCD number
{
return ((x & 0x0F) + '0');
}
/////////////////////////////////
void init(){
ADCON1=0;
CMCON=7;
TRISC=0;//
////////////
I2C1_Init(100000); //DS1307 I2C is running at 100KHz
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_out(1,1,"Time:");
Lcd_out(2,1,"Date:");
}
///////////////////////////////////////////
//Global Variables:
int second;
int minute;
int hour;
int hr;
int day;
int dday;
int month;
int year;
int ap;
/////////////////////////
char time[] = "00:00:00 PM";
char date[] = "00-00-00";
////////////////////////////////
void main()
{
init();
///////////
while(1)
{
second = read_ds1307(0);//sec
minute = read_ds1307(1);//min register
hour = read_ds1307(2);//hr register
hr = hour & 0b00011111;
ap = hour & 0b00100000;
dday = read_ds1307(3);//day register
day = read_ds1307(4);//
month = read_ds1307(5);// month register
year = read_ds1307(6);//year month register
////////////////////////////////////
time[0] = MSB(hr);// char time[] = "00:00:00 PM";
time[1] = LSB(hr);
time[3] = MSB(minute);
time[4] = LSB(minute);
time[6] = MSB(second);
time[7] = LSB(second);
//////////////////////////////////
date[0] = MSB(day);// char date[] = "00-00-00";
date[1] = LSB(day);
date[3] = MSB(month);
date[4] = LSB(month);
date[6] = MSB(year);
date[7] = LSB(year);
if(ap)
{
time[9] = 'P'; //);// char time[] = "00:00:00 PM";
time[10] = 'M';
}
else
{
time[9] = 'A';
time[10] = 'M';
}
Lcd_out(1, 6, time);
Lcd_out(2, 6, date);
Delay_ms(100);
}
}
شرح أجزاء البرنامج :
__________________
مقالات المهندس فتح الله عبدالعزيز |
|
|
|
|
|
#5 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
شرح أجزاء البرنامج :
1- أعدادات توصيل وحدة العرض LCD : كود:
// LCD module connections sbit LCD_RS at RB2_bit; sbit LCD_EN at RB3_bit; sbit LCD_D4 at RB4_bit; sbit LCD_D5 at RB5_bit; sbit LCD_D6 at RB6_bit; sbit LCD_D7 at RB7_bit; sbit LCD_RS_Direction at TRISB2_bit; sbit LCD_EN_Direction at TRISB3_bit; sbit LCD_D4_Direction at TRISB4_bit; sbit LCD_D5_Direction at TRISB5_bit; sbit LCD_D6_Direction at TRISB6_bit; sbit LCD_D7_Direction at TRISB7_bit; // End LCD module connections كود:
unsigned short read_ds1307(unsigned short address)
{
unsigned short read_data;
I2C1_Start();
I2C1_Wr(0xD0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(address);
I2C1_Repeated_Start();
I2C1_Wr(0xD1); //0x68 followed by 1 --> 0xD1
read_data=I2C1_Rd(0);
I2C1_Stop();
return(read_data);
}
• الدالة التالية مباشرة هى دالة كتابة (أرسال) بايت عبر الناقل وهى I2C1_Wr(0xD0); . هذه الدالة تنبه الجهاز الذى عنوان تعريفه هو السبع بتات الأخيرة من البايت D0 وهو على وجه التحديد الجهاز DS1307 ، البت الأولى من اليمين تحدد نوع العملية القادمة ليتأهر لها الجهاز ، فإن كانت البت بصف فإن العملية القادمة تكون عملية كتابة (إرسال من الميكروكونترولر إلى DS1307 ) ، كما هو الحال فى هذه الحالة ، وإن كانت البت بواحد فهذا يعنى أن العملية القادمة هى عملية قراءة (الحصول على بيانات بايت من DS1307 إلى PIC ) . • كما توقعنا الدالة التالية هى دالة كتابة I2C1_Wr(address); وهى تحتاج لتحديد عنوان البايت المراد الكتابة عليه وهو البارامتر الموجود فى نموذج الدالة address . بهذه الطريقة نكون حددنا عنوان لبايت ، ونظرا لأننا بصدد دالة قراءة سجلات DS1307 نتوقع أن تكون الدالة التالية هى دالة قراءة ، ولكننا كنا قد نبهنا الجهاز بدالة كتابة لذلك ينبغى إعادة تنبيهه على أن القادم هى عملية قراءة . • تبدأ عملية القراءة بإعادة البدء بالدالة I2C1_Repeated_Start(); ، ثم يليها دالة الكتابة I2C1_Wr(0xD1); وآخر بت هى الواحد والتى تعنى أن العملية القادمة هى عملية قراءة . • كما توقعنا الدالة التالية read_data=I2C1_Rd(0); هى قراءة بيانات البايت المحدد عنوانه سابقا وحفظه فى المتغير read_data . الصفر (0) أنه لن يتم قراءة بايت أخر حاليا ، إذا كان المطلوب قراءة بيانات السجلات بشكل متتابع نضع واحد بدل الصفر ونليه بدوال القراءة واحدة تلو الأخرى وفى نهاية المطاف نستخدم I2C1_Rd(0); . • يتم تنبيه DS1307 بانتهاء العملية بالدالة I2C1_Stop(); . • فى النهاية نحصل على عائد هذه الدالة باستخدام التعليمة return(read_data); . بعد أن حصلنا على بيانات سجلات التوقيت والتاريخ من DS1307 سوف تقابلنا مشكلة !! وهى أن DS1307 يتعامل فقط مع البيانات بنظام الثنائى المكود عشرى BCD ، وهو ما يعنى أنه ثنائى (مكون من أصفار وآحاد) ولكن فى شكل عشرى أى آحاد وعشرات . بايت البيانات يتكون من من 8 بتات ، كل أربعة بت ، وتسمى نبل، تمثل خانة أو رقم فالأربعة بتات ذات القيمة الأدنى LSB تمثل الآحاد ، والأربعة بتات ذات القيمة الأقصى MSB تمثل رقم العشرات . على سبيل المثال ، سجل الثوانى الذى يعطى 15 SEC يتعامل معه DS1307 فى الشكل (00011001) حيث الأربعة بتات الأدنى تمثل الآحاد وهى 1001=5 والأربعة بتات العليا تمثل العشرات وهى 0001 = 1 ، فما هو الحل ؟ الحل هو أنشاء دالة لتحويل النبل الأدنى ودالة لتحويل النبل الأعلى إلى أحرف ليمكن عرضها على وحدة العرض LCD كما يلى : كود:
unsigned char MSB(unsigned char x) //Display Most Significant Bit of BCD number
{
return ((x >> 4) + '0');
}
///////////////////////////////////////////////////////////////
unsigned char LSB(unsigned char x) //Display Least Significant Bit of BCD number
{
return ((x & 0x0F) + '0');
}
يتم تحويل النبل الأعلى إلى أحرف بزحزحة بيانات البايت جهة اليمين بأربع للتخلص من النبل الأدنى ووضع النبل الأعلى فى بداية بايت العائد ، ثم إضافة حرف الصفر '0' أو العدد 48 لتحويل الرقم إلى حرف من حروف كود أسكى القابل للكتابة والعرض على وحدة LCD . ويتم تحويل النبل الأدنى إلى أحرف بإجراء عملية AND باستخدام المعامل & بين بيانات البايت والقيمة 0X0F بغرض التخلص النبل العلوى مع الحفاظ على النبل السفلى فى بداية بايت العائد ، ثم إضافة حرف الصفر '0' . بعد حل مشكلة اختلاف نوع البيانات نعود للعمل الاعتيادى : • من المفضل وضع جميع الإعدادات فى شكل دالة كما يلى : كود:
void init(){
ADCON1=0;
CMCON=7;
TRISC=0;//
////////////
I2C1_Init(100000); //DS1307 I2C is running at 100KHz
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_out(1,1,"Time:");
Lcd_out(2,1,"Date:");
}
بعد ذلك يتم إعلان المتغيرات كما يلى : كود:
//Global Variables: int second; int minute; int hour; int hr; int day; int dday; int month; int year; int ap; ///////////////////////// char time[] = "00:00:00 PM"; char date[] = "00-00-00"; //////////////////////////////// وأخيرا نصل إلى الدالة الرئيسية : نبدأ باستدعاء دالة الإعدادات Init(); ثم ننشىء حلقة غير منتهية كود:
void main()
{
Init();
///////////
while(1)
{
• قراءة بيانات جميع سجلات التوقيت والتاريخ من DS1307 بواسطة الدالة read_ds1307(0);// وفى كل مرة نضع عنوان السجل المناسب كما يلى : second = read_ds1307(0);//sec minute = read_ds1307(1);//min register hour = read_ds1307(2);//hr register hr = hour & 0b00011111; ap = hour & 0b00100000; dday = read_ds1307(3);//day register day = read_ds1307(4);// month = read_ds1307(5);// month register year = read_ds1307(6);//year month register • بعد ذلك يتم تحويل البيانات من BCD إلى أحرف كما يلى : //////////////////////////////////// كود:
time[0] = MSB(hr);// char time[] = "00:00:00 PM";
time[1] = LSB(hr);
time[3] = MSB(minute);
time[4] = LSB(minute);
time[6] = MSB(second);
time[7] = LSB(second);
//////////////////////////////////
date[0] = MSB(day);// char date[] = "00-00-00";
date[1] = LSB(day);
date[3] = MSB(month);
date[4] = LSB(month);
date[6] = MSB(year);
date[7] = LSB(year);
if(ap)
{
time[9] = 'P'; //);// char time[] = "00:00:00 PM";
time[10] = 'M';
}
else
{
time[9] = 'A';
time[10] = 'M';
}
كود:
Lcd_out(1, 6, time);
Lcd_out(2, 6, date);
Delay_ms(100);
}
}
__________________
مقالات المهندس فتح الله عبدالعزيز التعديل الأخير تم بواسطة : F.Abdelaziz بتاريخ 16-04-2016 الساعة 07:09 AM. |
|
|
|
|
|
#6 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
ملفات البرنامج والمحاكاة ببرنامج بروتيس على الرابط :
http://www.mediafire.com/download/85...ic-project.zip النتيجة : ![]()
__________________
مقالات المهندس فتح الله عبدالعزيز |
|
|
|
|
|
#7 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
المشروع الأول : ساعة بسيطة باستخدام DS1307 و PIC16F877A و LCD :
لكى يعمل المشروع بشكل صحيح فى الواقع أو فى المحاكاة ينبغى وضع بعض القيم فى DS13-7 (ضبط الساعة) قبل القراءة منها وعرض النتائج على وحدة العرض LCD أى مجرد ضبط الساعة قبل عملية القراءة . فى هذا المشروع لن نستخدم أزرار للضبط بغرض تسهيل معرفة مبادىء العمل ، وسوف نستخدم لاحقا فى المشاريع أزرار الضبط للوصول إلى ساعة عملية . علاوة على ذلك يتم توضيح فكرة استخدام طرف الخرج SOUT لتوليد موجة مربعة بتردد 1Hz . الدائرة الكهربية : الدائرة الكهربية للساعة بسيطة جدا وهى مبينة بالشكل التالى : ![]() البرنامج مزد بالتعليقات اللازمة لشرح طريقة العمل : كود:
//DS1307 RTC Interfacing with PIC16F877A
// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
/////////////////////
///// global variables////
unsigned short sec;
unsigned short minute;
unsigned short hour;
unsigned short day;
unsigned short date;
unsigned short month;
unsigned short year;
unsigned short temp;
char time[9];
char ddate[11];
//////functions ////////
//////////
unsigned short read_ds1307(unsigned short address)// address byte
{
I2C1_Start();//Determines if I²C bus is free and issues START signal.
I2C1_Wr(0xd0); //address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(address);//address of ds1307 to be read
I2C1_Repeated_Start();//to change from write condition to read condition
I2C1_Wr(0xd1); //0x68 followed by 1 --> 0xD1
temp=I2C1_Rd(0);//Reads one byte from the slave, and sends not acknowledge signal
I2C1_Stop();//Issues STOP signal
return(temp);//BCD byte
}
/////////
void write_ds1307(unsigned short address,unsigned short w_data)//address and w_data bytes
{
I2C1_Start(); // issue I2C start signal
//address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(0xD0); // send byte via I2C (device address + W)
I2C1_Wr(address); // send byte (address of DS1307 location)
I2C1_Wr(w_data); // send data (data to be written)
I2C1_Stop(); // issue I2C stop signal
}
/////////////////////////
unsigned char BCD2UpperCh(unsigned char bcd)
{
return ((bcd >> 4) + '0');//get ASCII character
}
////////
unsigned char BCD2LowerCh(unsigned char bcd)
{
return ((bcd & 0x0F) + '0');
}
///////
void init(){
I2C1_Init(100000); //DS1307 I2C is running at 100KHz
PORTB = 0;
TRISB = 0; // Configure PORTB as output
TRISC = 0xFF;
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, "TIME:");
Lcd_Out(2, 1, "DATE:");
//Set Time
write_ds1307(0,0x80); //address 0 , data 10000000 :Reset second to 0 sec. and stop Oscillator ,DS1307 TIMEKEEPER REGISTERS Figure 3
write_ds1307(1,0x06); //write min 06
write_ds1307(2,0x12); //write hour 12
write_ds1307(3,0x07); //write day of week 7:satarday
write_ds1307(4,0x16); // write date 16
write_ds1307(5,0x04); // write month 04
write_ds1307(6,0x16); // write year 16 --> 2016
write_ds1307(7,0x10); //SQWE output at 1 Hz , control address 0x07 , enable bit bit4
write_ds1307(0,0x00); //Reset second to 0 sec. and start Oscillator
}
///////main function////////////
void main(){
init();
while(1)
{
sec=read_ds1307(0); // read second
minute=read_ds1307(1); // read minute
hour=read_ds1307(2); // read hour
day=read_ds1307(3); // read day
date=read_ds1307(4); // read date
month=read_ds1307(5); // read month
year=read_ds1307(6); // read year
time[0] = BCD2UpperCh(hour);
time[1] = BCD2LowerCh(hour);
time[2] = ':';
time[3] = BCD2UpperCh(minute);
time[4] = BCD2LowerCh(minute);
time[5] = ':';
time[6] = BCD2UpperCh(sec);
time[7] = BCD2LowerCh(sec);
time[8] = '\0';
ddate[0] = BCD2UpperCh(date);
ddate[1] = BCD2LowerCh(date);
ddate[2] ='/';
ddate[3] = BCD2UpperCh(month);
ddate[4] = BCD2LowerCh(month);
ddate[5] ='/';
ddate[6] = '2';
ddate[7] = '0';
ddate[8] = BCD2UpperCh(year);
ddate[9] = BCD2LowerCh(year);
ddate[10] = '\0';
Lcd_Out(1,6,time);
Lcd_Out(2,6,ddate);
Delay_ms(50);
}
}
__________________
مقالات المهندس فتح الله عبدالعزيز |
|
|
|
|
|
#8 |
|
استاذ و مشرف قسم الالكترونيات
المشاركات: 6,894
معدل تقييم المستوى: 335
|
تحويل عدد من رقمين من BCD إلى عشرى والعكس :
لعمل ساعة رقمية بجميع الميزات سوف يتم استخدام DS1307 . فى هذه الحالة سوف نستخدم العديد من التحويلات من BCD إلى العشرى والعكس من أجل قراءة وضبط توقيت ساعة التوقيت الحقيقى DS1307 . يوفر مترجم الميكرو سى دوال مدمجة به من أجل مثل هذه التحويلات ولكن الدوال تستهلك معظم كمية حيز ذاكرة الميكروكونترولر ، لذلك يمكن إنشاء دوال بسيطة والتى تستهلك ذاكرة أقل للقيام بتحويل عدد BCD مكون من رقمين إلى عشرى والعكس . 1- دالة تحويل عدد BCD مكون من رقمين 2-digit BCD إلى عدد عشرى Decimal: كود:
unsigned short myBcd2Dec(unsigned short bcd){
return ((bcd >> 4)*10+(bcd & 0x0F));
}
Example: myBcd2Dec(01000101) = 45
الشرح : • العدد BCD المكون من رقمين ، كل رقم يمثله 4-bits ويكون الإجمالى 8-bits . • دالة التحويل مكونة من جزءين جزء العشرات وجزء الآحاد يتم جمعهما معا . كل جزء خاص بتحويل 4-bits (نبل) . • النبل العلوى يمثل رقم العشرات ولتحويله نتخلص من النبل السفلى بزحزحة العدد الكلى أربعة مواقع للحصول على العدد العشرى ثم نضربه فى 10 للحصول على قيمة العشرات (bcd >> 4)*10 . • النبل السفلى يمثل رقم الآحاد ولتحويله نتخلص من النبل العلوى بإجراء عملية AND بالعامل 7 بين العدد الكلى والعدد 0x0F (تسمى عملية تغطية mask ) لنحصل على النبل السفلى (المقابل للآحاد) دون أى تغيير وحيث أنه الآحاد يتم الضرب فى واحد (bcd & 0x0F) • فى النهاية تكون النتيجة ((bcd >> 4)*10+(bcd & 0x0F)) ففى المثال : 01000101 نتيجة الجزء الأول تكون 00000100 وهى القيمة (4) تضرب فى 10 فتكون 40 . فى حين أن نتيجة الجزء الثانى 00000101 أى القيمة (5) ويكون المجموع (45) . سهلة 1 أليست كذلك . 2- دالة تحويل عدد عشرى مكون من رقمين 2-digit Decimal إلى عدد BCD : كود:
unsigned short myDec2Bcd(unsigned short dec){
return (((dec/10)<<4)(dec%10));
}
Example: myDec2Bcd(45) = 01000101
الشرح : • نحصل على رقم الخانة العلوية بقسمة بايت العدد العشرى على 10 ونزحزح النتيجة 4 مواقع جهة اليمين (dec/10)<<4) ، ونحصل على رقم الخانة السفليى بإيجاد باقى خارج قسمة العدد العشرى على عشرة (dec%10) ، ثم نضع الجزئين بجوار بعضهما بالترتيب المناسب (dec/10)<<4)(dec%10) ملحوظة : تستخدم الأقواس ( ) فى تجميع التعبيرات ، وفصل تعبيرات الشرط ، وفى استدعاء الدوال، وفى احتواء بارامترات الدوال .
__________________
مقالات المهندس فتح الله عبدالعزيز |
|
|
|
![]() |
| العلامات المرجعية |
| أدوات الموضوع | |
|
|