كيفية البدء فى عمل شاشة ليد ماتريكس ناجحة والبرمجة بلغة السى مع المترجم ميكروسى برو :
صفحة 1 من اصل 1
كيفية البدء فى عمل شاشة ليد ماتريكس ناجحة والبرمجة بلغة السى مع المترجم ميكروسى برو :
كيفية البدء فى عمل شاشة ليد ماتريكس ناجحة والبرمجة بلغة السى مع المترجم ميكروسى برو :
عرض متحرك :
وإلى التفاصيل
عرض متحرك :
وإلى التفاصيل
الفكرة العامة :
الفكرة العامة :
الفكرة العامة تشبه إلى حد كبير العرض المرئى (السينيمائى) ، والذى يتكون من شريط كبير يحتوى على العديد من المناظر ، يتم عرضها منظر (صورة أو إطار) تلو الآخر وبسرعة لتشكيل الحركة . وكل ما علينا هو "تشكيل" بعض الصور (الإطارات) وعرضها بسرعة . كيف يتم ذلك ، هذا هو الموضوع .
فى البداية يجب أن يكون لديك مصفوفتان :
المصفوفة الأولى : تكون مصفوفة ثابتة وتحتوى على عناصر تمثل الرسالة المطلوب عرضها ، حيث أن كل حرف من الأحرف يمكن تمثيله بخريطة من نقط قد تكون فى شكل مصفوفة 5x7 أو فى شكل مصفوفة 8x8 أو أى شكل آخر . هنا سوف نبدأ بحرف واحد وليكن الحرف (A) ، المصفوفة التى تمثل هذا الحرف سوف تكون بالشكل التالى :
المصفوفة الثانية : تكون مصفوفة متغيرة ، تسمى مصفوفة المخزن المؤقت buffer وعناصرها تمثل صورة (إطار) للشاشة وسوف يتم تغيير (تحديث update) محتوياتها بشكل مستمر للحصول على صور تلو الأخرى ، كما سوف نرى لاحقا ، ونظرا لأن الشاشة ، كبداية ، مكونة من وحدة ليد ماتريكس 8x8 فإن هذه المصفوفة سوف تحتوى على 8 عناصر كما يلى :
ملخص الخطوات :
الخطوة الأولى :
مسح جميع بايتات مصفوفة المخزن المؤقت buffer الذى يمثل صورة لشاشة الليد ماتريكس ، وذلك لضمان عدم وجود أى بيانات سابقة غير مرغوب فيها .
الخطوة الثانية :
تشكيل صورة (إطار) تلو الأخرى عن طريق تحديث بيانات المخزن المؤقت بالبيانات الموجودة فى مصفوفة المخزن الثابت (الرسالة المطلوب عرضها) والتى تمثل بايتات التمثيل النقطى للحروف font ويتم هذا التحديث فى الخطوات التالية :
• إزاحة جميع عناصر (بايتات)مصفوفة المخزن المؤقت لموقع واحد جهة اليسار ، بغرض بداية عملية التحريك جهة اليسار (للغة الإنجليزية) ، فيخلو آخر موقع من البيانات .
• نقل أول عنصر (بايت) من المخزن الثابت ووضعه فى آخر موقع لمصفوفة المخزن المؤقت . لنحصل على مصفوفة مخزن مؤقت تمثل صورة أو إطار يحتوى على بايت بيانات موجود فى آخر موقع .
• تنفيذ عملية مسح scanning الأعمدة وعرض هذه الصورة (توصيل عامود تلو الآخر وعرض البيانات المرتبطة به )، فيظهر كما فى الشكل التالى :
لعلك لاحظت أن بداية ظهور العرض تكون من بداية الشاشة وجهة اليسار .
• نكرر ما سبق لكل بايت من بايتات الرسالة ، وعند نقل بايت تتولد صورة (إطار) جديدة يتم عرضها ، وتكون النتائج كما يلى :
اختيار الأجهزة (الهادوير) :
الفكرة العامة تشبه إلى حد كبير العرض المرئى (السينيمائى) ، والذى يتكون من شريط كبير يحتوى على العديد من المناظر ، يتم عرضها منظر (صورة أو إطار) تلو الآخر وبسرعة لتشكيل الحركة . وكل ما علينا هو "تشكيل" بعض الصور (الإطارات) وعرضها بسرعة . كيف يتم ذلك ، هذا هو الموضوع .
فى البداية يجب أن يكون لديك مصفوفتان :
المصفوفة الأولى : تكون مصفوفة ثابتة وتحتوى على عناصر تمثل الرسالة المطلوب عرضها ، حيث أن كل حرف من الأحرف يمكن تمثيله بخريطة من نقط قد تكون فى شكل مصفوفة 5x7 أو فى شكل مصفوفة 8x8 أو أى شكل آخر . هنا سوف نبدأ بحرف واحد وليكن الحرف (A) ، المصفوفة التى تمثل هذا الحرف سوف تكون بالشكل التالى :
- الكود:
font [8]={0xfc,0xfe,0x11,0x11,0xfe,0xfc,0x00,0x00};
المصفوفة الثانية : تكون مصفوفة متغيرة ، تسمى مصفوفة المخزن المؤقت buffer وعناصرها تمثل صورة (إطار) للشاشة وسوف يتم تغيير (تحديث update) محتوياتها بشكل مستمر للحصول على صور تلو الأخرى ، كما سوف نرى لاحقا ، ونظرا لأن الشاشة ، كبداية ، مكونة من وحدة ليد ماتريكس 8x8 فإن هذه المصفوفة سوف تحتوى على 8 عناصر كما يلى :
- الكود:
buffer[8];
ملخص الخطوات :
الخطوة الأولى :
مسح جميع بايتات مصفوفة المخزن المؤقت buffer الذى يمثل صورة لشاشة الليد ماتريكس ، وذلك لضمان عدم وجود أى بيانات سابقة غير مرغوب فيها .
- الكود:
buffer[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
الخطوة الثانية :
تشكيل صورة (إطار) تلو الأخرى عن طريق تحديث بيانات المخزن المؤقت بالبيانات الموجودة فى مصفوفة المخزن الثابت (الرسالة المطلوب عرضها) والتى تمثل بايتات التمثيل النقطى للحروف font ويتم هذا التحديث فى الخطوات التالية :
• إزاحة جميع عناصر (بايتات)مصفوفة المخزن المؤقت لموقع واحد جهة اليسار ، بغرض بداية عملية التحريك جهة اليسار (للغة الإنجليزية) ، فيخلو آخر موقع من البيانات .
- الكود:
buffer[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
• نقل أول عنصر (بايت) من المخزن الثابت ووضعه فى آخر موقع لمصفوفة المخزن المؤقت . لنحصل على مصفوفة مخزن مؤقت تمثل صورة أو إطار يحتوى على بايت بيانات موجود فى آخر موقع .
- الكود:
buffer[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC };
• تنفيذ عملية مسح scanning الأعمدة وعرض هذه الصورة (توصيل عامود تلو الآخر وعرض البيانات المرتبطة به )، فيظهر كما فى الشكل التالى :
لعلك لاحظت أن بداية ظهور العرض تكون من بداية الشاشة وجهة اليسار .
• نكرر ما سبق لكل بايت من بايتات الرسالة ، وعند نقل بايت تتولد صورة (إطار) جديدة يتم عرضها ، وتكون النتائج كما يلى :
- الكود:
buffer[]={0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0xFE };
- الكود:
buffer[]={0x00,0x00,0x00,0x00,0x00,0xFC,0xFE,0x11 };
- الكود:
buffer[]={0x00,0x00,0x00,0x00,0xFC,0xFE,0x11,0x11 };
- الكود:
buffer[]={0x00,0x00,0x00,0xFC,0xFE,0x11,0X11,0xFE };
- الكود:
buffer[]={0x00,0x00,0xFC,0xFE,0x11,0X11,0xFE,0xFC };
- الكود:
buffer[]={0x00,0xFC,0xFE,0x11,0X11,0xFE,0xFC,0x00 };
- الكود:
buffer[]={0xFC,0xFE,0x11,0X11,0xFE,0xFC,0x00,0x00 };
اختيار الأجهزة (الهادوير) :
اختيار الأجهزة (الهادوير) :
اختيار الأجهزة (الهادوير) :
فى البداية سوف نستخدم الميكروكونترولر PIC16F628A لرخص لتوفره ولرخص سعره ولأنه يحقق جميع متطلبات مرحلة البداية . على الرغم من أننا بدأنا بشاشة تتكون من وحدة واحدة 8x8 إلا أن الميكروكونترولر PIC16F628A لا يستطيع بمفرده توفير إمكانية لعرض ، بسبب قلة أطراف الدخل / الخرج ، وحتى مع استخدام الميكروكونترولر الأكبر ينبغى علينا استخدام دوائر متكاملة مساعدة لتقليل عدد الأطراف اللازمة للشاشة .
فى البداية سوف نستخم المنفذ PORTB بالكامل لإرسال بيانات الصفوف الثمانية ، وسوف نستخدم مسجل الإزاحة 74164 للتحكم فى مسح الأعمدة ، وهو ما سوف يسهل عمل توسعة للشاشة مستقبلا .
مسجلات الإزاحة shift registers تعتبر جزء مهم من إلكترونيات المنطق الرقمى ، فهى بمثابة اللاصق الموجود بين عالم البيانات التسلسلية وعالم البيانات المتوازية . فهى تقلل من عدد الأسلاك (الخطوط) ، ومن ثم عدد الأطراف المستخدمة ، وحتى أنها تساعد على تخفيف الحمل عن وحدة المعالجة المركزية من خلال قدرتها على تخزين بياناتها .
تأتى مسجلات الإزاحة فى أحجام ونماذج مختلفة من أجل الاستخدامات المختلفة . والآن ، سوف نناقش الدائرة المتكاملة 74HC164 وهى : مسجل إزاحة ، 8 بت ، دخل تسلسلى ، خرج متوازى ، بدون مزلاج (ماسك) . لماذا ؟ حسنا . السبب أنه واحد من أبسط سجلات الإزاحة المتاحة ، والذى يجعل تعلمه أسهل .
لمحة سريعة على سجل الإزاحة 74HC164 :
الرقم “74” يعنى أنه من العائلة المنطقية “74XX” ، وحيث أنه منطقى فهو لا يمكنه التحكم المباشر فى تيار كبير ( إجمالى تيار الشريحة 16-20mA ) ، فهو فقط يمرر الإشارات ، ولكن ذلك هذه الإشارات يمكنها تشغيل ترانزستورات من أجل الأحمال ذات التيار المرتفع .
الرقم “HC” يعنى سرعة مرتفعة ، ولكن كل ما مطلوب منك معرفته حوله هو أنه جهاز منخفض القدرة ويعمل على جهد من 2 إلى 5 فولت . أيضا يمكنه العمل بشكل جيد عند السرعات المرتفعة .
الرقم “164” هو رقم الموديل لهذه الشريحة .
فمسجل الإزاحة 74164 هو مسجل إزاحة 8 بت نوع "دخل تسلسلى ، خرج متوازى" يتم إشعاله بحافة نبضة . يتم إدخال البيانات تسلسليا من خلال أحد الدخلين DSA أو DSB ، يمكن استخدام أى من الدخلين ليكون فعال فى الحالة المرتفعة HIGH من أجل تمكين إدخال البيانات من المدخل الآخر . يجب توصيل المدخلين معا أو ربط المدخل الغير مستخدم بالجهد المرتفع .
يتم زحزحة البيانات بمكان واحد جهة اليمين عند كل انتقال من الجهد المنخفض إلى الجهد المرتفع LOW-to-HIGH لدخل الساعة clock (CP) ويخرج من الخرج Q0 .
المستوى المنخفض على طرف دخل الإعادة master reset (MR) يؤدى إلى تخطى جميع المداخل ومسح جميع البيانات وإجبار جميع المخارج لكى تكون على المستوى المنخفض LOW .
فيما يلى تمثيل حركى لاستخدام مسجل الأزاحة 74164 :
فى البداية سوف نستخدم الميكروكونترولر PIC16F628A لرخص لتوفره ولرخص سعره ولأنه يحقق جميع متطلبات مرحلة البداية . على الرغم من أننا بدأنا بشاشة تتكون من وحدة واحدة 8x8 إلا أن الميكروكونترولر PIC16F628A لا يستطيع بمفرده توفير إمكانية لعرض ، بسبب قلة أطراف الدخل / الخرج ، وحتى مع استخدام الميكروكونترولر الأكبر ينبغى علينا استخدام دوائر متكاملة مساعدة لتقليل عدد الأطراف اللازمة للشاشة .
فى البداية سوف نستخم المنفذ PORTB بالكامل لإرسال بيانات الصفوف الثمانية ، وسوف نستخدم مسجل الإزاحة 74164 للتحكم فى مسح الأعمدة ، وهو ما سوف يسهل عمل توسعة للشاشة مستقبلا .
مسجلات الإزاحة shift registers تعتبر جزء مهم من إلكترونيات المنطق الرقمى ، فهى بمثابة اللاصق الموجود بين عالم البيانات التسلسلية وعالم البيانات المتوازية . فهى تقلل من عدد الأسلاك (الخطوط) ، ومن ثم عدد الأطراف المستخدمة ، وحتى أنها تساعد على تخفيف الحمل عن وحدة المعالجة المركزية من خلال قدرتها على تخزين بياناتها .
تأتى مسجلات الإزاحة فى أحجام ونماذج مختلفة من أجل الاستخدامات المختلفة . والآن ، سوف نناقش الدائرة المتكاملة 74HC164 وهى : مسجل إزاحة ، 8 بت ، دخل تسلسلى ، خرج متوازى ، بدون مزلاج (ماسك) . لماذا ؟ حسنا . السبب أنه واحد من أبسط سجلات الإزاحة المتاحة ، والذى يجعل تعلمه أسهل .
لمحة سريعة على سجل الإزاحة 74HC164 :
الرقم “74” يعنى أنه من العائلة المنطقية “74XX” ، وحيث أنه منطقى فهو لا يمكنه التحكم المباشر فى تيار كبير ( إجمالى تيار الشريحة 16-20mA ) ، فهو فقط يمرر الإشارات ، ولكن ذلك هذه الإشارات يمكنها تشغيل ترانزستورات من أجل الأحمال ذات التيار المرتفع .
الرقم “HC” يعنى سرعة مرتفعة ، ولكن كل ما مطلوب منك معرفته حوله هو أنه جهاز منخفض القدرة ويعمل على جهد من 2 إلى 5 فولت . أيضا يمكنه العمل بشكل جيد عند السرعات المرتفعة .
الرقم “164” هو رقم الموديل لهذه الشريحة .
فمسجل الإزاحة 74164 هو مسجل إزاحة 8 بت نوع "دخل تسلسلى ، خرج متوازى" يتم إشعاله بحافة نبضة . يتم إدخال البيانات تسلسليا من خلال أحد الدخلين DSA أو DSB ، يمكن استخدام أى من الدخلين ليكون فعال فى الحالة المرتفعة HIGH من أجل تمكين إدخال البيانات من المدخل الآخر . يجب توصيل المدخلين معا أو ربط المدخل الغير مستخدم بالجهد المرتفع .
يتم زحزحة البيانات بمكان واحد جهة اليمين عند كل انتقال من الجهد المنخفض إلى الجهد المرتفع LOW-to-HIGH لدخل الساعة clock (CP) ويخرج من الخرج Q0 .
المستوى المنخفض على طرف دخل الإعادة master reset (MR) يؤدى إلى تخطى جميع المداخل ومسح جميع البيانات وإجبار جميع المخارج لكى تكون على المستوى المنخفض LOW .
فيما يلى تمثيل حركى لاستخدام مسجل الأزاحة 74164 :
الدائرة الكهربية :
الدائرة الكهربية :
وصف الدائرة :
تتكون دائرة الاختبار من الميكروكونترولر PIC16F628A والذ يعمل على تردد 4MHz (ساعة داخلية أو ساعة خارجية) ، يتم توصيل أطراف المنفذ PORTB إلى أطراف الكاثودات المشتركة لوحدة الليد ماتريكس (الصفوف )خلال مقاومات تحديد التيار المناسبة ، كما يتم توصيل الطرف RA0 إلى مدخل الساعة لمسجل الإزاحة 74164 وتوصيل الطرف RA1 إلى طرف البيانات التسلسلية DS .
يتم توصيل طرف الأعادة العمومى MR إلى الجهد المرتفع لعدم استخدام خاصية الإعادة ، وبالتالى تمكين مسجل الإزاحة من العمل العادى .
يتم توصيل أطراف خرج مسجل الإزاحة إلى أطرااف الأنودات المشتركة (الأعمدة) .
وصف الدائرة :
تتكون دائرة الاختبار من الميكروكونترولر PIC16F628A والذ يعمل على تردد 4MHz (ساعة داخلية أو ساعة خارجية) ، يتم توصيل أطراف المنفذ PORTB إلى أطراف الكاثودات المشتركة لوحدة الليد ماتريكس (الصفوف )خلال مقاومات تحديد التيار المناسبة ، كما يتم توصيل الطرف RA0 إلى مدخل الساعة لمسجل الإزاحة 74164 وتوصيل الطرف RA1 إلى طرف البيانات التسلسلية DS .
يتم توصيل طرف الأعادة العمومى MR إلى الجهد المرتفع لعدم استخدام خاصية الإعادة ، وبالتالى تمكين مسجل الإزاحة من العمل العادى .
يتم توصيل أطراف خرج مسجل الإزاحة إلى أطرااف الأنودات المشتركة (الأعمدة) .
العملية الأساسية هى عملية مسح الشاشة Scanning The Display :
العملية الأساسية هى عملية مسح الشاشة Scanning The Display :
تقنية هذا النوع من الشاشات تستخدم ظاهرة دوام الرؤية POV كأداة لإعطاء عرض لصورة وهمية (خداع بصرى) .
الآن ، عندما يكون لدينا ليد ماتريكس يكون لدينا خياران :
الخيار الأول : تقنية مسح الأعمدة بمعنى : تشغيل عامود column واحد فى كل مرة ، مع عرض (تواجد) نموذج الليدات الموصلة on وغير الموصلة off على صفوف هذا العامود ، وإعطائها بعض الوقت لترك أثر للصورة على أعيننا ، ثم بعد ذلك يتم إيقاف تشغيل العامود الأول والانتقال إلى تشغيل العامود الثانى ، ويتم تكرار نفس العملية مرة أخرى ومرة أخرى .
الخيار الثانى : تقنية مسح الصفوف ، يمكننا استخدام مسح الصفوف بنفس الكيفية ، بدلا من مسح الأعمدة .
كلا التقنيتين جيد على حد سواء .
التدريب الأساسى :
فى البداية سوف نطلق أسماء سهلة ومعبرة على أطراف الميكروكونترولر ، وذلك باستخدام التوجيه #define كما يلى :
وكما ذكرت ، يجب أن يكون لدينا مصفوفة ثابتة font تحتوى على بيانات بايتات التمثيل النقطى لحروف الرسالة ، وسوف نبدأ بحرف واحد فقط هو الحرف “A” ، ومصفوفة المخزن المؤقت buffer والتى تحتوى على بتات بيانات إطار (صورة) يتم تحدبثها بصفة مستمرة للحصول على التأثير الحركى :
الخطوة الأولى : إنشاء دالة مسح عناصر مصفوفة المخزن المؤقت buffer :
مسح جميع عناصر مصفوفة المخزن المؤقت لضمان عدم وجود بيانات سابقة غير مرغوب فيها ، ومن المضل برمجيا وضع هذا الجزء فى دالة منفصلة كما يلى :
فى هذه الدالة تجد حلقة for تتكرر 8 مرات ، فى كل مرة يتم مسح عنص (بايت) من العناصر الثمانية لمصفوفة المخزن المؤقت .
الخطوة الثانية : إنشاء دالة لزحزحة جميع عناصر مصفوفة المخزن المؤقت بموقع واحد جهة اليسار :
فى هذه الدالة يتم نقل كل عنصر من عناصر مصفوفة المخزن المؤقت إلى مكان العنصر الذى يليه ، وتكون المحصلة زحزحة مكونات الصورة (الإطار) جهة اليسار مع تفريغ محتويات العنصر الأخير استعدادا لملوه بابايتالذى عليه الدور فى عملية تحديث الإطار .
الخطوة الثالثة : إنشاء دالة مسح وعرض محتويات المخزن المؤقت buffer أى الصورة (الإطار) :
فى هذه الدالة يتم تنفيذ ما سبق شرحه فى عملية مسح الأعمدة وعرض بيانات الصفوف وفقا للهارد وير المسخدم :
• نبدأ بوضع جهد مرتفع على طرف البيانات DS=1 .
ثم نقوم بتشكيل حلقة for تتكرر 8 مرات ، فى كل مرة :
• يتم إعطاء نبضة ساعة CLK (تنتقل من الحالة الابتدائية المنخفضة إلى الحالة المرتفعة ثم تعود إلى الحالة الابتدائية المنخفضة مرة أخرى ) يلى ذلك التأكيد على مسح خط البيانات DS ، والغرض تشغيل عامود معين فى كل دورة .
• بعد تشغيل العامود يتم عرض بيانات الصفوف المقابلة لهذا العامود ، بعد عكسها ، باستخدام العامل (~) ، لأنه سوف يتم إرسالها إلى أطراف الكاثود المشترك بوحدة الليد ماتريكس .
• بعد ذلك يتم وضع تأخير زمنى قصير كافى لرؤية بياات العامود ضمن الصورة الكاملة .
بعد انتهاء حقلة المسح وعرض محتويات المخزن المؤقت يتم إطفاء الشاشة لحظيا لمنع تداخل الصور المتتابعة .
ملحوظة :
عملية المسح السابقة يجب تكرارها عدد من المرات حتى نحصل على عرض مستقر ، وللتحكم فى سرعة العرض ، لذلك يمكن تعديل الدالة السابقة لتصبح بالشكل التالى :
الخطوة الخامسة : استخدام الدوال السابقة لإنشاء دالة تحديث بيانات المخزن المؤقت من المخزن الدائم :
الآن إلى الدالة الرئيسية :
تقنية هذا النوع من الشاشات تستخدم ظاهرة دوام الرؤية POV كأداة لإعطاء عرض لصورة وهمية (خداع بصرى) .
الآن ، عندما يكون لدينا ليد ماتريكس يكون لدينا خياران :
الخيار الأول : تقنية مسح الأعمدة بمعنى : تشغيل عامود column واحد فى كل مرة ، مع عرض (تواجد) نموذج الليدات الموصلة on وغير الموصلة off على صفوف هذا العامود ، وإعطائها بعض الوقت لترك أثر للصورة على أعيننا ، ثم بعد ذلك يتم إيقاف تشغيل العامود الأول والانتقال إلى تشغيل العامود الثانى ، ويتم تكرار نفس العملية مرة أخرى ومرة أخرى .
الخيار الثانى : تقنية مسح الصفوف ، يمكننا استخدام مسح الصفوف بنفس الكيفية ، بدلا من مسح الأعمدة .
كلا التقنيتين جيد على حد سواء .
التدريب الأساسى :
فى البداية سوف نطلق أسماء سهلة ومعبرة على أطراف الميكروكونترولر ، وذلك باستخدام التوجيه #define كما يلى :
- الكود:
#define CLK PORTA.B0
#define DS PORTA.B1
وكما ذكرت ، يجب أن يكون لدينا مصفوفة ثابتة font تحتوى على بيانات بايتات التمثيل النقطى لحروف الرسالة ، وسوف نبدأ بحرف واحد فقط هو الحرف “A” ، ومصفوفة المخزن المؤقت buffer والتى تحتوى على بتات بيانات إطار (صورة) يتم تحدبثها بصفة مستمرة للحصول على التأثير الحركى :
- الكود:
unsigned char FONT[8]={0xFC,0xFE,0x11,0x11,0xFE,0xFC,0x00,0x00};
unsigned char buffer[8];
الخطوة الأولى : إنشاء دالة مسح عناصر مصفوفة المخزن المؤقت buffer :
مسح جميع عناصر مصفوفة المخزن المؤقت لضمان عدم وجود بيانات سابقة غير مرغوب فيها ، ومن المضل برمجيا وضع هذا الجزء فى دالة منفصلة كما يلى :
- الكود:
void clear_buffer()
{
unsigned char i;
for(i=0;i<8;i++) buffer[i]=0; //clear 8 bytes
}
فى هذه الدالة تجد حلقة for تتكرر 8 مرات ، فى كل مرة يتم مسح عنص (بايت) من العناصر الثمانية لمصفوفة المخزن المؤقت .
الخطوة الثانية : إنشاء دالة لزحزحة جميع عناصر مصفوفة المخزن المؤقت بموقع واحد جهة اليسار :
- الكود:
void shift_buffer()//moves the data one place to the left to give the "movement" effect
{
unsigned char i;
for(i=0;i<8;i++)
{
buffer[i]=buffer[i+1];
}
}
فى هذه الدالة يتم نقل كل عنصر من عناصر مصفوفة المخزن المؤقت إلى مكان العنصر الذى يليه ، وتكون المحصلة زحزحة مكونات الصورة (الإطار) جهة اليسار مع تفريغ محتويات العنصر الأخير استعدادا لملوه بابايتالذى عليه الدور فى عملية تحديث الإطار .
الخطوة الثالثة : إنشاء دالة مسح وعرض محتويات المخزن المؤقت buffer أى الصورة (الإطار) :
- الكود:
void frame_scan()
{
unsigned char i;
DS=1; //put 1 on data pin
for(i=0;i<8;i++)//from byte 0 to byte 7
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
فى هذه الدالة يتم تنفيذ ما سبق شرحه فى عملية مسح الأعمدة وعرض بيانات الصفوف وفقا للهارد وير المسخدم :
• نبدأ بوضع جهد مرتفع على طرف البيانات DS=1 .
ثم نقوم بتشكيل حلقة for تتكرر 8 مرات ، فى كل مرة :
• يتم إعطاء نبضة ساعة CLK (تنتقل من الحالة الابتدائية المنخفضة إلى الحالة المرتفعة ثم تعود إلى الحالة الابتدائية المنخفضة مرة أخرى ) يلى ذلك التأكيد على مسح خط البيانات DS ، والغرض تشغيل عامود معين فى كل دورة .
• بعد تشغيل العامود يتم عرض بيانات الصفوف المقابلة لهذا العامود ، بعد عكسها ، باستخدام العامل (~) ، لأنه سوف يتم إرسالها إلى أطراف الكاثود المشترك بوحدة الليد ماتريكس .
• بعد ذلك يتم وضع تأخير زمنى قصير كافى لرؤية بياات العامود ضمن الصورة الكاملة .
بعد انتهاء حقلة المسح وعرض محتويات المخزن المؤقت يتم إطفاء الشاشة لحظيا لمنع تداخل الصور المتتابعة .
ملحوظة :
عملية المسح السابقة يجب تكرارها عدد من المرات حتى نحصل على عرض مستقر ، وللتحكم فى سرعة العرض ، لذلك يمكن تعديل الدالة السابقة لتصبح بالشكل التالى :
- الكود:
void frame_scan()
{
unsigned char i ,n, speed=25;
//=======================
for(n=0;n<= speed;n++) //Repeat 25 times to obtain steady display , speed of display
{
DS=1; //put 1 on data pin
for(i=0;i<8;i++)//from byte 0 to byte 7
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
}
الخطوة الخامسة : استخدام الدوال السابقة لإنشاء دالة تحديث بيانات المخزن المؤقت من المخزن الدائم :
- الكود:
void buffer_update()
{
unsigned char index;
//update display frame for each FONT[index] byte ,so we have 8 frames
for(index=0;index<8;index++)
{
shift_buffer();
buffer[7]= FONT[index];//put first character in last buffer location
frame_scan();
}
}//end of display frame buffer update
الآن إلى الدالة الرئيسية :
- الكود:
void main()
{
TRISA=0;
TRISB=0;
while(1)
{
clear_buffer();
buffer_update()
}//while end
}//main end
البرنامج :
البرنامج :
- الكود:
//======================
#define CLK PORTA.B0
#define DS PORTA.B1
//=====================
unsigned char FONT[8]={0xFC,0xFE,0x11,0x11,0xFE,0xFC,0x00,0x00};
unsigned char buffer[8];
//========================
void clear_buffer()
{
unsigned char i;
for(i=0;i<8;i++) buffer[i]=0; //clear 8 bytes
}
//=================================
void shift_buffer()//moves the data one place to the left to give the "movement" effect
{
unsigned char i;
for(i=0;i<8;i++)
{
buffer[i]=buffer[i+1];
}
}
//==========================
void frame_scan()
{
unsigned char i ,n, speed=25;
//=======================
for(n=0;n<= speed;n++) //Repeat 25 times to obtain steady display , speed of display
{
DS=1; //put 1 on data pin
for(i=0;i<8;i++)//from byte 0 to byte 7
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
}
//=====================
void buffer_update()
{
unsigned char index;
//update display frame for each FONT[index] byte ,so we have 8 frames
for(index=0;index<8;index++)
{
shift_buffer();
buffer[7]= FONT[index];//put first character in last buffer location
frame_scan();
}
}//end of display frame buffer update
//=========================
void main()
{
TRISA=0;
TRISB=0;
while(1)
{
clear_buffer();
buffer_update();
}//while end
}//main end
خطوة إلى لأمام : توسعة ساشة الليد ماتريكس
خطوة إلى لأمام : توسعة ساشة الليد ماتريكس
توسعة شاشة الليد ماتريكس تعنى ، من حيث الهاردوير ، زيادة عدد وحدات الليد ماتريكس وبالتالى عدد الدوائر المتكاملة 74164 نظرا لزيادة عدد الأعمدة بثمانى أعمدة لكل وحدة إضافية ، أما ن حيث البرمجة فإن مصفوفة المخزن المؤقت سوف تزداد بثمانى عناصر لكل وحدة .
لتعميم التوسعة نفترض أن الشاشة مطلوب أن تحتوى على عدد من الأعمدة (عدد الوحدات مضروب فى 8 ) قيمته NC ، فإن مصفوفة المخزن المؤقت buffer ( ومن ثم إطار الصورة) يجب أن تحتوى أيضا على NC عنصر وترتيب هذه العناصر index يبدأ من الصفر وينتهى بالعنصر (NC-1) ، وفيما يلى مثال لشاشة مكونة من 2 وحدة ليد ماتريكس ، من ثم يصبح البرنامج بالشكل التالى :
نتيجة المحاكاة :
توسعة شاشة الليد ماتريكس تعنى ، من حيث الهاردوير ، زيادة عدد وحدات الليد ماتريكس وبالتالى عدد الدوائر المتكاملة 74164 نظرا لزيادة عدد الأعمدة بثمانى أعمدة لكل وحدة إضافية ، أما ن حيث البرمجة فإن مصفوفة المخزن المؤقت سوف تزداد بثمانى عناصر لكل وحدة .
لتعميم التوسعة نفترض أن الشاشة مطلوب أن تحتوى على عدد من الأعمدة (عدد الوحدات مضروب فى 8 ) قيمته NC ، فإن مصفوفة المخزن المؤقت buffer ( ومن ثم إطار الصورة) يجب أن تحتوى أيضا على NC عنصر وترتيب هذه العناصر index يبدأ من الصفر وينتهى بالعنصر (NC-1) ، وفيما يلى مثال لشاشة مكونة من 2 وحدة ليد ماتريكس ، من ثم يصبح البرنامج بالشكل التالى :
- الكود:
//======================
#define CLK PORTA.B0
#define DS PORTA.B1
//=====================
#define NC 16 //// Numbers of display columns
//======================
unsigned char FONT[32]=
{
0xFF, 0xFF, 0x09, 0x09, 0x0F, 0x06, 0x00, 0x00,//P
0x00, 0x00, 0x81, 0xFF, 0xFF, 0x81, 0x00, 0x00,//I
0x1C, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00,//C
};
//==================================
unsigned char buffer[NC];
//========================
void clear_buffer()
{
unsigned char i;
for(i=0;i<NC;i++) buffer[i]=0; //clear NC bytes index from 0 to NC-1
}
//=================================
void shift_buffer()//moves the data one place to the left to give the "movement" effect
{
unsigned char i;
for(i=0;i<NC;i++) // index from 0 to NC-1
{
buffer[i]=buffer[i+1];
}
}
//==========================
void frame_scan()
{
unsigned char i ,n, speed=25;
//=======================
for(n=0;n<= speed;n++) //Repeat 25 times to obtain steady display , speed of display
{
DS=1; //put 1 on data pin
for(i=0;i<NC;i++)//from byte 0 to byte NC-1 , index from 0 to NC-1
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
}
//=====================
void buffer_update()
{
unsigned char index;
//update display frame for each FONT[index] byte ,so we have 8 frames
for(index=0;index<32;index++)
{
shift_buffer();
buffer[NC-1]= FONT[index];//put first character in last buffer location , index NC-1
frame_scan();
}
}//end of display frame buffer update
//=========================
void main()
{
CMCON=7;
TRISA=0;
TRISB=0;
while(1)
{
clear_buffer();
buffer_update();
}//while end
}//main end
//=======================================
نتيجة المحاكاة :
مثال لشاشة مكونة من 8 وحدات ليد ماتريكس
فيما يلى مثال لشاشة مكونة من 8 وحدات ليد ماتريكس :
لعلك لاحظت بعض العيوب ، منها على سبيل المثال التحكم فى السرعة غير منتظم ، نتيجة لاستخدام تقنية مسح الأعمدة ، فمع زيادة عدد الأعمدة يزداد معدل زمن المسح وتقل سرعة العرض ، كذلك التباعد بين الحروف . وسوف يتم علاج السرعة باستخدام المقاطعة للحصول على معدل مسح ثابت ، أو استخدام مسح الصفوف أو كلاهما معا ، أما مشكلة علاج تباعد الحروف فسوف يتم علاجها باستخدام مصفوفة خريط نقط الحروف نوع 5X7 أو 6x8 أو غيرها .
- الكود:
//======================
#define CLK PORTA.B0
#define DS PORTA.B1
//=====================
#define NC 64 //// Numbers of display columns
//======================
unsigned char FONT[80]=
{
0xFF, 0xFF, 0x09, 0x09, 0x0F, 0x06, 0x00, 0x00,//P
0x00, 0x00, 0x81, 0xFF, 0xFF, 0x81, 0x00, 0x00,//I
0x1C, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00,//C
0xFF, 0x02, 0x04, 0x08, 0x04, 0x02, 0xFF, 0x00,//M
0x00, 0x00, 0x81, 0xFF, 0xFF, 0x81, 0x00, 0x00,//I
0x1C, 0x3E, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00,//C
0xFF, 0x19, 0x29, 0x49, 0x89, 0x86, 0x00, 0x00,//R
0x1C, 0x22, 0x41, 0x41, 0x41, 0x22, 0x1C, 0x00, //O
};
//==================================
unsigned char buffer[NC];
//========================
void clear_buffer()
{
unsigned char i;
for(i=0;i<NC;i++) buffer[i]=0; //clear NC bytes index from 0 to NC-1
}
//=================================
void shift_buffer()//moves the data one place to the left to give the "movement" effect
{
unsigned char i;
for(i=0;i<NC;i++) // index from 0 to NC-1
{
buffer[i]=buffer[i+1];
}
}
//==========================
void frame_scan()
{
unsigned char i ,n, speed=2;
//=======================
for(n=0;n<= speed;n++) //Repeat 25 times to obtain steady display , speed of display
{
DS=1; //put 1 on data pin
for(i=0;i<NC;i++)//from byte 0 to byte NC-1 , index from 0 to NC-1
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
}
//=====================
void buffer_update()
{
unsigned char index;
//update display frame for each FONT[index] byte ,so we have 8 frames
for(index=0;index<80;index++)
{
shift_buffer();
buffer[NC-1]= FONT[index];//put first character in last buffer location , index NC-1
frame_scan();
}
}//end of display frame buffer update
//=========================
void main()
{
CMCON=7;
TRISA=0;
TRISB=0;
while(1)
{
clear_buffer();
buffer_update();
}//while end
}//main end
لعلك لاحظت بعض العيوب ، منها على سبيل المثال التحكم فى السرعة غير منتظم ، نتيجة لاستخدام تقنية مسح الأعمدة ، فمع زيادة عدد الأعمدة يزداد معدل زمن المسح وتقل سرعة العرض ، كذلك التباعد بين الحروف . وسوف يتم علاج السرعة باستخدام المقاطعة للحصول على معدل مسح ثابت ، أو استخدام مسح الصفوف أو كلاهما معا ، أما مشكلة علاج تباعد الحروف فسوف يتم علاجها باستخدام مصفوفة خريط نقط الحروف نوع 5X7 أو 6x8 أو غيرها .
استخدام جدول حروف كود أسكى كمخزن ثابت لجميع الحروف القابلة للكتابة
والآن لنتقدم خطوة أخرى إلى الأمام : استخدام جدول حروف كود أسكى كمخزن ثابت لجميع الحروف القابلة للكتابة ، بغرض كتابة وعرض أى رسالة .
فى هذه الحالة ، ينحصر التغيير فى الرسالة ومصفوفة الحروف الثابتة:
الرسالة تكون على شكل سلسة نصية ، وهى مصفوفة حروف وتكون ، على سبيل المثال بالشكل التالى :
بمجرد أن يقابل المترجم أقواس الاقتباس المزدوجة يعرف أن ما بينها هو سلسلة من الحروف فيتعرف عليها (فى شكل قيمة عددية لكود أسكى) وعلى عددها وعلى بدايتها وعلى نهايتها ويقوم بوضع حرف النهاية لها وحو الحرف (\0) .
نتيجة لذلك يمكن تحديد عدد الحروف باستخدام العبارة التالية :
كل حرف يتكون من 5 بايت ، يمكن الوصول إلى بيانات الحروف الموجود بالرسالة ومعالجتها كما تم معالجة المصفوفة الثابتة السابقة التعيين عن طريق عملية حسابية بسيطة :
أول حرف فى جدول أسكى هو مسافة فارغة وقيمته العددية هى “32” ، وبالتالى يمكن الوصول إلى ترتيب الحرف داخل جدول آسكى بطرح قيمة أسكى لهذا الحرف من القيمة “32” . على سبيل المثال حرف “A” قيمة أسكى له هى القيمة “65” فيكون ترتيبه index فى جدول أسكى هو(‘A’-32) أى “65-32=33” . من عند هذا الترتيب يبدأ الخمسة بايتات الخاصة بهذا الحرف وبالتالى يمكن تعيين بداية رتب الخمسة أحرف الخاصة بكل حرف بالشكل التالى :
نتيجة لهذا التعديل يصبح لبرنامج بالشكل التالى :
فى هذه الحالة ، ينحصر التغيير فى الرسالة ومصفوفة الحروف الثابتة:
الرسالة تكون على شكل سلسة نصية ، وهى مصفوفة حروف وتكون ، على سبيل المثال بالشكل التالى :
- الكود:
unsigned char message[]="PIC MICROCONTROLLER " ;
// define string array , as you wish , depends on memory
بمجرد أن يقابل المترجم أقواس الاقتباس المزدوجة يعرف أن ما بينها هو سلسلة من الحروف فيتعرف عليها (فى شكل قيمة عددية لكود أسكى) وعلى عددها وعلى بدايتها وعلى نهايتها ويقوم بوضع حرف النهاية لها وحو الحرف (\0) .
نتيجة لذلك يمكن تحديد عدد الحروف باستخدام العبارة التالية :
- الكود:
number_of_characters = strlen(message);
كل حرف يتكون من 5 بايت ، يمكن الوصول إلى بيانات الحروف الموجود بالرسالة ومعالجتها كما تم معالجة المصفوفة الثابتة السابقة التعيين عن طريق عملية حسابية بسيطة :
أول حرف فى جدول أسكى هو مسافة فارغة وقيمته العددية هى “32” ، وبالتالى يمكن الوصول إلى ترتيب الحرف داخل جدول آسكى بطرح قيمة أسكى لهذا الحرف من القيمة “32” . على سبيل المثال حرف “A” قيمة أسكى له هى القيمة “65” فيكون ترتيبه index فى جدول أسكى هو(‘A’-32) أى “65-32=33” . من عند هذا الترتيب يبدأ الخمسة بايتات الخاصة بهذا الحرف وبالتالى يمكن تعيين بداية رتب الخمسة أحرف الخاصة بكل حرف بالشكل التالى :
- الكود:
index=message[character]-32; // character index
index=index*5; // first byte index
نتيجة لهذا التعديل يصبح لبرنامج بالشكل التالى :
- الكود:
//==============================
#include "FONT.H"//const unsigned char FONT[] , ASCII TABLE , reserve 96 character x 5 bytes = 480 bytes , use 5 byte pattern to save program memory
//======================
#define CLK PORTA.B0
#define DS PORTA.B1
//=====================
#define NC 32 //// Numbers of display columns
//======================
//==================================
unsigned char message[]="PIC MICROCONTROLLER " ; // define string array , as you wish , depends on memory
//==========================
unsigned char buffer[NC];
//==============
unsigned char index,number_of_characters,character,speed=5;
//=====================
void clear_buffer()
{
unsigned char i;
for(i=0;i<NC;i++) buffer[i]=0; //clear NC bytes index from 0 to NC-1
}
//================
void shift_buffer()//moves the data one place to the left to give the "movement" effect
{
unsigned char i;
for(i=0;i<NC;i++) // index from 0 to NC-1
{
buffer[i]=buffer[i+1];
}
}
//============
void frame_scan()
{
unsigned char i,n;
//=======================
for(n=0;n<= speed;n++) //Repeat 25 times to obtain steady display , speed of display
{
DS=1; //put 1 on data pin
for(i=0;i<NC;i++)//from byte 0 to byte NC-1 , index from 0 to NC-1
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
}
//===========
void buffer_update()
{
unsigned char new_index;
//character display frame for each FONT[index] byte ,so we have 8 frames
for(new_index=index;new_index<index+5;new_index++)
{
shift_buffer();
buffer[NC-1]= FONT[new_index];//put first character in last buffer location , index NC-1
frame_scan();
}
}//end of display frame buffer character
//=======================
void main()
{
CMCON=7;
TRISA=0;
TRISB=0;
//========
number_of_characters = strlen(message);
while(1)
{
clear_buffer();
for(character=0;character<number_of_characters;character++)
{
index=message[character]-32;
index=index*5; // first byte index
buffer_update();
}
}
}
//==============================
الآن نغلف جميع دوال البرنامج فى دالة واحدة تحتوى على بارامتر واحد هو سرعة العرض speed :
وأخيرا وبعد أن عرفنا أجزاء ودوال البرنامج ، الآن نغلف جميع دوال البرنامج فى دالة واحدة تحتوى على بارامتر واحد هو سرعة العرض speed :
- الكود:
//==============================
#include "FONT.H"//const unsigned char FONT[] , ASCII TABLE , reserve 96 charecter x 5 bytes = 480 bytes , use 5 byte pattern to save program memory
//======================
#define CLK PORTA.B0
#define DS PORTA.B1
//=====================
#define NC 32 //// Numbers of display columns
//==================================
unsigned char message[]="PIC MICROCONTROLLER " ; // define string array , as you wish , depends on memory
//==========================
unsigned char buffer[NC];
//==============
void clear_buffer();
void shift_buffer();
void ptint_message(unsigned char speed);
//========================
void main()
{
CMCON=7;
TRISA=0;
TRISB=0;
//========
while(1)
{
ptint_message(5);
}
}
//======================
//===========================
void clear_buffer()
{
unsigned char i;
for(i=0;i<NC;i++) buffer[i]=0; //clear NC bytes index from 0 to NC-1
}
//================
void shift_buffer()//moves the data one place to the left to give the "movement" effect
{
unsigned char i;
for(i=0;i<NC;i++) // index from 0 to NC-1
{
buffer[i]=buffer[i+1];
}
}
//=======================
void ptint_message(unsigned char speed)
{
unsigned char index,new_index,number_of_characters,character,n,i;
//=====clear buffer==================
clear_buffer();
//=======================
number_of_characters = strlen(message);
//=============================
for(character=0;character<number_of_characters;character++)
{
index=message[character]-32;
index=index*5; // first byte index
//=========update frame after each byte for each character =====
for(new_index=index;new_index<index+5;new_index++)
{
shift_buffer();
buffer[NC-1]= FONT[new_index];//put first character in last buffer location , index NC-1
//=======================
for(n=0;n<=speed;n++) //Repeat speed times to obtain steady display , speed of display
{
DS=1; //put 1 on data pin
for(i=0;i<NC;i++)//from byte 0 to byte NC-1 , index from 0 to NC-1
{
CLK=1; CLK=0; DS=0;// clock pulse and clear data
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
delay_ms(1);
}
PORTB=0xFF; //ones to OFF all led common cathodes 8 rows
}
}
}
}
//================================
والآن خطوة قصيرة إلى الأمام : استخدام الدائرة المتكاملة ULN2803 لتوفير التيار اللازم لتشغيل الشاشة :
والآن خطوة قصيرة إلى الأمام : استخدام الدائرة المتكاملة ULN2803 لتوفير التيار اللازم لتشغيل الشاشة :
http://www.mediafire.com/download/u8rxkuyt5ndazr1/6-MY-MIKROC-64X8-LED-MATRIX-16F628-74164-final.zip
فيما يلى مثال لشاشة ليد ماتريكس مكونة من 6 وحدات 8X8 ، كل ما عليك هو :
• تغيير عدد الأعمدة ليكون NC=48 .
• إزالة عامل الانعكاس ( ~ ) فى العبارة :
لتكون :
وذلك لأن الدائرة المتكاملة ULN2803 سوف تقوم بهذه المهمة .
http://www.mediafire.com/download/u8rxkuyt5ndazr1/6-MY-MIKROC-64X8-LED-MATRIX-16F628-74164-final.zip
فيما يلى مثال لشاشة ليد ماتريكس مكونة من 6 وحدات 8X8 ، كل ما عليك هو :
• تغيير عدد الأعمدة ليكون NC=48 .
• إزالة عامل الانعكاس ( ~ ) فى العبارة :
- الكود:
PORTB=~ buffer[i]; // inverse and send buffer data byte to PORTB
لتكون :
- الكود:
PORTB= buffer[i]; send buffer data byte to PORTB
وذلك لأن الدائرة المتكاملة ULN2803 سوف تقوم بهذه المهمة .
خطوة متقدمة : استخدام مسجل الإزاحة 74595 فى عملية انتخاب الأعمدة وفى إرسال بيانات الصفوف :
خطوة متقدمة : استخدام مسجل الإزاحة 74595 فى عملية انتخاب الأعمدة وفى إرسال بيانات الصفوف :
باتباع نفس النهج السابق ، ومع معرفة خصائص مسجل الإزاحة 74595 والفرق بينه ومسجل الأزاحة يمكننا البدء فى إنشاء شاشة ليد ماتريكس 8X8 قابلة للتوسعة ، فقط بزيادة عدد عناصر مصفوفة المخزن المؤقت كما يلى :
باتباع نفس النهج السابق ، ومع معرفة خصائص مسجل الإزاحة 74595 والفرق بينه ومسجل الأزاحة يمكننا البدء فى إنشاء شاشة ليد ماتريكس 8X8 قابلة للتوسعة ، فقط بزيادة عدد عناصر مصفوفة المخزن المؤقت كما يلى :
- الكود:
#include "font.h"
//===================
#define LOW 0
#define HIGH 1
//====================
#define DATA_columns PORTA.F0
#define CLK_columns PORTA.F1
#define LAT_columns PORTA.F2
//================================
#define DATA_rows PORTB.F0
#define CLK_rows PORTB.F1
#define LAT_rows PORTB.F2
//=================================
#define rows_clock CLK_rows=HIGH; CLK_rows=LOW;
#define rows_latch LAT_rows=HIGH; LAT_rows=LOW;
//================================
#define columns_clock CLK_columns=LOW; CLK_columns=HIGH;
#define columns_latch LAT_columns=LOW; LAT_columns=HIGH;
//===========================
#define NC 8 // Numbers of display columns
//==================================
unsigned char message[]="PIC " ; // define string array , as you wish , depends on memory
//==========================
unsigned char buffer[NC];
//===============================
void clear_buffer();
void display_buffer(unsigned char scroll_speed);
void send_data(unsigned char byte_data);
void print_message(unsigned char speed);
//=======================
void main()
{
CMCON=7;
TRISA=0;
TRISB=0;
while(1)
{
print_message(50);
}
}
//========================
void clear_buffer()
{
unsigned char i;
for(i=0;i<NC;i++)
{
buffer[i]=0;
}
}
//=========================
//send byte data serially bit by bit to rows via rows shift register
void send_data(unsigned char byte_data)
{
unsigned char i;
for(i=0;i<8;i++)
{
DATA_rows=byte_data&1;
rows_clock;
byte_data=byte_data>>1 ;
}
rows_latch;
}
//===============================
void display_buffer(unsigned char scroll_speed)
{
unsigned char i,j;
for(i=0;i<scroll_speed;i++)//display one frame speed times
{
DATA_columns=HIGH; columns_clock; columns_latch; //only for first column to put 1
for(j=0;j<NC;j++)
{
send_data(~buffer[j]);
delay_ms(1);
DATA_columns=LOW; columns_clock; columns_latch; // for other columns
send_data(0xFF);
}
}
}
//===============================
void print_message(char speed)
{
unsigned char index,new_index,number_of_characters,update,character,i;
//=====clear buffer==================
clear_buffer();
//=======================
number_of_characters = strlen(message);
//=============================
for(character=0;character<number_of_characters;character++)
{
index=message[character]-32;
index=index*5;
//==========================
for(new_index=index;new_index<index+5;new_index++)
{
//=======shift=============
for(i=0;i<NC;i++)
{
buffer[i]=buffer[i+1];
}
//----------transfer------------
buffer[NC-1]=font[new_index];//Last element
//====display===========
display_buffer(speed);
}
}
//==============================
}
//=====================
مثال لشاشة ليد ماتريكس مكونة من 4 وحدات 8X8 :
مثال لشاشة ليد ماتريكس مكونة من 4 وحدات 8X8 :
- الكود:
#include "font.h"
//===================
#define LOW 0
#define HIGH 1
//====================
#define DATA_columns PORTA.F0
#define CLK_columns PORTA.F1
#define LAT_columns PORTA.F2
//================================
#define DATA_rows PORTB.F0
#define CLK_rows PORTB.F1
#define LAT_rows PORTB.F2
//=================================
#define rows_clock CLK_rows=HIGH; CLK_rows=LOW;
#define rows_latch LAT_rows=HIGH; LAT_rows=LOW;
//================================
#define columns_clock CLK_columns=LOW; CLK_columns=HIGH;
#define columns_latch LAT_columns=LOW; LAT_columns=HIGH;
//===========================
#define NC 32 // Numbers of display columns
//==================================
unsigned char message[]="PIC MICRO " ; // define string array , as you wish , depends on memory
//==========================
unsigned char buffer[NC];
//===============================
void clear_buffer();
void display_buffer(unsigned char scroll_speed);
void send_data(unsigned char byte_data);
void print_message(unsigned char speed);
//=======================
void main()
{
CMCON=7;
TRISA=0;
TRISB=0;
while(1)
{
print_message(5);
}
}
//========================
void clear_buffer()
{
unsigned char i;
for(i=0;i<NC;i++)
{
buffer[i]=0;
}
}
//=========================
//send byte data serially bit by bit to rows via rows shift register
void send_data(unsigned char byte_data)
{
unsigned char i;
for(i=0;i<8;i++)
{
DATA_rows=byte_data&1;
rows_clock;
byte_data=byte_data>>1 ;
}
rows_latch;
}
//===============================
void display_buffer(unsigned char scroll_speed)
{
unsigned char i,j;
for(i=0;i<scroll_speed;i++)//display one frame speed times
{
DATA_columns=HIGH; columns_clock; columns_latch; //only for first column to put 1
for(j=0;j<NC;j++)
{
send_data(~buffer[j]);
delay_ms(1);
DATA_columns=LOW; columns_clock; columns_latch; // for other columns
send_data(0xFF);
}
}
}
//===============================
void print_message(char speed)
{
unsigned char index,new_index,number_of_characters,update,character,i;
//=====clear buffer==================
clear_buffer();
//=======================
number_of_characters = strlen(message);
//=============================
for(character=0;character<number_of_characters;character++)
{
index=message[character]-32;
index=index*5;
//==========================
for(new_index=index;new_index<index+5;new_index++)
{
//=======shift=============
for(i=0;i<NC;i++)
{
buffer[i]=buffer[i+1];
}
//----------transfer------------
buffer[NC-1]=font[new_index];//Last element
//====display===========
display_buffer(speed);
}
}
//==============================
}
//=====================
مواضيع مماثلة
» تقنيات عرض الرسائل والإعلانات على شاشات الليد ماتريكس مع المترجم CCS C والمترجم ميكروسى برو: مقدمة : مبدأ عمل شاشة العرض LED dot matrix :
» شاهد فديو إنشاء إشارة مرور ذو اتجاهين بلغة السى مع المترجم ميكروسى برو ثم استخرج مفاهيم لغة السى مع الشرح :
» الليد ماتريكس LED MATRIX علميا وعمليا والبرمجة بلغة السى والمترجم MIKROC والمترجم CCS C :
» سجل واحجز على الإنترنت دورة ميكروكونترولر PIC هاردوير وبرمجة بلغة السى مع المترجم ميكروسى والأنظمة المدمجة
» ترجمة الفصل الأول والفصل الثانى من كتاب برمجة الميكروكونترولر PIC بلغة السى مع المترجم ميكروسى برو
» شاهد فديو إنشاء إشارة مرور ذو اتجاهين بلغة السى مع المترجم ميكروسى برو ثم استخرج مفاهيم لغة السى مع الشرح :
» الليد ماتريكس LED MATRIX علميا وعمليا والبرمجة بلغة السى والمترجم MIKROC والمترجم CCS C :
» سجل واحجز على الإنترنت دورة ميكروكونترولر PIC هاردوير وبرمجة بلغة السى مع المترجم ميكروسى والأنظمة المدمجة
» ترجمة الفصل الأول والفصل الثانى من كتاب برمجة الميكروكونترولر PIC بلغة السى مع المترجم ميكروسى برو
صفحة 1 من اصل 1
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى