ما هو الميكروكونترولر Microcontroller ؟
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 4 من اصل 5
صفحة 4 من اصل 5 • 1, 2, 3, 4, 5
رد: ما هو الميكروكونترولر Microcontroller ؟
أجهزة إستشعار المسافة Distance sensors :
تستخدم أجهزة إستشعار المسافة فى قياس طول المسافة من مكان نقطة موقع الجسم العائق obstacle إلى موقع المستشعر (الحساس) . تنفيذ هذا النوع من الأجهزة مفيد فى أنظمة التحكم وفى مشاريع الروبوتات robotics.
وكحالة محددة فأنه فى هذا الجزء سوف يتم العمل بالحساس GP2D12 (الموجود ضمن برنامج إيزيس) ، هذا الحساس يستخدم تقنية إرسال الشعاع الضوئى للأشعة تحت الحمراء واستقبال إنعكاسها لتحديد المسافة . الشكل التالى يبين المظهر الطبيعى ، والأطراف ، والرمز فى برنامج إيزيس لهذا الحساس :
مثل هذا الحساس له سلوك غير خطى nonlinear ، هذا يعنى أن الخرج ليس له دالة تحويل خطية . لفهم هذا المفهوم بوضوح الرسم البيانى التالى يبين سلوك الخرج كدالة فى المسافة :
سلوك مثل هذا الحساس صعب التنفيذ ، لأنه فى بعض الحالات لا يقدم المصنع دالة تحويل مفيدة حتى يمكن استخدامها فى شكل معادلة واحدة . وعلى الرغم من ذلك فهذا لا يشكل عقبة أمام استخدام الحساس . كما هو موضح فى الداتا شيت أن المدى المؤثر من 10 إلى 80 سنتيمتر ( Effective Range: 10 to 80 cm) كما هو مبين فى الرسم البيانى .
الرسم البيانى الموضح موجود بالداتا شيت الخاص بالجهاز ويتم تنفيذه تجريبيا (نتيجة تجارب) . لوصف سلوك الحساس والحصول على دالة التحويل من الضرورى إجراء عملية رياضية تعرف باسم "الخطية" linearization . لتحقيق هذه الغاية يتم إجراء عملية "إستيفاء" interpolation بعدد معروف من نقاط الدالة ، هذه النقاط تؤخد من القياسات التجريبية . كلما زاد عدد النقاط كلما زادت دقة تقييم دالة التحويل .
لبدء هذه العملية يتم اختيار نقطتين موزعين بالتساوى . على سبيل المثال النقطة عند مسافة 10cm والنقطة عند مسافة 80cm . لكل نقطة نكون معادلة فيكون لدينا معادلتين من الدرجة الأولى فى هذه الحالة ، حيث يتم حلهما معا وإيجاد الثوابت .
لفهم هذا المفهوم ، نفترض أن المغير المستقل x يعبر عن جهد خرج الحساس بالفولت والمتغير التابع y يعبر عن المسافة بالسنتيمتر ونعتبر أن المعادلة التالية تعبر عن سلوك الحساس :
باعتبار أن y تمثل المسافة و x تمثل جهد خرج الحساس المستخدم ومن الرسم البيانى التجريبى نحصل على :
عندئذ يمكن كتابة المعادلات :
https://i.servimg.com/u/f11/18/74/92/45/1113.jpg
ونستطيع تكوين معادلتين فى مجهولين كما يلى :
بحل المعادلين يمكن تعيين الثوابت كما يلى :
https://i.servimg.com/u/f11/18/74/92/45/1311.jpg
بهذه الطريقة يمكن وضع صيغة لدالة التحويل للحساس كما يلى :
وحيث أن المتغير x يمثل جهد خرج الحساس مع الوضع فى الاعتبار أنه لا يزيد عن 2.5 volts ، فيجب ضبط جهد المرجع للمحول من تناظرى لرقمى عند 2.5 volts . لتحديد التحويل يتم استخدام المعادلة :
بالتعويض نحصل على صيغة دالة التحويل التالية :
الخطوة التالية هى تنفيذ كود المصدر لبرنامج يستخدم دالة التحويل وعرض هذه القيمة ، لهذا الغرض إليك كود المصدر للبرنامج التالى :
وأخيرا للتحقق من سلوك النظام يتم التنفيذ ببرنامج إيزيس بالأجهزة التالية :
16F877A, RES, LM016L, GP2D12 وتكوين الدائرة الكهربية كما فى الشكل التالى :
تستخدم أجهزة إستشعار المسافة فى قياس طول المسافة من مكان نقطة موقع الجسم العائق obstacle إلى موقع المستشعر (الحساس) . تنفيذ هذا النوع من الأجهزة مفيد فى أنظمة التحكم وفى مشاريع الروبوتات robotics.
وكحالة محددة فأنه فى هذا الجزء سوف يتم العمل بالحساس GP2D12 (الموجود ضمن برنامج إيزيس) ، هذا الحساس يستخدم تقنية إرسال الشعاع الضوئى للأشعة تحت الحمراء واستقبال إنعكاسها لتحديد المسافة . الشكل التالى يبين المظهر الطبيعى ، والأطراف ، والرمز فى برنامج إيزيس لهذا الحساس :
مثل هذا الحساس له سلوك غير خطى nonlinear ، هذا يعنى أن الخرج ليس له دالة تحويل خطية . لفهم هذا المفهوم بوضوح الرسم البيانى التالى يبين سلوك الخرج كدالة فى المسافة :
سلوك مثل هذا الحساس صعب التنفيذ ، لأنه فى بعض الحالات لا يقدم المصنع دالة تحويل مفيدة حتى يمكن استخدامها فى شكل معادلة واحدة . وعلى الرغم من ذلك فهذا لا يشكل عقبة أمام استخدام الحساس . كما هو موضح فى الداتا شيت أن المدى المؤثر من 10 إلى 80 سنتيمتر ( Effective Range: 10 to 80 cm) كما هو مبين فى الرسم البيانى .
الرسم البيانى الموضح موجود بالداتا شيت الخاص بالجهاز ويتم تنفيذه تجريبيا (نتيجة تجارب) . لوصف سلوك الحساس والحصول على دالة التحويل من الضرورى إجراء عملية رياضية تعرف باسم "الخطية" linearization . لتحقيق هذه الغاية يتم إجراء عملية "إستيفاء" interpolation بعدد معروف من نقاط الدالة ، هذه النقاط تؤخد من القياسات التجريبية . كلما زاد عدد النقاط كلما زادت دقة تقييم دالة التحويل .
لبدء هذه العملية يتم اختيار نقطتين موزعين بالتساوى . على سبيل المثال النقطة عند مسافة 10cm والنقطة عند مسافة 80cm . لكل نقطة نكون معادلة فيكون لدينا معادلتين من الدرجة الأولى فى هذه الحالة ، حيث يتم حلهما معا وإيجاد الثوابت .
لفهم هذا المفهوم ، نفترض أن المغير المستقل x يعبر عن جهد خرج الحساس بالفولت والمتغير التابع y يعبر عن المسافة بالسنتيمتر ونعتبر أن المعادلة التالية تعبر عن سلوك الحساس :
باعتبار أن y تمثل المسافة و x تمثل جهد خرج الحساس المستخدم ومن الرسم البيانى التجريبى نحصل على :
عندئذ يمكن كتابة المعادلات :
https://i.servimg.com/u/f11/18/74/92/45/1113.jpg
ونستطيع تكوين معادلتين فى مجهولين كما يلى :
بحل المعادلين يمكن تعيين الثوابت كما يلى :
https://i.servimg.com/u/f11/18/74/92/45/1311.jpg
بهذه الطريقة يمكن وضع صيغة لدالة التحويل للحساس كما يلى :
وحيث أن المتغير x يمثل جهد خرج الحساس مع الوضع فى الاعتبار أنه لا يزيد عن 2.5 volts ، فيجب ضبط جهد المرجع للمحول من تناظرى لرقمى عند 2.5 volts . لتحديد التحويل يتم استخدام المعادلة :
بالتعويض نحصل على صيغة دالة التحويل التالية :
الخطوة التالية هى تنفيذ كود المصدر لبرنامج يستخدم دالة التحويل وعرض هذه القيمة ، لهذا الغرض إليك كود المصدر للبرنامج التالى :
- الكود:
// 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
//Variables Declaration .
unsigned int Radc, DisI;
float Dis;
char Text[16];
void main( void )
{
//Set the ADC module with pin AN3
//as positive reference voltage.
ADCON1 = 0b11000001;
//Initiation LCD
Lcd_Init();
//Clearing the cursor.
Lcd_Cmd(_LCD_CURSOR_OFF);
//Printing text.
Lcd_Out( 1, 1, "Distance:");
while(1) //Infinite Loop.
{
//Reading analog channel 0 .
Radc=ADC_Read(0);
//Implementation of the transfer function Equation
Dis = (14226.02784/Radc)-4.793814433;
//force the result to an integer value.
DisI=Dis;
//convert the integer value to string.
IntToStr( DisI, Text );
//Print the sensor reading.
Lcd_Out( 2, 1, Text );
//Delay 100m-seconds.
delay_ms(100);
}
}
وأخيرا للتحقق من سلوك النظام يتم التنفيذ ببرنامج إيزيس بالأجهزة التالية :
16F877A, RES, LM016L, GP2D12 وتكوين الدائرة الكهربية كما فى الشكل التالى :
رد: ما هو الميكروكونترولر Microcontroller ؟
أجهزة الأستشعار LDR Sensors
أجهزة الاستشعار LDR هى أجهزة تتغير مقاومتها اعتمادا على شدة الضوء ، كلما ارتفعت شدة الضوء انخفضت مقاومة LDR .
هذه الأجهزة مفيدة لتحديد وجود أو غياب الإضاءة المحيطة ، لذلك فهى تستخدم فى الأنظمة التى تتطلب التحكم فى شدة الإضاءة .
الشكل التالى يبين المظهر الطبيعى والرموز فى برنامج إيزيس :
الخصائص الكهربائية لهذه الأجهزة ليست صعبة التحقيق ، حيث أنها تعمل بطريقة بسيطة ويوجد لها مجموعة متنوعة من شركات التصنيع ، أجهزة LDR أو المقاومة الضوئية متوفرة تجاريا بمختلف الأحجام ، وهذا يعنى أن مدى التغير فى المقاومة يعتمد على الحجم ، فالحجم الكبير يكون له مدى صغير والعكس بالنسبة للحجم الصغير . قد يكون التغيرفى المقاومة ليس متماثلا فى اثنين من LDR لهما نفس الحجم . هذه الأسباب تجعلها سهلة الاستخدام لقراءة المقاومة أو الجهد بين طرفيها . أبسط طريقة لاستخدام LDR هى عمل مقسم جهد مع مقاومة ثابتة .
لفهم هذا المفهوم يمكنك النظر إلى الشكل التالى :
بتطبيق النظرية الأساسية لتقسيم الجهد على الدائرة السابقة نحصل على :
من هذه المعادلة يمكن الحصول على المعادلة :
وحيث أن الجهد التناظرى بالقيمة Vout يدخل إلى المحول من التناظرى لرقمى ، وهو ما يعتبره الميكروكونترولر جهد دخل Vadc ، وباستخدام جهد المرجع الموجب بالقيمة 5 volts (الافتراضى) فإنه يمكن التعبير عن التحويل بالصيغة التالية :
بالتعويض فى المعادلة السابقة وبفرض أن الجهد Vccيساوى 5 volts يمكننا الحصول على العلاقة :
فى هذه الحالة الخاصة للتدريب على المحاكاة سوف نستخدم مقاومة مقسم الجهد بالقيمة 10k وبالتالى سوف تصبح معادلة LDR بالصيغة :
لإدراك المفاهيم السابقة يتم تحرير وترجمة ومراقبة وتحليل كودالمصدر للبرنامج التالى :
للمحاكاة ببرنامج إيزيس يتم جلب الأجهزة التالية :
16F877A, RES, LM016L, TORCH_LDR وإنشاء الدائرة الكهربية الآتية :
أجهزة الاستشعار LDR هى أجهزة تتغير مقاومتها اعتمادا على شدة الضوء ، كلما ارتفعت شدة الضوء انخفضت مقاومة LDR .
هذه الأجهزة مفيدة لتحديد وجود أو غياب الإضاءة المحيطة ، لذلك فهى تستخدم فى الأنظمة التى تتطلب التحكم فى شدة الإضاءة .
الشكل التالى يبين المظهر الطبيعى والرموز فى برنامج إيزيس :
الخصائص الكهربائية لهذه الأجهزة ليست صعبة التحقيق ، حيث أنها تعمل بطريقة بسيطة ويوجد لها مجموعة متنوعة من شركات التصنيع ، أجهزة LDR أو المقاومة الضوئية متوفرة تجاريا بمختلف الأحجام ، وهذا يعنى أن مدى التغير فى المقاومة يعتمد على الحجم ، فالحجم الكبير يكون له مدى صغير والعكس بالنسبة للحجم الصغير . قد يكون التغيرفى المقاومة ليس متماثلا فى اثنين من LDR لهما نفس الحجم . هذه الأسباب تجعلها سهلة الاستخدام لقراءة المقاومة أو الجهد بين طرفيها . أبسط طريقة لاستخدام LDR هى عمل مقسم جهد مع مقاومة ثابتة .
لفهم هذا المفهوم يمكنك النظر إلى الشكل التالى :
بتطبيق النظرية الأساسية لتقسيم الجهد على الدائرة السابقة نحصل على :
- الكود:
Vout = Vcc * (LDR / (LDR+R))
من هذه المعادلة يمكن الحصول على المعادلة :
- الكود:
LDR = (Vout)(R) / (Vcc – Vout)
وحيث أن الجهد التناظرى بالقيمة Vout يدخل إلى المحول من التناظرى لرقمى ، وهو ما يعتبره الميكروكونترولر جهد دخل Vadc ، وباستخدام جهد المرجع الموجب بالقيمة 5 volts (الافتراضى) فإنه يمكن التعبير عن التحويل بالصيغة التالية :
- الكود:
Vadc = Radc * (5 / 1023) = Radc * 0.004887585
بالتعويض فى المعادلة السابقة وبفرض أن الجهد Vccيساوى 5 volts يمكننا الحصول على العلاقة :
- الكود:
LDR = (Radc)( 0.004887585) (R) / (5 – (Radc)( 0.004887585))
فى هذه الحالة الخاصة للتدريب على المحاكاة سوف نستخدم مقاومة مقسم الجهد بالقيمة 10k وبالتالى سوف تصبح معادلة LDR بالصيغة :
- الكود:
LDR = (Radc) (48.87585) / (5 – (Radc)( 0.004887585))
لإدراك المفاهيم السابقة يتم تحرير وترجمة ومراقبة وتحليل كودالمصدر للبرنامج التالى :
- الكود:
// 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
//Dariables Declaration .
unsigned long Radc, DisI;
char Text[16];
void main( void )
{
//Initiation LCD
Lcd_Init();
//Cursor OFF.
Lcd_Cmd(_LCD_CURSOR_OFF);
//Printing text.
Lcd_Out( 1, 1, "Resistance:");
while(1) //Infinite Loop.
{
//Reading analog channel 0.
Radc=ADC_Read(0);
//Implementation the calculation of the LDR equation
DisI = (Radc*48.87585533)/(5.0-Radc*0.004887585);
//Convert the long integer value in string.
LongToStr( DisI, Text );
//Print the sensor reading.
Lcd_Out( 2, 1, Text );
//Delay 100m-seconds.
delay_ms(100);
}
}
للمحاكاة ببرنامج إيزيس يتم جلب الأجهزة التالية :
16F877A, RES, LM016L, TORCH_LDR وإنشاء الدائرة الكهربية الآتية :
رد: ما هو الميكروكونترولر Microcontroller ؟
أجهزة استشعار الضغط Pressure sensors :
الضغط هو متغير طبيعى، يمثل بمتجه يعرف بأنه القوة الواقعة على مساحة معينة . يتم الدلالة على الضغط بوحدات مختلفة تبعا لنظام الوحدات المستخدم ، فيمكن أن يعطى الضغط بالوحدات :
psi, Pascal, atmospheres, inches of mercury الخ.
للأغراض العملية لهذا الجزء سوف يتم العمل بحساس الضغط MPX4115 . خواص هذا الحساس تعطى بالكيلوباسكال Kilo Pascal ويمكنه قياس الضغوط فى المدى بين 15 kPa و 115 kPa، أو بين 2.18 psi و 16.7 psi.
المظهر الطبيعى وتوزيع الأطرف ومز المحاكاة فى برنامج إيزيس موضح بالشكل التالى :
يتم التنفيذ تبعا لنوع الحساس ، كل حساس يجب أن يكون له "دالة تحويل" transfer function وهى العلاقة بين الخرج والدخل ، فى حالة حساس الضغط MPX4115 تتحدد دالة التحويل بواسطة الصناع بالعلاقة :
حيث Vout هو جهد خرج الحساس ، و P هو الضغط بالكيلوباسكال Kilo Pascal ، و Vs جهد تغذية الحساس . من هذه المعادلة يمكن الحصول على صيغة للضغط بالشكل التالى :
عندما يتم إعداد الميكروكونترولر PIC ليعمل المحول من تناظرى لرقمىADC بدقة 10 بتات 10-bit يمكن استنتاج العلاقة التالية :
هذا الجهد هو نفسه جهد خرج الحساس ، بالتعويض عن Vout يمكن الحصول على المعادلة أو العلاقة التى يم استخدامها بالميكروكونترولر لقراءة الحساس ، هذه العلاقة تكون بالشكل التالى :
هنا ، فى حالتنا الخاصة ، سوف يتم استخدام جهد التغذية بقيمة 5 volts وهو الذى يغذى الميكروكونترولر والحساس ولذلك فإن Vs تساوى 5 volts , ونحصل على العلاقة النهائية لنسبة التحويل بالصيغة التالية :
لاستعراض العمل الفعلى لمثل هذا الحساس راقب وحلل كود المصدر للبرنامج التالى :
بعد تحرير وترجمة البرنامج , يمكن تنفيذ المحاكاة ببرنامج إيزيس بجلب الأجهزة الآتية :
16F877A, MPX4115, LM016L وتكون الدائرة الكهربية كما فى الشكل التالى :
الضغط هو متغير طبيعى، يمثل بمتجه يعرف بأنه القوة الواقعة على مساحة معينة . يتم الدلالة على الضغط بوحدات مختلفة تبعا لنظام الوحدات المستخدم ، فيمكن أن يعطى الضغط بالوحدات :
psi, Pascal, atmospheres, inches of mercury الخ.
للأغراض العملية لهذا الجزء سوف يتم العمل بحساس الضغط MPX4115 . خواص هذا الحساس تعطى بالكيلوباسكال Kilo Pascal ويمكنه قياس الضغوط فى المدى بين 15 kPa و 115 kPa، أو بين 2.18 psi و 16.7 psi.
المظهر الطبيعى وتوزيع الأطرف ومز المحاكاة فى برنامج إيزيس موضح بالشكل التالى :
يتم التنفيذ تبعا لنوع الحساس ، كل حساس يجب أن يكون له "دالة تحويل" transfer function وهى العلاقة بين الخرج والدخل ، فى حالة حساس الضغط MPX4115 تتحدد دالة التحويل بواسطة الصناع بالعلاقة :
- الكود:
Vout = Vs ( 0.009P – 0.095)
حيث Vout هو جهد خرج الحساس ، و P هو الضغط بالكيلوباسكال Kilo Pascal ، و Vs جهد تغذية الحساس . من هذه المعادلة يمكن الحصول على صيغة للضغط بالشكل التالى :
- الكود:
P = (111.111 Vout / Vs) + 10.555
عندما يتم إعداد الميكروكونترولر PIC ليعمل المحول من تناظرى لرقمىADC بدقة 10 بتات 10-bit يمكن استنتاج العلاقة التالية :
- الكود:
Vadc = Radc * (5 / 1023)
هذا الجهد هو نفسه جهد خرج الحساس ، بالتعويض عن Vout يمكن الحصول على المعادلة أو العلاقة التى يم استخدامها بالميكروكونترولر لقراءة الحساس ، هذه العلاقة تكون بالشكل التالى :
- الكود:
P = (0.54306 Radc / Vs ) + 10.555
هنا ، فى حالتنا الخاصة ، سوف يتم استخدام جهد التغذية بقيمة 5 volts وهو الذى يغذى الميكروكونترولر والحساس ولذلك فإن Vs تساوى 5 volts , ونحصل على العلاقة النهائية لنسبة التحويل بالصيغة التالية :
- الكود:
P = 0.10861Radc +10.555
لاستعراض العمل الفعلى لمثل هذا الحساس راقب وحلل كود المصدر للبرنامج التالى :
- الكود:
// 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
//Variables Declaration .
unsigned int Radc, PreI;
float Pre;
char Text[16];
void main( void )
{
//LCD initiation.
Lcd_Init();
//Clearing the cursor.
Lcd_Cmd(_LCD_CURSOR_OFF);
//Printing text
Lcd_Out( 1, 1, "Pressure in KPa:");
while(1) //Infinite Loop.
{
//Reading ADC channel 0.
Radc = ADC_Read(0);
//Using the equation
Pre = 0.10861*Radc+10,5555;
//Forces the result to the integer part.
PreI = Pre;
//Converts the integer to a string.
IntToStr( PreI, Text );
//prints the result.
Lcd_Out( 2, 1, Text);
//Delay 100 m seconds.
delay_ms(100);
}
}
بعد تحرير وترجمة البرنامج , يمكن تنفيذ المحاكاة ببرنامج إيزيس بجلب الأجهزة الآتية :
16F877A, MPX4115, LM016L وتكون الدائرة الكهربية كما فى الشكل التالى :
رد: ما هو الميكروكونترولر Microcontroller ؟
قياس درجة حرارة موجبة وسالبة باستخدام الحساس LM35
الدائرة الكهربية :
برجاء مراجعة الداتا شيت الخاصة بالحساس LM35
البرنامج :
الدائرة الكهربية :
برجاء مراجعة الداتا شيت الخاصة بالحساس LM35
البرنامج :
- الكود:
//program Thermometer_with_LM35 + & -
// 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 temp; // unsigned (int) 0 .. 65535
unsigned tempn;
short tempout ; //(signed) short (int) - 128 .. 127
char Tc[5];
void main(){
TRISA = 0xFF; // designate PORTA as input
TRISB = 0; // as outputs
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"ENG.F.ABDELAZIZ"); // Write text in first row
Lcd_Out(2,1,"WELCOME"); // Write text in second row
Delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Out(1,1,"ROOM TEMP."); // Write text in first row
while (1) {
temp = ADC_read(0);
tempn = ADC_read(1);
temp = temp/2.046; // T = (Vadc mV /10) = (1/10) * ADC_READ*(5000/1023)
tempn = tempn/2.046;
tempout = temp - tempn;
shortToStr(tempout,Tc);
Lcd_Out(2,1,Tc);
Lcd_Chr_Cp(223); // ASCII degree character
Lcd_Chr_Cp('C');
delay_ms(1000);
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
مشروع : تصميم نظام قياس درجة الحرارة يعتمد على الميكروكونترولر باستخدام مقاومة حرارية RTD نوع Pt100 .
حساس الحرارة المستخدم له معامل حرارى =0.00385 α . وخواصه :
إذا فرضنا أن مقومة المصدر Rs=1K وجهد المصدر Vs=5V فإن الجهد بين طرفى الحساس RTD عند كل من نهايتى مدى درجة حرارة التشغيل تكون :
فإذا استخدمنا مكبر عمليات كسبه (تكبيرة) يساوى 5 فإن المدى الذى يرى من جهة المحول A/D سوف يكون:
وحيث أن المحول ذات 10 بت ومداه الكامل هو 5V فإن دقته أو الجهد المناظر لكل بت يكون :
ولكن مدى جهد الدخل :
ومن ثم سوف تكون دقة (حساسية) النظام حوالى واحد درجة مئوية .
المخطط الصندوقى :
الدائرة الكهربية :
مبدأ العمل :
• يتم تحويل الجهد بين طرفى الحساس RTD إلى الشكل الرقمى .
• يتم حساب مقاومة الحساس Rt باستخدام المعادلة :
• حيث Vt الجهد بين طرفى الحساس و Vs=5V و Rs=1k , بالتعويض نحصل على :
• يتم حساب درجة الحرارة من المعادلة :
• حيث t هى درجة الحرارة المقاسة بالدرجات المئوية ، و Rt هى مقاومة الحساس عند درجة الحرارة t ، و :
بالتعويض نحصل على :
حيث يمكننا حساب درجة الحرارة t بمعلومية المقاومة Rt .
البرنامج :
ملخص لخطوات البرنامج :
• إعدادات وحدة العرض .
• إعدادات الميكروكونترولر .
• إنشاء حلقة غير منتهية وفيها يتم :
# قراءة الجهد التناظرى بين طرفى الحساس RTD وتحويله إلى الشكل الرقمى .
# حساب المقاومة Rt .
# حساب درجة الحرارة t .
# عمل المقياس اللازم للتحويل إلى درجة حرارة .
# عرض درجة الحرارة على وحدة العرض LCD .
# الانتظار لثانية ثم التكرار بصفة مستمرة لتحديث البيانات .
النتائج :
حساس الحرارة المستخدم له معامل حرارى =0.00385 α . وخواصه :
إذا فرضنا أن مقومة المصدر Rs=1K وجهد المصدر Vs=5V فإن الجهد بين طرفى الحساس RTD عند كل من نهايتى مدى درجة حرارة التشغيل تكون :
فإذا استخدمنا مكبر عمليات كسبه (تكبيرة) يساوى 5 فإن المدى الذى يرى من جهة المحول A/D سوف يكون:
وحيث أن المحول ذات 10 بت ومداه الكامل هو 5V فإن دقته أو الجهد المناظر لكل بت يكون :
ولكن مدى جهد الدخل :
ومن ثم سوف تكون دقة (حساسية) النظام حوالى واحد درجة مئوية .
المخطط الصندوقى :
الدائرة الكهربية :
مبدأ العمل :
• يتم تحويل الجهد بين طرفى الحساس RTD إلى الشكل الرقمى .
• يتم حساب مقاومة الحساس Rt باستخدام المعادلة :
• حيث Vt الجهد بين طرفى الحساس و Vs=5V و Rs=1k , بالتعويض نحصل على :
• يتم حساب درجة الحرارة من المعادلة :
• حيث t هى درجة الحرارة المقاسة بالدرجات المئوية ، و Rt هى مقاومة الحساس عند درجة الحرارة t ، و :
بالتعويض نحصل على :
حيث يمكننا حساب درجة الحرارة t بمعلومية المقاومة Rt .
البرنامج :
ملخص لخطوات البرنامج :
• إعدادات وحدة العرض .
• إعدادات الميكروكونترولر .
• إنشاء حلقة غير منتهية وفيها يتم :
# قراءة الجهد التناظرى بين طرفى الحساس RTD وتحويله إلى الشكل الرقمى .
# حساب المقاومة Rt .
# حساب درجة الحرارة t .
# عمل المقياس اللازم للتحويل إلى درجة حرارة .
# عرض درجة الحرارة على وحدة العرض LCD .
# الانتظار لثانية ثم التكرار بصفة مستمرة لتحديث البيانات .
- الكود:
/* This project measures the temperature with a RTD PT100 and
* then displays on a LCD
Eng.F.Abdelaziz
*/
// LCD module connections
sbit LCD_RS at RC0_bit;
sbit LCD_EN at RC1_bit;
sbit LCD_D4 at RC4_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D7 at RC7_bit;
sbit LCD_RS_Direction at TRISC0_bit;
sbit LCD_EN_Direction at TRISC1_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End LCD module connections
float rtdv,rtdr,temp,y; // Floating-point Types
int msd, isd;
char temperature [6] ;
void main()
{
/* Initialize the microcontroller */
TRISA=0xFF; //configure PORTA as Input direction
TRISB=0; //configure PORTB as Output direction
TRISC=0; //configure PORTD as Output direction
PORTA=0; //Clear
PORTB=0;
PORTC=0;
//===============================================
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"RTD Pt100 TEMP.");
while(1) {
rtdv = ADC_Read(0);// Get RTD voltage 10-bit result
rtdv = rtdv *5 /1024 ; //Scale RTD voltage in Volts
rtdv = rtdv/5; //for op amp gain
/* Calculate RTD resistance rtdr */
rtdr = rtdv*1000.0/(5.0-rtdv);
/* Calculate temperature temp */
y = 0.15274- (rtdr-100.0)*0.0002310;
if(y>= 0) y = sqrt(y) ;
temp = (y-0.39083)/(-0.0001155) ;
ByteToStr(temp,temperature); // Change to string
Lcd_Out(2,6,temperature); // Display
Lcd_Chr(2, 9, 223);// Add degree character
Lcd_Chr(2, 10, 'C');// Add letter "c"
delay_ms(1000);
//==============
}
}
النتائج :
mariacontenis يعجبه هذا الموضوع
رد: ما هو الميكروكونترولر Microcontroller ؟
التدريب الرابع :
قياس درجة حرارة باستخدام الحساس LM35 وعرضها على 4 وحدات سفن سيجمنت
الدائرة الكهربية :
البرنامج :
قياس درجة حرارة باستخدام الحساس LM35 وعرضها على 4 وحدات سفن سيجمنت
الدائرة الكهربية :
البرنامج :
- الكود:
/*
* Project name: Multiplexing_7-Segment 4 UNITS
MCU: PIC16F877A , ADC , LM35
Oscillator: HS, 8.0000 MHz
SW: mikroC PRO
*/
#define Digit1 PORTD.B0 // THOUTHAND
#define Digit2 PORTD.B1 // HUNDRED
#define Digit3 PORTD.B2 // TENS
#define Digit4 PORTD.B3 // ONES
unsigned char Display (unsigned char digit)
{
unsigned char pattern;
unsigned char SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
pattern = SEGMENT_MAP[digit] ; //The pattern to return
return (pattern);
}
void main() {
unsigned char DD1,DD2, DD3,DD4 ;
unsigned int result; //
float scale ;
char num ;
ADCON1= 0; //
TRISA.B0=1; // AN0 INPUT
TRISD = 0; // Configure PORTD as outputs , COMMON CATHODES
TRISB = 0; // Configure PORTB as outputs ,7 SEGMENT DATA PORT
Digit1 = 0; //Disable digit 1
Digit2 = 0; //Disable digit 2
Digit3 = 0; //Disable digit 3
Digit4 = 0; //Disable digit 4
while(1){
result=ADC_Read(0); // Read analog value from channel 0
scale = result * (5000.0/1023.0); // input analog voltage
scale = scale /10.0 ; // input temp inc for LM35
num = scale ;
///////////
DD1 = num / 1000; //Extract DD1 from result >>THOUTHAND
PORTB = Display(DD1); //Display the DD1
Digit1 = 1; //Enable digit 1
Delay_Ms(10); //a short 10ms delay
Digit1 = 0; //Disable digit 1
/////////
DD2 = (num/100) % 10; // DD2 digit >>>HUNDRED
PORTB = Display(DD2); //Display the DD3
Digit2 = 1; //Enable digit 2
Delay_Ms(10); //a short 10ms delay
Digit2 = 0; //Disable digit 2
////////////
DD3 = (num/10) % 10; //Extract DD3 from result >>TENS
PORTB = Display(DD3); //Display the DD3
Digit3 = 1; //Enable digit 3
Delay_Ms(10); //a short 10ms delay
Digit3 = 0; //Disable digit 3
/////////
DD4 = num % 10; //Extract DD4 from result >>ONES
PORTB = Display(DD4); //Display the DD4
Digit4 = 1; //Enable digit 4
Delay_Ms(10); //a short 10ms delay
Digit4 = 0; //Disable digit 4
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
تطوير للتدريب السابق بوضع حرف :"C" للإشارة إلى الدرجات المئوية .
الدائرة الكهربية :
البرنامج :
- الكود:
/*
* Project name: Multiplexing_7-Segment 4 UNITS
MCU: PIC16F877A , ADC , LM35 MOD
Oscillator: HS, 8.0000 MHz
SW: mikroC PRO
*/
#define Digit1 PORTD.B0 // DIGIT 1 FROM LEFT , THOUTHAND
#define Digit2 PORTD.B1 // DIGIT 2 FROM LEFT , HUNDRED
#define Digit3 PORTD.B2 // DIGIT 3 FROM LEFT , TENS
#define Digit4 PORTD.B3 // DIGIT 4 FROM LEFT , ONES
unsigned char Display (unsigned char digit)
{
unsigned char pattern;
unsigned char SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
pattern = SEGMENT_MAP[digit] ; //The pattern to return
return (pattern);
}
void main() {
unsigned char DD1,DD2, DD3,DD4 ;
unsigned int ADC_result; //
float scale ;
unsigned int num ;
ADCON1= 0; //
TRISA.B0=1; // AN0 INPUT
TRISD = 0; // Configure PORTD as outputs , COMMON CATHODES
TRISB = 0; // Configure PORTB as outputs ,7 SEGMENT DATA PORT
Digit1 = 0; //Disable digit 1
Digit2 = 0; //Disable digit 2
Digit3 = 0; //Disable digit 3
Digit4 = 0; //Disable digit 4
while(1){
ADC_result=ADC_Read(0); // Read analog value from channel 0
scale = ADC_result * (5000.0/1023.0); // input analog voltage
num = scale /10.0 ; // input temp inc for LM35
///////////
DD1 = num / 100; //Extract DD1 from ADC_result >>THOUTHAND
PORTB = Display(DD1); //Display the DD1
Digit1 = 1; //Enable digit 1
Delay_Ms(10); //a short 10ms delay
Digit1 = 0; //Disable digit 1
/////////
DD2 = (num/10) % 10; // DD2 digit >>>HUNDRED
PORTB = Display(DD2); //Display the DD3
Digit2 = 1; //Enable digit 2
Delay_Ms(10); //a short 10ms delay
Digit2 = 0; //Disable digit 2
////////////
DD3 = num % 10; //Extract DD3 from ADC_result >>TENS
PORTB = Display(DD3); //Display the DD3
Digit3 = 1; //Enable digit 3
Delay_Ms(10); //a short 10ms delay
Digit3 = 0; //Disable digit 3
/////////
//DD4 = num % 10; //Extract DD4 from ADC_result >>ONES
PORTB = 0x39; //Display C CHARACTER
Digit4 = 1; //Enable digit 4
Delay_Ms(10); //a short 10ms delay
Digit4 = 0; //Disable digit 4
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
[SIZE="4"]
إزالة حرف "C" واستخدام خانة الآحاد لبيان كسر الآحاد مع عرض النقطة العشرية على وحدة السفن سيجمنت :
الدائرة الكهربية :
البرنامج :
[/SIZE]
إزالة حرف "C" واستخدام خانة الآحاد لبيان كسر الآحاد مع عرض النقطة العشرية على وحدة السفن سيجمنت :
الدائرة الكهربية :
البرنامج :
- الكود:
/*
* Project name: Multiplexing_7-Segment 4 UNITS
MCU: PIC16F877A , ADC , LM35 MOD
Oscillator: HS, 8.0000 MHz
SW: mikroC PRO
*/
#define Digit1 PORTD.B0 // DIGIT 1 FROM LEFT , THOUTHAND
#define Digit2 PORTD.B1 // DIGIT 2 FROM LEFT , HUNDRED
#define Digit3 PORTD.B2 // DIGIT 3 FROM LEFT , TENS
#define Digit4 PORTD.B3 // DIGIT 4 FROM LEFT , ONES
unsigned char Display (unsigned char digit)
{
unsigned char pattern;
unsigned char SEGMENT_MAP[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
pattern = SEGMENT_MAP[digit] ; //The pattern to return
return (pattern);
}
void main() {
unsigned char DD1,DD2, DD3,DD4 ;
float result; //
unsigned int result1;
ADCON1= 0; //
TRISA.B0=1; // AN0 INPUT
TRISD = 0; // Configure PORTD as outputs , COMMON CATHODES
TRISB = 0; // Configure PORTB as outputs ,7 SEGMENT DATA PORT
Digit1 = 0; //Disable digit 1
Digit2 = 0; //Disable digit 2
Digit3 = 0; //Disable digit 3
Digit4 = 0; //Disable digit 4
while(1){
result=ADC_Read(0); // Read analog value from channel 0 ,0 to 1023
result = result * (5000.0/1023.0); // input analog voltage
result = result /10.0 ; // input temp in C for LM35 0.0 to 150.0
///////////
result = result *10.0 ; // float 0.0 to 1500.0
result1=result; //integer 0 to 1500 to get fraction
/////////////
DD1 = result1 / 1000; //Extract DD1 from result >>THOUTHAND(hundred)
PORTB = Display(DD1); //Display the DD1
Digit1 = 1; //Enable digit 1
Delay_Ms(10); //a short 10ms delay
Digit1 = 0; //Disable digit 1
/////////
DD2 = (result1/100) % 10; // DD2 digit >>>HUNDRED (tens)
PORTB = Display(DD2); //Display the DD3
Digit2 = 1; //Enable digit 2
Delay_Ms(10); //a short 10ms delay
Digit2 = 0; //Disable digit 2
////////////
DD3 = (result1/10) % 10; //Extract DD3 from result >>TENS (ones)
PORTB = Display(DD3); //Display the DD3
Digit3 = 1; //Enable digit 3
Delay_Ms(10); //a short 10ms delay
Digit3 = 0; //Disable digit 3
/////////
DD4 = result1 % 10; //Extract DD4 from result >>ONES(fraction)
//PORTB = 0x39; //Display C CHARACTER
PORTB = Display(DD4);
Digit4 = 1; //Enable digit 4
Delay_Ms(10); //a short 10ms delay
Digit4 = 0; //Disable digit 4
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
فكرة إنشاء ثرموستات باستخدام المقاومة السالبة NTC والمحول ADC ووحدة العرض LCD مع المترجم ميكرو سى
المقاومة السالبة المستخدم من النوع NTC / NTSA0WB203 وهذا النوع موجود فى برنامج ISIS .
هذه المقاومة لها معامل أو ثابت يسمى بيتا “β = 4050” ، ولها مقاومة قيمتها 20 كيلوأوم عند درجة حرارة 25 درجة مئوية .
الدائرة الكهربية :
يتم تشكيل مقسم جهد من مصدر جهد (بطارية ، على سبيل المثال ) والمقاومة السالبة NTC ومقاومة ثابتة R1 بقية 10 كيلوأوم ، وحساب درجة الحرارة من المعادلات التالية :
البرنامج :
المقاومة السالبة المستخدم من النوع NTC / NTSA0WB203 وهذا النوع موجود فى برنامج ISIS .
هذه المقاومة لها معامل أو ثابت يسمى بيتا “β = 4050” ، ولها مقاومة قيمتها 20 كيلوأوم عند درجة حرارة 25 درجة مئوية .
الدائرة الكهربية :
يتم تشكيل مقسم جهد من مصدر جهد (بطارية ، على سبيل المثال ) والمقاومة السالبة NTC ومقاومة ثابتة R1 بقية 10 كيلوأوم ، وحساب درجة الحرارة من المعادلات التالية :
- الكود:
VT=VB * RT/R1+RT
VB*RT = VT*R1 + VT * RT
VT*R1= RT(VB-VT)
RT = VT*R1/(VB-VT) = 10000VT/(5-VT)
البرنامج :
- الكود:
// 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
float tv,tr,temp,y; //Equation variables
unsigned unsigned int value;
int Tc ;
char text [7] ;
void main() {
lcd_init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,1,"ADC NTC TEMP." );
while (1) {
value = ADC_Read(0);
tv = 5.0 * value / 1023.0;
tr = tv * 10000.0 / (5.0 - tv);
y = log(tr/20000.0);
y = (1.0/298.15) + (y *(1.0/4050.0));
temp=1.0/y;
temp = temp -273.15;
Tc = temp ;
IntToStr(Tc , text);
Lcd_Out(2,1,text);
Lcd_Chr_Cp(223);
Lcd_Chr_Cp('C');
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
فهم المقاطعات في الميكروكنترولر PIC مع المترجم ميكروسى برو :
المقاطعات هي مفهوم قوي في الأنظمة المدمجة من أجل التحكم فى الأحداث التى تقع في بيئة حساسة للوقت . في النظام المدمج النموذجي ، المعالج المدمج (الميكروكونترولر) هو المسؤول عن القيام بأكثر من مهمة واحدة (ولكن يمكن أن يقوم بعمل مهمة واحدة فقط في نفس الوقت ). على سبيل المثال ، دعونا نقول أنه في منظم درجة حرارة (ثرموستات) رقمى مبرمج لغرفة ، حيث يتم تخصيص الميكروكونترولر لمراقبة درجة حرارة الغرفة ، وتحويل المكيف أو سخان لوضع التشغيل ON ووضع الإيقاف OFF ، والتحكم في شاشة LCD ، والاستجابة لأي إعدادات جديدة لدرجة الحرارة من قبل المستخدم . من بين هذه المهام ، الثلاث مهام الأولى تكون غير حرجة للوقت ويتم تنفيذها بشكل مستمر في تسلسل واحدة تلو الآخرى ، داخل الحلقة الرئيسية . ولكن عندما يضغط المستخدم أي زر على لوحة الإعداد ، يجب أن يكون الميكروكونترولر قادرا على قراءته قبل أن يحرر المستخدم الزر. لذلك هذا الحدث يكون حساس (حرج) للوقت ، ويجب على الميكروكونترولر أن يتوقف عن كل ما يقوم به والاستجابة (الرد) على هذا الحدث ذات الأولوية المرتفعة . هذا ممكن من خلال استخدام المقاطعات interrupts . فى هذا الدرس سوف يتم أولا وصف نظام المقاطعة بشكل عام ثم توضيح كيفية التعامل معه في الميكروكونترولر PIC .
وكما ذكر أعلاه ، تشكل المقاطعات الأساس لفصل الأحداث ذات الحساسية للوقت عن الأحداث الأخرى وتنفيذها بطريقة ذات أولوية . المقاطعة تخبر الميكروكونترولر بترك كل ما يقوم به وتنفيذ برنامج آخر (روتين خدمة المقاطعة ISR ) المخزن في مكان محدد مسبقا في ذاكرة البرنامج . طلبات المقاطعة هي أحداث غير متزامنة مما يعني أنه يمكن حدوث طلب المقاطعة في أي وقت أثناء تنفيذ أحد البرامج . ولكن كلما حدث ذلك ، فإن وحدة المعالجة المركزية تنهى التعليمة الحالية وتخزن عنوان التعليمة التالية (عن طريق عداد البرنامج PC ) في ذاكرة المكدس stack بحيث يمكن للبرنامج الحالي من أن يستمر فى التنفيذ من حيث وقف بمجرد انتهاء روتين خدمة المقاطعة . عتدئذ اقفز وحدة المعالجة المركزية إلى موقع ذاكرة برنامج معين (المةقع 0x0004 فى الميكروكونترولر PIC )، حيث يبدأ روتين خدمة المقاطعة ISR . في نهاية روتين خدمة المقاطعة ، تنفيذ تعليمة العودة return تحميل العنوان الموجود في الجزء العلوي من المكدس مرة أخرى في عداد البرنامج ، ويتقدم التنفيذ من نفس النقطة حيث تم مقاطعة المعالج .
الميكروكونترولر لديه عدة مصادر للمقاطعات ، والتي يمكن أن تكون خارجية أو داخلية . مصادر المقاطعة الداخلية الأكثر شيوعا هي المؤقتات Timers وذاكرة EEPROM وموديول ADC والمقارن Comparator . المقاطعات الخارجية تنشأ في الأجهزة الطرفية وتصل إلى متحكم الميكروكونترولر من خلال واحد من أطرافه والمنافذ المرتبطة به.
المقاطعات يمكن أن يتم تمكينها أو تعطيلها بشكل عام globally ، وكذلك فإن كل مصدر مقاطعة يمكن تمكينه أو تعطيله بشكل فردى .
مصادر المقاطعة فى الميكروكونترولر PIC16F877A :
العائلة PIC16F87XA لديها ما يصل الى 15 من مصادر المقاطعة. ويسجل سجل التحكم في المقاطعة INTCON طلبات المقاطعات الفردية في بتات العلم flag bits . هذا السجل به أيضا بتات التمكين enable bits للمقاطعة الفردية والعمومية .
يسمح بت عموم المقاطعات GIE (INTCON<7>) بتمكين جميع المقاطعات (إذا تم تعيينها set) ، أو تعطيلها جميعا (إذا تم مسحه clear ) . عندما يتم تمكين بت عموم المقاطعات GIE ويتم تحديد بت علم المقاطعة فسوف يتم تفعيل المقاطعة على الفور . المقاطعات الفردية يمكن تعطيلها من خلال ما يقابلها من بتات التمكين في السجلات المختلفة. يتم تعيين بت المقاطعة الفردية بغض النظر عن حالة البت GIE . يتم مسح البت GIE عند إعادة تعيين Reset .
تعليمة "العودة من المقاطعة" RETFIE تخرج روتين المقاطعة ، فضلا عن تعيين set البت GIE ، وهو ما يعيد تمكين المقاطعات.
مقاطعة الطرف RB0/INT ، والمقاطعة عند تغيير المنفذ RB ، والمقاطعة نتيجة طفحان (تجاوز) المؤقت TMR0 موجودة بالسجل INTCON .
أعلام المقاطعة الطرفية موجودة فى سجلات الوظائف الخاصة PIR1 , PIR2 ، وبتات تمكين المقاطعة المناظرة موجودة فى سجلات الوظائف الخاصة PIE1 , PIE2 ، وبت تمكين المقاطعة الطرفية موجود فى السجل INTCON .
عندما يتم الاستجابة للمقاطعة ، يتم مسح البت GIE لتعطيل أي مقاطعة أخرى ، يتم دفع عنوان الرجوع الى المكدس ويتم تحميل عداد البرنامج بالعنوان 0004h . يمكن تحديد مصدر أو مصادر المقاطعة عن طريق تقصى بتات علم المقاطعة .
بت أو بتات علم المقاطعة يجب أن يتم مسحها في البرنامج قبل إعادة تمكين المقاطعات لتجنب تكرار المقاطعات .
بالنسبة لأحداث المقاطعة الخارجية ، مثل مقاطعة الطرف INT أو المقاطعة نتيجة تغيير المنفذ PORTB ، يكون زمن استجابة المقاطعة ثلاث أو أربع دورات تعليمة . يعتمد وقت الاستجابة الصحيح على زمن حدوث حدث المقاطعة . زمن الاستجابة هو نفسه لمدة دورة أو دورتى تعليمة .
يتم تحديد set بتات علم المقاطعة بصرف النظر عن حالة البتات PEIE , GIE المقابلة .
بعض مصادر المقاطعة :
المقاطعة الخارجية نتيجة تطبيق نبضة على الطرف RB0/INT :
المقاطعة الخارجية على الطرف RB0/INT هى مقاطعة تعمل بالحافة edge ، يتم اختيار نوع الحافة ، إما حافة صاعدة rising ( بتحديد set البت السادسة INTEDG بالسجل OPTION_REG<6> ) ، أو حافة هابطة ( بمسح clear البت INTEDG ) . عندما تظهر حافة صالحة على الطرف RB0/INT ، يتم تحديد set بت علم المقاطعة الخارجية INTF ، وهى البت الأولى بالسجل INTCON<1> . يمكن تعطيل هذه المقاطعة عن طريق مسح بت تمكينها INTE ، وهى البت الرابعة بالسجل INTCON<4> . بت العلم INTF يجب أن يتم مسحها فى البرنامج ، فى روتين خدمة المقاطعة ، قبل إعادة تمكين هذه المقاطعة . يمكن للمقاطعة الخارجية INT أن توقظ المعالج من النوم إذا كانت البت INTE قد تم تعيينها قبل الذهاب إلى النوم .
مقاطعة المؤقت TMR0 :
حدوث طفحان overflow(FFh → 00h) فى سجل المؤقت TMR0 سوف يحدد set بت العلم TMR0IF ، البت الثانية بالسجل INTCON<2> . يمكن تمكين / تعطيل هذه المقاطعة عن طريق تحديد set / مسح clear بت التمكين TMR0IE ، البت الخامسة بالسجل INTCON<5> .
المقاطعة نتيجة تغيير حالة أطراف المنفذ PORTB :
التغيير فى دخل الأطراف من 4 إلى 7 للمنفذ PORTB<7:4> ، تحدد set بت العلم RBIF وهى البت صفر للسجل INTCON<0> . يمكن تمكين / تعطيل هذه المقاطعة عن طريق تحديد / مسح بت التمكين RBIE ، وهى البت الرابعة للسجل INTCON<4> .
كل من هذه المقاطعات يمكن تمكينها أو تعطيلها بشكل فردي ، ويمكن أن تكون أكثر من مقاطعة واحدة نشطة في نفس الوقت . عند طلب مقاطعة ، ينتهي الميكروكونترولر من تنفيذ التعليمة الحالية، ويخزن قيمة عداد البرنامج في المكدس ، ويقفز إلى الغنوان 0004h في ذاكرة البرنامج ، حيث يقع روتين خدمة المقاطعة . ونظرا لأن جميع مصادر المقاطعة تجعل البرنامج يقفز إلى نفس المكان (0004h) ، فإنه يجب على المبرمج ، عند كتابة روتين خدمة المقاطعة ، أولا معرفة المصدر الذي طلب المقاطعة . ويتم ذلك من خلال قراءة البتات المناسبة في سجلات الوظيفة الخاصة ، INTCON و PIR1 ، المرتبطة بنظام المقاطعة . ويبين الشكل أدناه البتات في سجل التحكم في المقاطعة INTCON .
المقاطعات هي مفهوم قوي في الأنظمة المدمجة من أجل التحكم فى الأحداث التى تقع في بيئة حساسة للوقت . في النظام المدمج النموذجي ، المعالج المدمج (الميكروكونترولر) هو المسؤول عن القيام بأكثر من مهمة واحدة (ولكن يمكن أن يقوم بعمل مهمة واحدة فقط في نفس الوقت ). على سبيل المثال ، دعونا نقول أنه في منظم درجة حرارة (ثرموستات) رقمى مبرمج لغرفة ، حيث يتم تخصيص الميكروكونترولر لمراقبة درجة حرارة الغرفة ، وتحويل المكيف أو سخان لوضع التشغيل ON ووضع الإيقاف OFF ، والتحكم في شاشة LCD ، والاستجابة لأي إعدادات جديدة لدرجة الحرارة من قبل المستخدم . من بين هذه المهام ، الثلاث مهام الأولى تكون غير حرجة للوقت ويتم تنفيذها بشكل مستمر في تسلسل واحدة تلو الآخرى ، داخل الحلقة الرئيسية . ولكن عندما يضغط المستخدم أي زر على لوحة الإعداد ، يجب أن يكون الميكروكونترولر قادرا على قراءته قبل أن يحرر المستخدم الزر. لذلك هذا الحدث يكون حساس (حرج) للوقت ، ويجب على الميكروكونترولر أن يتوقف عن كل ما يقوم به والاستجابة (الرد) على هذا الحدث ذات الأولوية المرتفعة . هذا ممكن من خلال استخدام المقاطعات interrupts . فى هذا الدرس سوف يتم أولا وصف نظام المقاطعة بشكل عام ثم توضيح كيفية التعامل معه في الميكروكونترولر PIC .
وكما ذكر أعلاه ، تشكل المقاطعات الأساس لفصل الأحداث ذات الحساسية للوقت عن الأحداث الأخرى وتنفيذها بطريقة ذات أولوية . المقاطعة تخبر الميكروكونترولر بترك كل ما يقوم به وتنفيذ برنامج آخر (روتين خدمة المقاطعة ISR ) المخزن في مكان محدد مسبقا في ذاكرة البرنامج . طلبات المقاطعة هي أحداث غير متزامنة مما يعني أنه يمكن حدوث طلب المقاطعة في أي وقت أثناء تنفيذ أحد البرامج . ولكن كلما حدث ذلك ، فإن وحدة المعالجة المركزية تنهى التعليمة الحالية وتخزن عنوان التعليمة التالية (عن طريق عداد البرنامج PC ) في ذاكرة المكدس stack بحيث يمكن للبرنامج الحالي من أن يستمر فى التنفيذ من حيث وقف بمجرد انتهاء روتين خدمة المقاطعة . عتدئذ اقفز وحدة المعالجة المركزية إلى موقع ذاكرة برنامج معين (المةقع 0x0004 فى الميكروكونترولر PIC )، حيث يبدأ روتين خدمة المقاطعة ISR . في نهاية روتين خدمة المقاطعة ، تنفيذ تعليمة العودة return تحميل العنوان الموجود في الجزء العلوي من المكدس مرة أخرى في عداد البرنامج ، ويتقدم التنفيذ من نفس النقطة حيث تم مقاطعة المعالج .
الميكروكونترولر لديه عدة مصادر للمقاطعات ، والتي يمكن أن تكون خارجية أو داخلية . مصادر المقاطعة الداخلية الأكثر شيوعا هي المؤقتات Timers وذاكرة EEPROM وموديول ADC والمقارن Comparator . المقاطعات الخارجية تنشأ في الأجهزة الطرفية وتصل إلى متحكم الميكروكونترولر من خلال واحد من أطرافه والمنافذ المرتبطة به.
المقاطعات يمكن أن يتم تمكينها أو تعطيلها بشكل عام globally ، وكذلك فإن كل مصدر مقاطعة يمكن تمكينه أو تعطيله بشكل فردى .
مصادر المقاطعة فى الميكروكونترولر PIC16F877A :
العائلة PIC16F87XA لديها ما يصل الى 15 من مصادر المقاطعة. ويسجل سجل التحكم في المقاطعة INTCON طلبات المقاطعات الفردية في بتات العلم flag bits . هذا السجل به أيضا بتات التمكين enable bits للمقاطعة الفردية والعمومية .
يسمح بت عموم المقاطعات GIE (INTCON<7>) بتمكين جميع المقاطعات (إذا تم تعيينها set) ، أو تعطيلها جميعا (إذا تم مسحه clear ) . عندما يتم تمكين بت عموم المقاطعات GIE ويتم تحديد بت علم المقاطعة فسوف يتم تفعيل المقاطعة على الفور . المقاطعات الفردية يمكن تعطيلها من خلال ما يقابلها من بتات التمكين في السجلات المختلفة. يتم تعيين بت المقاطعة الفردية بغض النظر عن حالة البت GIE . يتم مسح البت GIE عند إعادة تعيين Reset .
تعليمة "العودة من المقاطعة" RETFIE تخرج روتين المقاطعة ، فضلا عن تعيين set البت GIE ، وهو ما يعيد تمكين المقاطعات.
مقاطعة الطرف RB0/INT ، والمقاطعة عند تغيير المنفذ RB ، والمقاطعة نتيجة طفحان (تجاوز) المؤقت TMR0 موجودة بالسجل INTCON .
أعلام المقاطعة الطرفية موجودة فى سجلات الوظائف الخاصة PIR1 , PIR2 ، وبتات تمكين المقاطعة المناظرة موجودة فى سجلات الوظائف الخاصة PIE1 , PIE2 ، وبت تمكين المقاطعة الطرفية موجود فى السجل INTCON .
عندما يتم الاستجابة للمقاطعة ، يتم مسح البت GIE لتعطيل أي مقاطعة أخرى ، يتم دفع عنوان الرجوع الى المكدس ويتم تحميل عداد البرنامج بالعنوان 0004h . يمكن تحديد مصدر أو مصادر المقاطعة عن طريق تقصى بتات علم المقاطعة .
بت أو بتات علم المقاطعة يجب أن يتم مسحها في البرنامج قبل إعادة تمكين المقاطعات لتجنب تكرار المقاطعات .
بالنسبة لأحداث المقاطعة الخارجية ، مثل مقاطعة الطرف INT أو المقاطعة نتيجة تغيير المنفذ PORTB ، يكون زمن استجابة المقاطعة ثلاث أو أربع دورات تعليمة . يعتمد وقت الاستجابة الصحيح على زمن حدوث حدث المقاطعة . زمن الاستجابة هو نفسه لمدة دورة أو دورتى تعليمة .
يتم تحديد set بتات علم المقاطعة بصرف النظر عن حالة البتات PEIE , GIE المقابلة .
بعض مصادر المقاطعة :
المقاطعة الخارجية نتيجة تطبيق نبضة على الطرف RB0/INT :
المقاطعة الخارجية على الطرف RB0/INT هى مقاطعة تعمل بالحافة edge ، يتم اختيار نوع الحافة ، إما حافة صاعدة rising ( بتحديد set البت السادسة INTEDG بالسجل OPTION_REG<6> ) ، أو حافة هابطة ( بمسح clear البت INTEDG ) . عندما تظهر حافة صالحة على الطرف RB0/INT ، يتم تحديد set بت علم المقاطعة الخارجية INTF ، وهى البت الأولى بالسجل INTCON<1> . يمكن تعطيل هذه المقاطعة عن طريق مسح بت تمكينها INTE ، وهى البت الرابعة بالسجل INTCON<4> . بت العلم INTF يجب أن يتم مسحها فى البرنامج ، فى روتين خدمة المقاطعة ، قبل إعادة تمكين هذه المقاطعة . يمكن للمقاطعة الخارجية INT أن توقظ المعالج من النوم إذا كانت البت INTE قد تم تعيينها قبل الذهاب إلى النوم .
مقاطعة المؤقت TMR0 :
حدوث طفحان overflow(FFh → 00h) فى سجل المؤقت TMR0 سوف يحدد set بت العلم TMR0IF ، البت الثانية بالسجل INTCON<2> . يمكن تمكين / تعطيل هذه المقاطعة عن طريق تحديد set / مسح clear بت التمكين TMR0IE ، البت الخامسة بالسجل INTCON<5> .
المقاطعة نتيجة تغيير حالة أطراف المنفذ PORTB :
التغيير فى دخل الأطراف من 4 إلى 7 للمنفذ PORTB<7:4> ، تحدد set بت العلم RBIF وهى البت صفر للسجل INTCON<0> . يمكن تمكين / تعطيل هذه المقاطعة عن طريق تحديد / مسح بت التمكين RBIE ، وهى البت الرابعة للسجل INTCON<4> .
كل من هذه المقاطعات يمكن تمكينها أو تعطيلها بشكل فردي ، ويمكن أن تكون أكثر من مقاطعة واحدة نشطة في نفس الوقت . عند طلب مقاطعة ، ينتهي الميكروكونترولر من تنفيذ التعليمة الحالية، ويخزن قيمة عداد البرنامج في المكدس ، ويقفز إلى الغنوان 0004h في ذاكرة البرنامج ، حيث يقع روتين خدمة المقاطعة . ونظرا لأن جميع مصادر المقاطعة تجعل البرنامج يقفز إلى نفس المكان (0004h) ، فإنه يجب على المبرمج ، عند كتابة روتين خدمة المقاطعة ، أولا معرفة المصدر الذي طلب المقاطعة . ويتم ذلك من خلال قراءة البتات المناسبة في سجلات الوظيفة الخاصة ، INTCON و PIR1 ، المرتبطة بنظام المقاطعة . ويبين الشكل أدناه البتات في سجل التحكم في المقاطعة INTCON .
رد: ما هو الميكروكونترولر Microcontroller ؟
تدريب 1 :
الغرض :
دراسة كيفية برمجة المقاطعة الخارجية نتيجة تطبيق نبضة على الطرف RB0/INT .
من أجل تهيئة المقاطعة INT ، يجب أن تتم العمليات التالية:
1- يجب أن يتم تهيئةالطرف RB0 كدخل (وهو الوضع الافتراضى ) .
2- يجب تعيين مصدر المقاطعة لتكون الإشارة إما بحافة هابطة أو حافة صاعدة ، باستخدام البت INTEDG بالسجل OPTION_REG .
3- يجب أن تكون بت علم المقاطعة الخارجية (البت INTF بالسجل INTCON ) ممسوحة (صفر) كحالة ابتدائية .
4- يجب تمكين بت عموم المقاطعات عن طريق تحديد (واحد) البت GIE بالسجل INTCON .
5- يجب تمكين بت المقاطعة الخارجية INT من خلال تحديد (واحد) البت INTE بالسجل INTCON .
الدائرة الكهربية :
يتم توصيل مفتاح ضاغط إلى الطرف RB0 ، هذا المفتاح سوف ينتج مقاطعة عند الضغط عليه . كما يتم توصيل أربع ليدات حمراء إلى الأطراف RC0-RC3 وليد أصفر إلى الطرف RD0 .
البرنامج الرئيسى هو عداد تصاعدى ثنائى 4-bit والذى يتزايد بمعدل واحد ثانية تقريبا . يتم إرسال قيمة الغداد إلى المنفذ PORTC والغرض على الأربع ليدات الحمراء . اليد الصفراء يتم تحويلها ON و OFF عند الضغط على المفتاح .
المفتاح فعال فى الحالة المنخفضة ولذلك يتم برمجة المقاطعة على الحافة الهابطة (تغيير من 5V إلى 0V ) ، من خلال جعل INTEDG = 0 (الحالة الابتدائية بواحد) .
يعتمد روتين خدمة المقاطعة ISR على التطبيق المحدد . ومع ذلك ، تطبق بعض الخطوات على جميع الحالات . على سبيل المثال ، يجب أن يبدأ روتين خدمة المقاطعة بالتحقق من الحدث المحدد الذي تسبب في المقاطعة (إذا تم تمكين أكثر من مقاطعة ) . في هذه الحالة ، يجب فحص البت INTF من السجل INTCON للتحقق من أن مصدر المقاطعة هو من الطرف RB0/INT .
وبالمثل ، يجب أن يتم مسح علم المقاطعة (البتINTF من السجل INTCON ) بواسطة روتين خدمة المقاطعة قبل العودة إلى البرنامج الرئيسي وإلا ستحدث سلسلة لا نهاية لها من المقاطعات . وذلك لأنه عند العودة فإن وحدة المعالجة المركزية سوف تجد علم المقاطعة لا يزال فى حالة تعيين set ويفترض أنها مقاطعة أخرى ويقفز مرة أخرى إلى روتين خدمة المقاطعة .
فى الميكروكونترولر ، يقوم المعالج تلقائيا بمسح بت عموم المقاطعات GIE بالسجل INTCON عندما تحجث مقاطعة . هذا يعنى أنه لا يمكن وقوع مقاطعة فى روتين خدمة المقاطعة ، وإلا تخيل الفوضى التى سوف تحدث ما لم يكن ينبغى هذا الحال .
عندما يقوم المعالج بتنفيذ عبارة الرجوع فى روتين خدمة المقاطعة ، يتم تحديد set البت GIE ويتم تمكين المقاطعات مرة أخرى .
فى هذا التدريب سوف نستخدم المترجم ميكروسى برو . فى هذا المترجم يتم كتابة روتين خدمة المقاطعة مثل أى برنامج فرعى (دالة) آخر لكن مع استخدام الاسم بالكلمة الخاصة (المحجوزة) interrupt . داخل روتين خدمة المقاطعة يتم اختبار بتات الأعلام المناسبة للتعرف على مصدر المقاطعة .
البرنامج :
النتيجة :
سوف ترى أن الميكروكونترولر سوف يحافظ على العد من 0 إلى 15 ويلف مرة أخرى من الصفر ويستمر فى ذلك . فى أى وقت تقوم بالضغط على المفتاح الضاغط ، تحدث المقاطعة ، وسوف يستجيب المعالج إليها عن طريق تغيير حالة الليد الأصفر ، بعد ذلك سوف يستأنف مهمة العد .
الغرض :
دراسة كيفية برمجة المقاطعة الخارجية نتيجة تطبيق نبضة على الطرف RB0/INT .
من أجل تهيئة المقاطعة INT ، يجب أن تتم العمليات التالية:
1- يجب أن يتم تهيئةالطرف RB0 كدخل (وهو الوضع الافتراضى ) .
2- يجب تعيين مصدر المقاطعة لتكون الإشارة إما بحافة هابطة أو حافة صاعدة ، باستخدام البت INTEDG بالسجل OPTION_REG .
3- يجب أن تكون بت علم المقاطعة الخارجية (البت INTF بالسجل INTCON ) ممسوحة (صفر) كحالة ابتدائية .
4- يجب تمكين بت عموم المقاطعات عن طريق تحديد (واحد) البت GIE بالسجل INTCON .
5- يجب تمكين بت المقاطعة الخارجية INT من خلال تحديد (واحد) البت INTE بالسجل INTCON .
الدائرة الكهربية :
يتم توصيل مفتاح ضاغط إلى الطرف RB0 ، هذا المفتاح سوف ينتج مقاطعة عند الضغط عليه . كما يتم توصيل أربع ليدات حمراء إلى الأطراف RC0-RC3 وليد أصفر إلى الطرف RD0 .
البرنامج الرئيسى هو عداد تصاعدى ثنائى 4-bit والذى يتزايد بمعدل واحد ثانية تقريبا . يتم إرسال قيمة الغداد إلى المنفذ PORTC والغرض على الأربع ليدات الحمراء . اليد الصفراء يتم تحويلها ON و OFF عند الضغط على المفتاح .
المفتاح فعال فى الحالة المنخفضة ولذلك يتم برمجة المقاطعة على الحافة الهابطة (تغيير من 5V إلى 0V ) ، من خلال جعل INTEDG = 0 (الحالة الابتدائية بواحد) .
يعتمد روتين خدمة المقاطعة ISR على التطبيق المحدد . ومع ذلك ، تطبق بعض الخطوات على جميع الحالات . على سبيل المثال ، يجب أن يبدأ روتين خدمة المقاطعة بالتحقق من الحدث المحدد الذي تسبب في المقاطعة (إذا تم تمكين أكثر من مقاطعة ) . في هذه الحالة ، يجب فحص البت INTF من السجل INTCON للتحقق من أن مصدر المقاطعة هو من الطرف RB0/INT .
وبالمثل ، يجب أن يتم مسح علم المقاطعة (البتINTF من السجل INTCON ) بواسطة روتين خدمة المقاطعة قبل العودة إلى البرنامج الرئيسي وإلا ستحدث سلسلة لا نهاية لها من المقاطعات . وذلك لأنه عند العودة فإن وحدة المعالجة المركزية سوف تجد علم المقاطعة لا يزال فى حالة تعيين set ويفترض أنها مقاطعة أخرى ويقفز مرة أخرى إلى روتين خدمة المقاطعة .
فى الميكروكونترولر ، يقوم المعالج تلقائيا بمسح بت عموم المقاطعات GIE بالسجل INTCON عندما تحجث مقاطعة . هذا يعنى أنه لا يمكن وقوع مقاطعة فى روتين خدمة المقاطعة ، وإلا تخيل الفوضى التى سوف تحدث ما لم يكن ينبغى هذا الحال .
عندما يقوم المعالج بتنفيذ عبارة الرجوع فى روتين خدمة المقاطعة ، يتم تحديد set البت GIE ويتم تمكين المقاطعات مرة أخرى .
فى هذا التدريب سوف نستخدم المترجم ميكروسى برو . فى هذا المترجم يتم كتابة روتين خدمة المقاطعة مثل أى برنامج فرعى (دالة) آخر لكن مع استخدام الاسم بالكلمة الخاصة (المحجوزة) interrupt . داخل روتين خدمة المقاطعة يتم اختبار بتات الأعلام المناسبة للتعرف على مصدر المقاطعة .
البرنامج :
- الكود:
/*
Understanding Interrupts
*/
sbit LED at RD0_bit; // Interrupt LED
unsigned short count;
// Interrupt service routine
void interrupt(){
if(INTCON.INTF == 1) LED = ~LED;
delay_ms(200); // Key debounce time
INTCON.INTF = 0;
}
void main() {
TRISB.B0 = 1 ; // RB0 as input
TRISC = 0; // PORTC all outputs
TRISD = 0 ; // PORTD all outputs
PORTD = 0 ;
INTCON = 0b10010000; // Set GIEand INTE bits , INTCON.GIE=1; INTCON.INTE=1;
OPTION_REG.INTEDG = 0; // External interrupt on falling edge of RB0/INT pin
count = 0;
LED = 0;
PORTC = count;
do {
count ++;
if (count ==16) count =0;
PORTC = count;
delay_ms(1000);
}while (1); // infinite loop
}
النتيجة :
سوف ترى أن الميكروكونترولر سوف يحافظ على العد من 0 إلى 15 ويلف مرة أخرى من الصفر ويستمر فى ذلك . فى أى وقت تقوم بالضغط على المفتاح الضاغط ، تحدث المقاطعة ، وسوف يستجيب المعالج إليها عن طريق تغيير حالة الليد الأصفر ، بعد ذلك سوف يستأنف مهمة العد .
رد: ما هو الميكروكونترولر Microcontroller ؟
تدريب 2 :
الدائرة الكهربية :
البرنامج :
تدريب 3 :
الدائرة الكهربية :
البرنامج :
الدائرة الكهربية :
البرنامج :
- الكود:
/*
Etxernal Interrupt (INT- RB0)
* Description:
This is a simple interrupt demostration project.
All LEDs on PORTD will flash utill interrupt occurs (RB0 is pressed).
Interrupt will set local flag , which will cause Flashing routine to be executed.
*/
bit flag;
void Delay250() {
Delay_ms(250);
}
void Delay150() {
Delay_ms(150);
}
void Flash () { // Flashing rutine
PORTD.F1 = 1;
Delay150();
PORTD.F1 = 0;
Delay250(); Delay250();
PORTD.F1 = 1;
Delay150();
PORTD.F1 = 0;
Delay250(); Delay250();
}
void interrupt(){ // Interrupt rutine
if(INTF_bit == 1 ) { // Checks Receive Interrupt Flag bit
flag = 1; // Set local interrupt flag
INTF_bit = 0; // Clear Interrupt Flag
}
}
void main() {
flag = 0; // Varialbe initialisation
TRISB = 1; // Set PORT B (only RB0) as input
TRISD = 0; // Set PORT D as output
PORTD = 0x00; // Set all pin on PORT D Low
INTEDG_bit = 1; // Set interrupt on rising edge
INTF_bit = 0; // Clear INT0 flag
INTE_bit = 1; // Enable INT0 interrupts
GIE_bit = 1; // Enable GLOBAL interrupts
while(1) {
PORTD = 0xFF; // Set all pin on PORT D High
Delay250(); // Wait for some time
PORTD = 0x00; // Set all pin on PORT D Low
Delay150(); // Wait for some time
if(flag) { // Checks local interrupt flag
Flash(); // Do something
flag = 0; // Reset local interrupt flag
}
}
}
تدريب 3 :
الدائرة الكهربية :
البرنامج :
- الكود:
/*
* Project name:
Etxernal Interrupt (RB4:RB7)
* Description:
This is a simple interrupt demostration project.
All LEDs on PORTD will flash utill interrupt occurs.
Interrupt will set local flag, which will cause Flashing routine to be executed.
Depending on pressed button (RB4:RB7) different Flashing routine will be executed.
*/
char pressedButton;
bit flag;
void interrupt(){ // Interrupt rutine
if(RBIF_bit == 1 ) { // Checks for Receive Interrupt Flag bit
flag = 1; // Set local interrupt flag
RBIF_bit = 0; // Clear Interrupt Flag
if (PORTB.F7 == 1){ // Checks if the RB7 is pressed
pressedButton = 7;
}
if (PORTB.F6 == 1){ // Checks if the RB6 is pressed
pressedButton = 6;
}
if (PORTB.F5 == 1){ // Checks if the RB5 is pressed
pressedButton = 5;
}
if (PORTB.F4 == 1){ // Checks if the RB4 is pressed
pressedButton = 4;
}
}
}
void Delay250() {
Delay_ms(250); // Waits for 250 ms
}
void Delay150() {
Delay_ms(150); // Waits for 150 ms
}
void FlashIt(char hexCode){ // Flashes LEDs two times
PORTD = hexCode; // Writes hex to to PORTD
Delay150(); // Short pause
PORTD = 0; // Clears PORTD
Delay250(); Delay250(); // Pause
PORTD = hexCode; // Writes hex to to PORTD second time
Delay150(); // Short pause
PORTD = 0; // Clears PORTD
Delay250(); Delay250(); // Pause
}
void main() {
flag = 0; // Varialbe initialisation
pressedButton = 0;
TRISB = 0xFF; // Set PORT B as input
TRISD = 0; // Set PORT D as output
PORTD = 0x00; // Set all pin on PORT D Low
RBIE_bit = 1; // Enable Port B Interrupt-On-Change
RBIF_bit = 0; // Clear IOC flag
GIE_bit = 1; // Enable GLOBAL interrupts
while(1) {
PORTD = 0xFF; // Set all pin on PORT D High
Delay250(); // Wait for some time
PORTD = 0x00; // Set all pin on PORT D Low
Delay150(); // Wait for some time
if(flag) {
switch(pressedButton) { // Depending on value(button pressed), calls FleshIt function with different argument
case 4:
FlashIt(0x03);
pressedButton = 0;
break;
case 5:
FlashIt(0x0C);
pressedButton = 0;
break;
case 6:
FlashIt(0x30);
pressedButton = 0;
break;
case 7:
FlashIt(0xC0);
pressedButton = 0;
break;
default:
FlashIt(0xAA); // Just in case
break;
}
flag = 0; // Reset flag variable
}
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
تدريب 4 :
الدائرة الكهربية :
البرنامج :
الدائرة الكهربية :
البرنامج :
- الكود:
/*
* Project name:
Peripheral Interrupt (Interrupt while reciving data over UART)
* Description:
This is a simple interrupt demostration project.
uC will send some data for connectivty test.
Received data will be saved in buffer using interrut.
Last recived character will be diplayed on portD.
*/
char rxbuff[20]; // Buffer variable for storing data sent from master
char rxidx; // Counter for data writen in buffer
void interrupt() { // Interrupt rutine
if(RCIF_bit == 1) { // Checks for Receive Interrupt Flag bit
rxbuff[rxidx] = UART1_Read(); // Storing read data
rxidx++; // Incresing counter of read data
if(rxidx >= 20) // Checks if data is larger than buffer
rxidx = 0; // Reset counter
}
}
void main() {
rxidx = 0; // Initialisation of variable
TRISD = 0; // Configure PORTD as output
UART1_Init(19200); // Initialize UART module at 19200 bps
Delay_ms(100); // Wait for UART module to stabilize
UART1_Write_Text("Start"); // Send text
UART1_Write(13); // ASCII carriage return
UART1_Write(10); // ASCII line feed (new line)
PORTD = 0xFF; // Set all pin on PORT D High
Delay_ms(100); // Wait for some time
PORTD = 0x00; // Set all pin on PORT D Low
RCIE_bit = 1; // turn ON interrupt on UART1 receive
RCIF_bit = 0; // Clear interrupt flag
PEIE_bit = 1; // Enable peripheral interrupts
GIE_bit = 1; // Enable GLOBAL interrupts
while(1) {
if (rxidx == 0) { // Nothing is read, or buffer overflows
PORTD = rxbuff[rxidx]; // Do something(Show first char that will be overwriten)
}
else {
PORTD = rxbuff[rxidx-1]; // Show binary value of the read character on PORT D
}
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
تدريب 5 : التعامل مع مقاطعات متعددة
المقاطعات هى أحداث مجدولة والتى تجعل الميكروكونترولر PIC "يعلق" برنامجه القائم على تنفيذه ويقوم بتشغيل جزء من برنامج (برنامج فرعى يسمى روتين المقاطعة interrupt routine) مقترن بحدث .
عند اكتمال روتين المقاطعة يستمر PIC فى تنفيذ سريان البرنامج من عند نفس النقطة التى كان قد علق عندها التنفيذ.
مصادر المقاطعة تختلف تبعا لنوع الميكروكونترولر . على سبيل المثال الميكروكونترولر PIC 16F877A له 15 مصدر للمقاطعة مثل :
• المقاطعة بالمؤقت Timer0 عند حدوث طفحان بالمؤقت .
• المقاطعة عن تغيير حافة النبضة الخارجية على الطرف RB0 (تعرف بالمقاطعة الخارجية) .
• المقاطعة عند وصول البيانات التسلسلية خلال الوحدة USART .
• المقاطعة بالمحول من تناظرى لرقمى ADC عند انتهاء التحويل .
وغيرها من المقاطعات .
مترجم الميكروسى برو يتضمن دالة سابقة التعريف من أجل تنفيذ المقاطعة ، هذه الدالة هى "دالة أو روتين المقاطعة" وهى بالصيغة التالية :
void interrupt (void);
يجب إعلان هذه الدالة قبل الدالة الرئيسية .
عند حدوث مقاطعة يتم استدعاء "دالة المقاطعة" تلقائيا عن طريق البرنامج ، داخل هذه الدالة يجب تحديد ما هى المقاطعات التى يتم بدؤها وأعلام (معلمات - علامات) flags كل مقاطعة .
لإعداد المقاطعات يجب تفعيل البتات المناظرة بسجلات المقاطعة . فى الميكروكونترولر PIC16F877A ، على سبيل المثال ، سجلات المقاطعة هى : INTCON, PIR1, PIR2, PIE1 , PIE2 . الشكل التالى يبين هذه السجلات يالميكروكونترولر PIC 16F877A :
لتنفيذ المقاطعات يجب اتباع الخطوات المناسبة للإعداد مع مرعاة ما يلى :
• أولا يتم تفعيل المقاطعات المطلوب استخدامها عن طريق بت التمكين IEالمناسب مثل :
TMR0IE, INTE, RCIE وغيرها .
• يجب عدم تمكين أعلام المقاطعات مثل :
TMR0IF, INTF, RCIF وغيرها .
• يجب تمكين مقاطعات الطرفيات عندما يتطلب ذلك ، على سبيل المثال المقاطعات التابعة للسجلات :
PIE1 و PIE2.
• وأخيرا يتم تحديد set بت تمكين عموم المقاطعات : GIE .
المثال التالى سوف يستخدم فى : المقاطعة باستقبال الاتصال التسلسلى ، والمقاطعة بالمؤقت Timer 0 ، والمقاطعة الخارجية . لهذا الهدف يمكنك مراقبة وتحليل كود المصدر للبرنامج التالى :
لمحاكاة هذا البرنامج ببرنامج إيزيس يتم جلب الأجهزة التالية :
16F877A, RES, BUTTON, LED-RED والوحدة الطرفية التخيلية والأوسليسكوب .
بعد تشغيل المحاكاة يجب التفاعل مع الوحدة الطرفية لإرسال بيانات , بالمفتاح الضاغط يجب أن تشاهد حالة الليد وخرج الأوسليسكوب وعرض شكل الموجة المربعة يتغير كل 65.535 msec , تبعا للمؤقت Timer 0 .
الدائرة الكهربية :
المقاطعات هى أحداث مجدولة والتى تجعل الميكروكونترولر PIC "يعلق" برنامجه القائم على تنفيذه ويقوم بتشغيل جزء من برنامج (برنامج فرعى يسمى روتين المقاطعة interrupt routine) مقترن بحدث .
عند اكتمال روتين المقاطعة يستمر PIC فى تنفيذ سريان البرنامج من عند نفس النقطة التى كان قد علق عندها التنفيذ.
مصادر المقاطعة تختلف تبعا لنوع الميكروكونترولر . على سبيل المثال الميكروكونترولر PIC 16F877A له 15 مصدر للمقاطعة مثل :
• المقاطعة بالمؤقت Timer0 عند حدوث طفحان بالمؤقت .
• المقاطعة عن تغيير حافة النبضة الخارجية على الطرف RB0 (تعرف بالمقاطعة الخارجية) .
• المقاطعة عند وصول البيانات التسلسلية خلال الوحدة USART .
• المقاطعة بالمحول من تناظرى لرقمى ADC عند انتهاء التحويل .
وغيرها من المقاطعات .
مترجم الميكروسى برو يتضمن دالة سابقة التعريف من أجل تنفيذ المقاطعة ، هذه الدالة هى "دالة أو روتين المقاطعة" وهى بالصيغة التالية :
void interrupt (void);
يجب إعلان هذه الدالة قبل الدالة الرئيسية .
عند حدوث مقاطعة يتم استدعاء "دالة المقاطعة" تلقائيا عن طريق البرنامج ، داخل هذه الدالة يجب تحديد ما هى المقاطعات التى يتم بدؤها وأعلام (معلمات - علامات) flags كل مقاطعة .
لإعداد المقاطعات يجب تفعيل البتات المناظرة بسجلات المقاطعة . فى الميكروكونترولر PIC16F877A ، على سبيل المثال ، سجلات المقاطعة هى : INTCON, PIR1, PIR2, PIE1 , PIE2 . الشكل التالى يبين هذه السجلات يالميكروكونترولر PIC 16F877A :
لتنفيذ المقاطعات يجب اتباع الخطوات المناسبة للإعداد مع مرعاة ما يلى :
• أولا يتم تفعيل المقاطعات المطلوب استخدامها عن طريق بت التمكين IEالمناسب مثل :
TMR0IE, INTE, RCIE وغيرها .
• يجب عدم تمكين أعلام المقاطعات مثل :
TMR0IF, INTF, RCIF وغيرها .
• يجب تمكين مقاطعات الطرفيات عندما يتطلب ذلك ، على سبيل المثال المقاطعات التابعة للسجلات :
PIE1 و PIE2.
• وأخيرا يتم تحديد set بت تمكين عموم المقاطعات : GIE .
المثال التالى سوف يستخدم فى : المقاطعة باستقبال الاتصال التسلسلى ، والمقاطعة بالمؤقت Timer 0 ، والمقاطعة الخارجية . لهذا الهدف يمكنك مراقبة وتحليل كود المصدر للبرنامج التالى :
- الكود:
//1-declaration interrupt function.
void interrupt ( void )
{
//A-Declaration of variables used in interrupt function.
char Data;
//B-Evaluates whether the interrupt is triggered by Timer 0, TMR0IF
if( INTCON.F2==1 )
{
//It complements the bit value RB1.
if(PORTB.F1==1)
PORTB.F1=0;
else
PORTB.F1=1;
// Turned off Timer 0 Flag.
INTCON.F2=0;
}
//C-Evaluates whether the external interrupt is triggered.
// INTF
if( INTCON.F1==1 )
{
//It complements the bit value RB2.
if(PORTB.F2==1)
PORTB.F2=0;
else
PORTB.F2=1;
//It turns off the external interrupt flag.
INTCON.F1=0;
}
//D-Evaluates whether the interruption triggered by serial reception.
if( PIR1.F5 ==1)
{
//It reads the input data.
Data = UART1_Read();
//Confirmation information is sent.
UART1_Write_Text("Input data: ");
//It sends the data received.
UART1_Write(Data);
UART1_Write(13); //ASCII code is sent enter.
UART1_Write(10); //and sends carriage return code.
//It reception apparatus for serial flag.
PIR1.F5 = 0;
}
}
void main( void )
{
//Ports are configured.
TRISB = 0b00000001;
PORTB = 0;
//Activates the serial receive interrupt.
PIE1 = 0b00100000;
//Other interrupt sources are disabled .
PIE2 = 0;
//Turn off interrupt flags.
PIR2 = 0;
PIR1 = 0;
//Setting the Timer 0 to 65.535 m Sec
OPTION_REG=0b11000111;
//Configuring the serial port at 9600 bps.
UART1_Init(9600);
//Global interrupts are enabled,
//for Timer 0, and external.
INTCON = 0b11110000;
while(1) //Infinite Loop.
{
}
}
لمحاكاة هذا البرنامج ببرنامج إيزيس يتم جلب الأجهزة التالية :
16F877A, RES, BUTTON, LED-RED والوحدة الطرفية التخيلية والأوسليسكوب .
بعد تشغيل المحاكاة يجب التفاعل مع الوحدة الطرفية لإرسال بيانات , بالمفتاح الضاغط يجب أن تشاهد حالة الليد وخرج الأوسليسكوب وعرض شكل الموجة المربعة يتغير كل 65.535 msec , تبعا للمؤقت Timer 0 .
الدائرة الكهربية :
رد: ما هو الميكروكونترولر Microcontroller ؟
المؤقتات Timers والعدادات Counters
الميكروكونترولر PIC مجهز بوحدة (موديول) أو أكثر للتوقيت الدقيق تعرف باسم المؤقتات Timers والتى يمكن استخدامها لتنفيذ مجموعة متنوعة من وظائف التوقيت الدقيقة مثل توليد أحداث في أوقات محددة ، وقياس مدة (فترة دوام) duration حدث وحفظ تسجيل التاريخ والوقت وعد الأحداث counting وما إلى ذلك.
العنصر الرئيسي فى وحدة (موديول) المؤقت هو "عداد ثنائى حر يتزايد عند كل نبضة ترد إليه" ، ونظرا لأنه يعمل بشكل مستقل فإنه يمكن أن يعد النبضات فى وقت واحد (بالتزامن) مع تنفيذ البرنامج الرئيسي .
يمتلك الميكروكونترولر PIC16F877A ، على سبيل المثال ، ثلاثة من المؤقتات كأجهزة hardware مدمجة به وتسمى Timer0 و Timer1و Timer2 وسوف نتناول فى هذا الدرس وحدة (موديول) المؤقت Timer0.
وحدة (موديول) المؤقت / العداد Timer 0 :
وحدة (موديول) المؤقت / العداد timer/counter module ببساطة هى عداد ثنائى binary counter مستقل والذى يمكن تهيئته (إعداده) لكى يقوم بعد نبضات ساعة دورات التعليمات الداخلية ( تردد الكريستال مقسوما على 4 ) أو عد نبضات ساعة خارجية .
المؤقت Timer 0 هو عداد متزامن بسعة 8 بتات 8-bit والذى يقوم بحفظ (تخزين) قيمة العداد فى سجل وظائف خاصة يسمى TMR0 . هذا السجل قابل للقراءة وللكتابة فى أى وقت عن طريق البرنامج . إذا كتبت قيمة عليه فسوف يبدأ العداد التزايد من هذه القيمة .
عندما يتم تشغيل الموديول Timer 0 بنبضات ساعة تعليمات المعالج فيقال أنه يعمل كمؤقت timer لأنه يتزايد بمعدل ثابت ( يتحدد بنبضات ساعة المعالج) ، وإذا علمت عدد النبضات التى قام بعدها يمكنك إشتقاق (إستنتاج) الوقت المنقضى .
يمكن للمؤقت Timer 0 أيضا عد النبضات الخارجية الواصلة إلى الطرف RA4 المسمى
T0CKI (Timer Zero Clock Input) " مدخل نبضات الساعة للمؤقت صفر " . عندما يقوم الموديول بعد النبضات الخارجية يقال أنه يعمل كعداد counter . سوف نناقش نظامى العمل كل على حدة .
نظام المؤقت Timer mode
• يتم اختيار نظام المؤقت بمسح clear البت T0CS " بت اختيار مصدر ساعة المؤقت Timer0 " وهى البت 5 بسجل الخيارات : (OPTION register, bit 5) إى T0CS=0.
• فى نظام المؤقت يتزايد السجل TMR0 عند كل دورة تعليمة ، ولأن هذا السجل ذو سعة 8-bit فيمكنه العد من الصفر 00 إلى FF (255) ، وعندما يصل إلى أقصى قيمة له وهى FF (255) ويتقدم (يتجاوز) فى التزايد يعود للعد من الصفر 00 من جديد وتعرف هذه الحالة بالطفحان overflow (تجاوز الحد الأقصى) ويتم تسجيل هذه الحالة عن طريق "رفع علم أو راية البت T0IF " بت علم مقاطعة المؤقت Timer0 " (Timer0 Interrupt Flag) وهى البت 3 بسجل التحكم فى المقاطعة : (INTCON,bit 3) (Interrupt Control) وذلك بجعلها بالقيمة set أى T0IF=1 ، حيث يمكن لهذه الحالة بدء (توليد) مقاطعة والتى تعرف باسم " المقاطعة بالمؤقت صفر " Timer0 Interrupt إذا ما كانت ممكنة لعمل مقاطعة .
• يتم تمكين مقاطعة المؤقت Timer0 بجعل البت T0IE (Timer0 Interrupt Enable) " تمكين المقاطعة بالمؤقت صفر " بسجل التحكم فى المقاطعة ( INTCON,bit5) بجعلها بالقيمة set أى T0IE=1 بالأضافة إلى خانة التمكين العام GIE ( INTCON,bit7). هذه المقاطعة هى التى يجب أن تبين أن الوقت إنتهى وتحدث عند حدوث طفحان بالسجل TMR0 .
• يجب مسح clear الخانة T0IF " علم مقاطعة المؤقت صفر " بواسطة روتين خدمة المقاطعة بحيث يمكن حدوث مقاطعة بالمؤقت من جديد أى T0IF=0.
مثال :
نفترض أن الميكروكونترولر PIC يعمل على مذبذب ساعة بتردد Fosc =4 MHz فإن تردد نبضات ساعة التعليمات سوف تكون Fosc /4 = 1 MHz . نتيجة لذلك يقوم العداد بالتزايد كل واحد ميكروثانية 1 μs بالضبط . وهذا يعنى أن المؤقت Timer0 سوف يستغرق 256 μs لكى يعد من الصفر إلى الصفر التالى .
عن طريق تحميل سجل المؤقت TMR0 بقيمة مسبقة مناسبة يمكن اختيار فترات زمنية أصغر .على سبيل المثال إذا تم تحميل السجل TMR0 مسبقا بالقيمة 206 فإن المؤقت Timer0 سوف يحدث له طفحان بعد 50 μs فقط .
• علاوة على ذلك يوجد قاسم تردد مبرمج بسعة 8-bit يعرف باسم prescaler "المقياس المسبق " أو " معامل القسمة " وهو متاح لقياس الفترات الزمنية الطويلة . والمقياس المسبق هو دائرة قسمة تقع بين مصدر نبضات الساعة والمؤقت وتقوم بقسمة التردد الداخل إلى المؤقت على قيمة من ثمانى قيم ثنائية تقع ما بين القيمة 2 والقيمة 256 .
مثال :
إذا كان تردد نبضات ساعة التعليمات 1MHz فإن أقصى فترة زمنية تناظر أكبر معامل قسمة وهو 256 أى :
• قيم معامل القسمة يتم اختيارها برمجيا بواسطة البتات الثلاثة : PS0, PS1,PS2 " بتات اختيار معامل القسمة " بسجل الخيارات (OPTION,bit0-bit2) .
• من أجل تخصيص استخدام معامل القسمة مع موديول المؤقت Timer0 يجب مسح clear = 0 البت PSA " تخصيص معامل القسمة " أى PSA=0. إما إذا كانت الخانة PSA بواحد set = 1 فلا يتم تخصيص أى معامل قسمة لموديول المؤقت (1 : 1 ) .
فيما يلى تفاصيل سجل الخيارات OPTION_REG وسجل التحكم فى المقاطعة INTCON للرجوع إليها عند الحاجة:
نظام العداد Counter Mode
يتم اختيار نظام العداد بجعل البت T0CSبالسجل OPTION بواحد set = 1 أى T0CS=1.
فى هذا النظام يقوم موديول المؤقت Timer0 بعد نبضات الساعة الخارجية الموجودة على الطرف RA4/T0CKI. يتزايد المؤقت سواء عند الحافة الصاعدة أو عند الحافة الهابطة لنبضات الساعة ويتم اختيار ذلك برمجيا بواسطة البت T0SE (Timer0 Source Edge) " حافة مصدر المؤقت صفر " بسجل الخيارات (OPTION,bit4) . إذا كانت هذه البت بواحد set أى T0SE=1 فسوف يتزايد المؤقت عند الحافة الهابطة لكل نبضة من نبضات الساعة التى تصل إلى الطرف RA4/T0CKI (عند الانتقال من الحالة المرتفعة إلى الحالة المنخفضة ) . مرة أخرى يمكن توسعة أو تمديد مدى العداد باستخدام prescaler .
الميكروكونترولر PIC مجهز بوحدة (موديول) أو أكثر للتوقيت الدقيق تعرف باسم المؤقتات Timers والتى يمكن استخدامها لتنفيذ مجموعة متنوعة من وظائف التوقيت الدقيقة مثل توليد أحداث في أوقات محددة ، وقياس مدة (فترة دوام) duration حدث وحفظ تسجيل التاريخ والوقت وعد الأحداث counting وما إلى ذلك.
العنصر الرئيسي فى وحدة (موديول) المؤقت هو "عداد ثنائى حر يتزايد عند كل نبضة ترد إليه" ، ونظرا لأنه يعمل بشكل مستقل فإنه يمكن أن يعد النبضات فى وقت واحد (بالتزامن) مع تنفيذ البرنامج الرئيسي .
يمتلك الميكروكونترولر PIC16F877A ، على سبيل المثال ، ثلاثة من المؤقتات كأجهزة hardware مدمجة به وتسمى Timer0 و Timer1و Timer2 وسوف نتناول فى هذا الدرس وحدة (موديول) المؤقت Timer0.
وحدة (موديول) المؤقت / العداد Timer 0 :
وحدة (موديول) المؤقت / العداد timer/counter module ببساطة هى عداد ثنائى binary counter مستقل والذى يمكن تهيئته (إعداده) لكى يقوم بعد نبضات ساعة دورات التعليمات الداخلية ( تردد الكريستال مقسوما على 4 ) أو عد نبضات ساعة خارجية .
المؤقت Timer 0 هو عداد متزامن بسعة 8 بتات 8-bit والذى يقوم بحفظ (تخزين) قيمة العداد فى سجل وظائف خاصة يسمى TMR0 . هذا السجل قابل للقراءة وللكتابة فى أى وقت عن طريق البرنامج . إذا كتبت قيمة عليه فسوف يبدأ العداد التزايد من هذه القيمة .
عندما يتم تشغيل الموديول Timer 0 بنبضات ساعة تعليمات المعالج فيقال أنه يعمل كمؤقت timer لأنه يتزايد بمعدل ثابت ( يتحدد بنبضات ساعة المعالج) ، وإذا علمت عدد النبضات التى قام بعدها يمكنك إشتقاق (إستنتاج) الوقت المنقضى .
يمكن للمؤقت Timer 0 أيضا عد النبضات الخارجية الواصلة إلى الطرف RA4 المسمى
T0CKI (Timer Zero Clock Input) " مدخل نبضات الساعة للمؤقت صفر " . عندما يقوم الموديول بعد النبضات الخارجية يقال أنه يعمل كعداد counter . سوف نناقش نظامى العمل كل على حدة .
نظام المؤقت Timer mode
• يتم اختيار نظام المؤقت بمسح clear البت T0CS " بت اختيار مصدر ساعة المؤقت Timer0 " وهى البت 5 بسجل الخيارات : (OPTION register, bit 5) إى T0CS=0.
• فى نظام المؤقت يتزايد السجل TMR0 عند كل دورة تعليمة ، ولأن هذا السجل ذو سعة 8-bit فيمكنه العد من الصفر 00 إلى FF (255) ، وعندما يصل إلى أقصى قيمة له وهى FF (255) ويتقدم (يتجاوز) فى التزايد يعود للعد من الصفر 00 من جديد وتعرف هذه الحالة بالطفحان overflow (تجاوز الحد الأقصى) ويتم تسجيل هذه الحالة عن طريق "رفع علم أو راية البت T0IF " بت علم مقاطعة المؤقت Timer0 " (Timer0 Interrupt Flag) وهى البت 3 بسجل التحكم فى المقاطعة : (INTCON,bit 3) (Interrupt Control) وذلك بجعلها بالقيمة set أى T0IF=1 ، حيث يمكن لهذه الحالة بدء (توليد) مقاطعة والتى تعرف باسم " المقاطعة بالمؤقت صفر " Timer0 Interrupt إذا ما كانت ممكنة لعمل مقاطعة .
• يتم تمكين مقاطعة المؤقت Timer0 بجعل البت T0IE (Timer0 Interrupt Enable) " تمكين المقاطعة بالمؤقت صفر " بسجل التحكم فى المقاطعة ( INTCON,bit5) بجعلها بالقيمة set أى T0IE=1 بالأضافة إلى خانة التمكين العام GIE ( INTCON,bit7). هذه المقاطعة هى التى يجب أن تبين أن الوقت إنتهى وتحدث عند حدوث طفحان بالسجل TMR0 .
• يجب مسح clear الخانة T0IF " علم مقاطعة المؤقت صفر " بواسطة روتين خدمة المقاطعة بحيث يمكن حدوث مقاطعة بالمؤقت من جديد أى T0IF=0.
مثال :
نفترض أن الميكروكونترولر PIC يعمل على مذبذب ساعة بتردد Fosc =4 MHz فإن تردد نبضات ساعة التعليمات سوف تكون Fosc /4 = 1 MHz . نتيجة لذلك يقوم العداد بالتزايد كل واحد ميكروثانية 1 μs بالضبط . وهذا يعنى أن المؤقت Timer0 سوف يستغرق 256 μs لكى يعد من الصفر إلى الصفر التالى .
عن طريق تحميل سجل المؤقت TMR0 بقيمة مسبقة مناسبة يمكن اختيار فترات زمنية أصغر .على سبيل المثال إذا تم تحميل السجل TMR0 مسبقا بالقيمة 206 فإن المؤقت Timer0 سوف يحدث له طفحان بعد 50 μs فقط .
• علاوة على ذلك يوجد قاسم تردد مبرمج بسعة 8-bit يعرف باسم prescaler "المقياس المسبق " أو " معامل القسمة " وهو متاح لقياس الفترات الزمنية الطويلة . والمقياس المسبق هو دائرة قسمة تقع بين مصدر نبضات الساعة والمؤقت وتقوم بقسمة التردد الداخل إلى المؤقت على قيمة من ثمانى قيم ثنائية تقع ما بين القيمة 2 والقيمة 256 .
مثال :
إذا كان تردد نبضات ساعة التعليمات 1MHz فإن أقصى فترة زمنية تناظر أكبر معامل قسمة وهو 256 أى :
- الكود:
256 x 256 μs = 65.536 ms
• قيم معامل القسمة يتم اختيارها برمجيا بواسطة البتات الثلاثة : PS0, PS1,PS2 " بتات اختيار معامل القسمة " بسجل الخيارات (OPTION,bit0-bit2) .
• من أجل تخصيص استخدام معامل القسمة مع موديول المؤقت Timer0 يجب مسح clear = 0 البت PSA " تخصيص معامل القسمة " أى PSA=0. إما إذا كانت الخانة PSA بواحد set = 1 فلا يتم تخصيص أى معامل قسمة لموديول المؤقت (1 : 1 ) .
فيما يلى تفاصيل سجل الخيارات OPTION_REG وسجل التحكم فى المقاطعة INTCON للرجوع إليها عند الحاجة:
نظام العداد Counter Mode
يتم اختيار نظام العداد بجعل البت T0CSبالسجل OPTION بواحد set = 1 أى T0CS=1.
فى هذا النظام يقوم موديول المؤقت Timer0 بعد نبضات الساعة الخارجية الموجودة على الطرف RA4/T0CKI. يتزايد المؤقت سواء عند الحافة الصاعدة أو عند الحافة الهابطة لنبضات الساعة ويتم اختيار ذلك برمجيا بواسطة البت T0SE (Timer0 Source Edge) " حافة مصدر المؤقت صفر " بسجل الخيارات (OPTION,bit4) . إذا كانت هذه البت بواحد set أى T0SE=1 فسوف يتزايد المؤقت عند الحافة الهابطة لكل نبضة من نبضات الساعة التى تصل إلى الطرف RA4/T0CKI (عند الانتقال من الحالة المرتفعة إلى الحالة المنخفضة ) . مرة أخرى يمكن توسعة أو تمديد مدى العداد باستخدام prescaler .
رد: ما هو الميكروكونترولر Microcontroller ؟
التدريب على نظام المؤقت :
مقدمة :
فى البداية سوف نتناول خطوة بخطوة إعداد الأجزاء المختلفة لموديول المؤقت باستخدام سجل الخيارات OPTION_REG :
1- اختيار مصدر المؤقت Timer كما فى الشكل التالى :
البت T0CS : بت اختيار مصدر ساعة المؤقت Timer0 .
T0CS=1 : نظام العداد : الإشارة الموجودة على الطرف T0CKI (Timer0 Clock Input) تستخدم كمصدر للمؤقت Timer0 .
T0CS=0 : نظام مؤقت : تستخدم ساعة التعليمات الداخلية كمصدر للمؤقت Timer0 .
ملحوظة :
دورة التعليمات الداخلية تساوى تردد مذبذب الميكروكونترولر مقسوم على أربعة Fosc/4 .
2- اختيار حافة المصدر ( للمصدر الخارجى فقط أى فى نظام العداد) :
البت T0SE : بت اختيار حافة مصدر المؤقت Timer0 .
T0SE=1 : يتزايد السجل TMR0 عند إنتقال حالة الطرف T0CKI من الحالة المرتفعة إلى الحالة المنخفضة ( الحافة الهابطة) .
T0SE=0 : يتزايد السجل TMR0 عند إنتقال حالة الطرف T0CKI من الحالة المنخفضة إلى الحالة المرتفعة ( الحافة الصاعدة) .
3- تخصيص وإعداد معامل قسمة التردد Prescaler :
يخصص معامل القسمة عن طريق البرنامج إما للمؤقت Timer0 أو لمؤقت الحراسة . لتخصيص معامل القسمة للمؤقت Timer0 يجب مسح خانة التخصيص PSA .
البت PSA : بت تخصيص معامل القسمة Prescaler .
PSA=1 : تخصيص معامل القسمة لمؤقت الحراسة .
PSA=0 : تخصيص معامل القسمة لموديول المؤقت Timer0 .
قيمة معامل القسمة prescaler سوف تحدد كم عدد حواف المصدر سوف تؤدى إلى تزايد السجل TMR0 بواحد . يمكن إعداد معامل القسمة ليأخذ أحد قيم النسب الثمانية من 1:1 إلى 1:256 .
البتات PS2:PS0 : بتات اختيار معدل معامل القسمة Prescaler.
4- أعدادات مقاطعة المؤقت TIMER0
تمهيد:
سوف يأتى الوقت الذى تريد فيه أن يكرس المعالج إهتمامه ، نتيجة لوقوع حدث ما ، لمهمة أخرى (غير مهمته العادية التى يقوم بها) ويقوم بخدمتها مثل زيادة متغير عداد عندما يرتفع علم مقاطعة المؤقت T0IF نتيجة حدوث تجاوز overflow بسجل المؤقت TMR0 بدون الحاجة للتحقق من حالتها بصفة مستمرة .
يمكن تحقيق ذلك بسهولة عن طريق روتين خدمة المقاطعة “ISR”.
عندما تحدث المقاطعة ، ويمكن أن يكون هناك أكثر من مقاطعة ، يتوقف المعالج على الفور عما يفعل فى البرنامج العادى ويقفز إلى روتين خدمة المقاطعة لخدمة المقاطعة . بمجرد الانتهاء من تقديم هذه الخدمة يعود المعالج إلى ما كان يفعله فى البرنامج العادى قبل المقاطعة .
إعداد مقاطعة المؤقت TIMER0 :
يمكن الإعداد لتوليد مقاطعة عندما يتجاوز السجل TMR0 العد من 255 إلى 0 ويتم ذلك عن طريق سجل التحكم فى المقاطعة INTCON كما فى الشكل التالى :
يتم إعداد إى مقاطعة عن طريق ثلاثة بتات أساسية :
• البت الأولى : "بت تمكين عموم المقاطعة" (GIE) , ويجب تمكينها GIE=1 لأن الحالة الافتراضية لها هى عدم التمكين GIE=0 . هذه البت تعمل كنوع من المفتاح الرئيسى الذى يجب رفعه (توصيله) set , GIE=1لتمكين قدرة الميكروكونترولر على المقاطعة . هذه البت سوف يتم مسحها clear "تلقائيا " GIE=0 كلما حدثت مقاطعة لضمان عدم حدوث أى مقاطعة أخرى خلال تنفيذ روتين خدمة المقاطعة . الحالة الافتراضية لهذه البت هى عدم التمكين GIE=0 .
لذلك بمجرد أن يكتمل روتين خدمة المقاطعة يجب جعل هذه البت GIE=1 مرة أخرى لتمكين المقاطعات فى المستقبل .
• البت الثانية : " بت تمكين المقاطعة بالمؤقت Timer0 " (T0IE) ، ويجب تمكينها T0IE=1 لأن الحالة الافتراضية لهذه البت هى عدم التمكين T0IE=0 .
• البت الثالثة : " بت علم تجاوز المؤقت Timer0" (T0IF) . عند حدوث تجاوز Overflow تتحول هذه البت إلى الحالة المرتفعة T0IF=1 وتظل على هذه الحالة حتى يتم مسحها عن طريق البرنامج . هذه البت تحتاج لمسحها إذا كنا نريد مقاطعة أخرى T0IF=0.
ينصح باتباع الخطوات التالية عند إعداد أى مقاطعة وتتبع أى روتين خدمة المقاطعة :
1- مسح clear بت علم المقاطعة ، وهى هنا T0IF=0 .
2- تمكين بت المقاطعة بالموديول المحدد ، وهى هنا T0IE .
3- تمكين بت عموم المقاطعة GIE=1 .
الإعداد بهذه الخطوات سوف يضمن عدم حدوث المقاطعة خلال التهيئة للبدء والذى يتسبب فى نتائج غير متوقعة .
مثال لروتين خدمة مقاطعة المؤقت Timer0 (مثال المترجم ميكروسى برو) :
فيما يلى مثال بسيط للتعامل مع المقاطعات من المؤقت TMR0 ( إذا لم يسمح لمقاطعات أخرى ) :
فى حالة تمكين مقاطعات متعددة ، تحتاج لاختبار المقاطعات التى تقع ، ومن ثم تقديم الكود المناسب :
مثال آخر :
باختصار :
من أجل استخدام المؤقت TMR0 بشكل صحيح ينبغى :
الخطوة الأولى : اختيار نظام العمل :
• يتم اختيار تظام عمل المؤقت عن طؤيق البت T0CS بالسجل OPTION_REG ، T0CS: 0=timer ، T0CS: 1= counter .
• عند الاستخدام ، يجب تخصيص معامل القسمة prescaler للمؤقت / العداد عن طريق مسح (0) البت PSA بالسجل OPTION_REG . يتم تحديد معدل معامل القسمة عن طريق البتنات PS2-PS0 بنفس السجل .
• عند استخدام المقاطعة ، يجب تحديد (1) البتات GIE و TMR0IE بالسجل INTCON .
الخطوة الثانية : القياس والعد
لقياس الزمن :
• قم بعمل Reset (صفر) للسجل TMR0 أو اكتب إليه قيمة معروفة .
• يتم قياس الزمن المنقضى (بالميكروثانية عندما تستخدم كريستال بتردد 4MHz ) عن طريق قراءة السجل TMR0 .
• بت العلم TMR0IF بالسجل INTCON يتم تلقائيا تحديدها (1) فى كل مرة يحدث طفحان overflow فى السجل TMR0 ، إذا كان قد تم تمكينها ، وتحدث مقاطعة .
لعد النبضات :
• يتم اختيار قطبية النبضات المراد عدها من على الطرف RA4 عن طريق البت T0SE بالسجل OPTION_REG ، (T0SE: 0=positive, 1=negative pulses) .
• يمكن قياس عدد النبضات عن طريق قراءة السجل TMR0 . يتم استخدام معامل القسمة والمقاطعة بنفس إسلوب نظام المؤقت .
مقدمة :
فى البداية سوف نتناول خطوة بخطوة إعداد الأجزاء المختلفة لموديول المؤقت باستخدام سجل الخيارات OPTION_REG :
1- اختيار مصدر المؤقت Timer كما فى الشكل التالى :
البت T0CS : بت اختيار مصدر ساعة المؤقت Timer0 .
T0CS=1 : نظام العداد : الإشارة الموجودة على الطرف T0CKI (Timer0 Clock Input) تستخدم كمصدر للمؤقت Timer0 .
T0CS=0 : نظام مؤقت : تستخدم ساعة التعليمات الداخلية كمصدر للمؤقت Timer0 .
ملحوظة :
دورة التعليمات الداخلية تساوى تردد مذبذب الميكروكونترولر مقسوم على أربعة Fosc/4 .
2- اختيار حافة المصدر ( للمصدر الخارجى فقط أى فى نظام العداد) :
البت T0SE : بت اختيار حافة مصدر المؤقت Timer0 .
T0SE=1 : يتزايد السجل TMR0 عند إنتقال حالة الطرف T0CKI من الحالة المرتفعة إلى الحالة المنخفضة ( الحافة الهابطة) .
T0SE=0 : يتزايد السجل TMR0 عند إنتقال حالة الطرف T0CKI من الحالة المنخفضة إلى الحالة المرتفعة ( الحافة الصاعدة) .
3- تخصيص وإعداد معامل قسمة التردد Prescaler :
يخصص معامل القسمة عن طريق البرنامج إما للمؤقت Timer0 أو لمؤقت الحراسة . لتخصيص معامل القسمة للمؤقت Timer0 يجب مسح خانة التخصيص PSA .
البت PSA : بت تخصيص معامل القسمة Prescaler .
PSA=1 : تخصيص معامل القسمة لمؤقت الحراسة .
PSA=0 : تخصيص معامل القسمة لموديول المؤقت Timer0 .
قيمة معامل القسمة prescaler سوف تحدد كم عدد حواف المصدر سوف تؤدى إلى تزايد السجل TMR0 بواحد . يمكن إعداد معامل القسمة ليأخذ أحد قيم النسب الثمانية من 1:1 إلى 1:256 .
البتات PS2:PS0 : بتات اختيار معدل معامل القسمة Prescaler.
4- أعدادات مقاطعة المؤقت TIMER0
تمهيد:
سوف يأتى الوقت الذى تريد فيه أن يكرس المعالج إهتمامه ، نتيجة لوقوع حدث ما ، لمهمة أخرى (غير مهمته العادية التى يقوم بها) ويقوم بخدمتها مثل زيادة متغير عداد عندما يرتفع علم مقاطعة المؤقت T0IF نتيجة حدوث تجاوز overflow بسجل المؤقت TMR0 بدون الحاجة للتحقق من حالتها بصفة مستمرة .
يمكن تحقيق ذلك بسهولة عن طريق روتين خدمة المقاطعة “ISR”.
عندما تحدث المقاطعة ، ويمكن أن يكون هناك أكثر من مقاطعة ، يتوقف المعالج على الفور عما يفعل فى البرنامج العادى ويقفز إلى روتين خدمة المقاطعة لخدمة المقاطعة . بمجرد الانتهاء من تقديم هذه الخدمة يعود المعالج إلى ما كان يفعله فى البرنامج العادى قبل المقاطعة .
إعداد مقاطعة المؤقت TIMER0 :
يمكن الإعداد لتوليد مقاطعة عندما يتجاوز السجل TMR0 العد من 255 إلى 0 ويتم ذلك عن طريق سجل التحكم فى المقاطعة INTCON كما فى الشكل التالى :
يتم إعداد إى مقاطعة عن طريق ثلاثة بتات أساسية :
• البت الأولى : "بت تمكين عموم المقاطعة" (GIE) , ويجب تمكينها GIE=1 لأن الحالة الافتراضية لها هى عدم التمكين GIE=0 . هذه البت تعمل كنوع من المفتاح الرئيسى الذى يجب رفعه (توصيله) set , GIE=1لتمكين قدرة الميكروكونترولر على المقاطعة . هذه البت سوف يتم مسحها clear "تلقائيا " GIE=0 كلما حدثت مقاطعة لضمان عدم حدوث أى مقاطعة أخرى خلال تنفيذ روتين خدمة المقاطعة . الحالة الافتراضية لهذه البت هى عدم التمكين GIE=0 .
لذلك بمجرد أن يكتمل روتين خدمة المقاطعة يجب جعل هذه البت GIE=1 مرة أخرى لتمكين المقاطعات فى المستقبل .
• البت الثانية : " بت تمكين المقاطعة بالمؤقت Timer0 " (T0IE) ، ويجب تمكينها T0IE=1 لأن الحالة الافتراضية لهذه البت هى عدم التمكين T0IE=0 .
• البت الثالثة : " بت علم تجاوز المؤقت Timer0" (T0IF) . عند حدوث تجاوز Overflow تتحول هذه البت إلى الحالة المرتفعة T0IF=1 وتظل على هذه الحالة حتى يتم مسحها عن طريق البرنامج . هذه البت تحتاج لمسحها إذا كنا نريد مقاطعة أخرى T0IF=0.
ينصح باتباع الخطوات التالية عند إعداد أى مقاطعة وتتبع أى روتين خدمة المقاطعة :
1- مسح clear بت علم المقاطعة ، وهى هنا T0IF=0 .
2- تمكين بت المقاطعة بالموديول المحدد ، وهى هنا T0IE .
3- تمكين بت عموم المقاطعة GIE=1 .
الإعداد بهذه الخطوات سوف يضمن عدم حدوث المقاطعة خلال التهيئة للبدء والذى يتسبب فى نتائج غير متوقعة .
مثال لروتين خدمة مقاطعة المؤقت Timer0 (مثال المترجم ميكروسى برو) :
فيما يلى مثال بسيط للتعامل مع المقاطعات من المؤقت TMR0 ( إذا لم يسمح لمقاطعات أخرى ) :
- الكود:
void interrupt() {
counter++;
TMR0 = 96;
INTCON.TMR0IF = 0; //TMR0 interrupt flag must be cleared in software
//to allow subsequent interrupts
}
فى حالة تمكين مقاطعات متعددة ، تحتاج لاختبار المقاطعات التى تقع ، ومن ثم تقديم الكود المناسب :
- الكود:
void interrupt() {
if (INTCON.TMR0IF) { //are TMR0 interrupts enabled
counter++;
TMR0 = 96;
INTCON.TMR0IF = 0;
}
else if (INTCON.RBIF) {
counter++;
INTCON.RBIF = 0;
}
}
مثال آخر :
- الكود:
// In this example, TMR0 is configured as a timer and prescaler is assigned to it.
unsigned cnt; // Define variable cnt
void interrupt() { // Interrupt routine
cnt++; // Interrupt causes cnt to be incremented by 1
TMR0 = 155; // Timer (or counter) TMR0 returns its initial value
INTCON = 0x20; // Bit T0IE is set, bit T0IF is cleared
}
void main() {
OPTION_REG = 0x04; // Prescaler (1:32) is assigned to the timer TMR0
TMR0 = 155; // Timer T0 counts from 155 to 255
INTCON = 0xA0; // Enable interrupt TMR0
...
...
// In the following example,TMR0 is configured as counter and prescaler is assigned to it
OPTION_REG = 0x20; // Prescaler (1:2) is assigned to the counter TMR0
TMR0 = 155; // Counter T0 counts from 155 to 255
INTCON = 0xA0; // Enable interrupt TMR0
...
...
باختصار :
من أجل استخدام المؤقت TMR0 بشكل صحيح ينبغى :
الخطوة الأولى : اختيار نظام العمل :
• يتم اختيار تظام عمل المؤقت عن طؤيق البت T0CS بالسجل OPTION_REG ، T0CS: 0=timer ، T0CS: 1= counter .
• عند الاستخدام ، يجب تخصيص معامل القسمة prescaler للمؤقت / العداد عن طريق مسح (0) البت PSA بالسجل OPTION_REG . يتم تحديد معدل معامل القسمة عن طريق البتنات PS2-PS0 بنفس السجل .
• عند استخدام المقاطعة ، يجب تحديد (1) البتات GIE و TMR0IE بالسجل INTCON .
الخطوة الثانية : القياس والعد
لقياس الزمن :
• قم بعمل Reset (صفر) للسجل TMR0 أو اكتب إليه قيمة معروفة .
• يتم قياس الزمن المنقضى (بالميكروثانية عندما تستخدم كريستال بتردد 4MHz ) عن طريق قراءة السجل TMR0 .
• بت العلم TMR0IF بالسجل INTCON يتم تلقائيا تحديدها (1) فى كل مرة يحدث طفحان overflow فى السجل TMR0 ، إذا كان قد تم تمكينها ، وتحدث مقاطعة .
لعد النبضات :
• يتم اختيار قطبية النبضات المراد عدها من على الطرف RA4 عن طريق البت T0SE بالسجل OPTION_REG ، (T0SE: 0=positive, 1=negative pulses) .
• يمكن قياس عدد النبضات عن طريق قراءة السجل TMR0 . يتم استخدام معامل القسمة والمقاطعة بنفس إسلوب نظام المؤقت .
رد: ما هو الميكروكونترولر Microcontroller ؟
تدريب على نظام عمل موديول المؤقت Timer0 كمؤقت Timer:
توليد تأخير زمنى بحوالى واحد ثانية باستخدام موديول Timer0 كمؤقت . تردد الكريستال 4 MHz لذلك يكون زمن دورة التعليمة هو واحد ميكروثانية 1µs . لتوليد فترة تأخير بقيمة واحد ثانية يجب أن يعد المؤقت مليون دورة 1000000 . إذا استخدمنا "معامل قسمة" prescaler بالقيمة 256 فإن العد المطلوب يقل إلى 3906 . والآن إذا قمنا بتحميل سجل المؤقت TMR0 بقيمة ابتدائية قدرها 39 فإنه سوف يحدث له طفحان overflow بعد عدد من العد قدره 256-39 = 217 counts . ومن ثم يكون عدد مرات الطفحان اللازمة هى 18 مرة كما يلى :
بهذه الإعدادات بعد كل 18 مرة طفحان لسجل المؤقت TMR0 (مع تحميله مسبقا بالقيمة 39) يكون قد إنقضى فترة زمنية قدرها واحد ثانية تقريبا . لمشاهدة النتيجة نجعل هذا الزمن يتسبب فى عمل وميض لليد .
الدائرة الكهربية :
البرنامج :
فى البداية نلقى نظرة على إعدادات سجل الخيارات وسجل التحكم فى المقاطعة :
توليد تأخير زمنى بحوالى واحد ثانية باستخدام موديول Timer0 كمؤقت . تردد الكريستال 4 MHz لذلك يكون زمن دورة التعليمة هو واحد ميكروثانية 1µs . لتوليد فترة تأخير بقيمة واحد ثانية يجب أن يعد المؤقت مليون دورة 1000000 . إذا استخدمنا "معامل قسمة" prescaler بالقيمة 256 فإن العد المطلوب يقل إلى 3906 . والآن إذا قمنا بتحميل سجل المؤقت TMR0 بقيمة ابتدائية قدرها 39 فإنه سوف يحدث له طفحان overflow بعد عدد من العد قدره 256-39 = 217 counts . ومن ثم يكون عدد مرات الطفحان اللازمة هى 18 مرة كما يلى :
- الكود:
3906 counts = 3906/217 = 18
بهذه الإعدادات بعد كل 18 مرة طفحان لسجل المؤقت TMR0 (مع تحميله مسبقا بالقيمة 39) يكون قد إنقضى فترة زمنية قدرها واحد ثانية تقريبا . لمشاهدة النتيجة نجعل هذا الزمن يتسبب فى عمل وميض لليد .
الدائرة الكهربية :
البرنامج :
فى البداية نلقى نظرة على إعدادات سجل الخيارات وسجل التحكم فى المقاطعة :
- الكود:
/*PIC16F877A
1sec timer using TIMER0
Oscillator @ 4MHz
*/
// Define LED connection
sbit LED at RB0_bit;
unsigned short Num;// overflow counter 0 .. 18
// Interrupt service routine
void interrupt(){
Num ++; // Interrupt causes Num to be incremented by 1
if(Num == 18){ // after 1 sec period
LED = ~LED; // Toggle LED every sec
Num = 0; //clear again
}
TMR0 = 39; // TMR0 returns to its initial value
INTCON.T0IF = 0; // Bit T0IF is cleared so that the interrupt could reoccur
}
void main() {
TRISB = 0b00000000; // PORTB All Outputs
LED = 0;
Num = 0; // begin
OPTION_REG = 0x07; // Prescaler (1:256) is assigned to the timer TMR0
TMR0 = 39; // Timer T0 counts from 39 to 255
INTCON = 0xA0; // Enable interrupt TMR0 and Global Interrupts
do {
// Your main programs goes here
} while(1); // infinite loop
}
رد: ما هو الميكروكونترولر Microcontroller ؟
التدريب على نظام عمل موديول المؤقت Timer 0 كعداد counter :
سوف نستخدم موديول المؤقت Timer0 كعداد لعد نبضات الساعة الخارجية والتى تصل عن طريق الطرف RA4/T0CKI . نبضات الساعة الخارجية سوف يتم اشتقاقها من منبع التيار المتردد . منبع التيار المتردد المستخدم جيبى ذو جهد وتردد 220V, 50 Hz .
سوف يتم أولا تخفيض الجهد إلى إشارة بجهد وتردد 9 V, 50 Hz باستخدام محول تيار متردد . وقبل توصيل هذه الإشارة إلى الطرف T0CKI يجب تقويمها (توحيدها) وقطع (قص – تحديد) قيمة جهد الذروة عند +5V . الدائرة التالية تحول الجهد 9 V, 50 Hz AC voltage إلى موجة مربعة تقريبا بجهد +5V مناسبة كمدخل للعداد من الطرف T0CKI .
يتم توصيل الموجة المربعة إلى الطرف RA4/T0CKI للميكروكونترولر PIC16F877A . يبدأ السجل TMR0 من الصفر ويعد النبضات الواصلة فى فترة زمنية قدرها واحد ثانية . يتم عرض النتيجة على شاشة وحدة عرض LCD .عدد النبضات فى الثانية هو تردد الإشارة الواصلة وهو 50 Hz .
الدائرة الكهربية :
البرنامج :
النتائج :
سوف نستخدم موديول المؤقت Timer0 كعداد لعد نبضات الساعة الخارجية والتى تصل عن طريق الطرف RA4/T0CKI . نبضات الساعة الخارجية سوف يتم اشتقاقها من منبع التيار المتردد . منبع التيار المتردد المستخدم جيبى ذو جهد وتردد 220V, 50 Hz .
سوف يتم أولا تخفيض الجهد إلى إشارة بجهد وتردد 9 V, 50 Hz باستخدام محول تيار متردد . وقبل توصيل هذه الإشارة إلى الطرف T0CKI يجب تقويمها (توحيدها) وقطع (قص – تحديد) قيمة جهد الذروة عند +5V . الدائرة التالية تحول الجهد 9 V, 50 Hz AC voltage إلى موجة مربعة تقريبا بجهد +5V مناسبة كمدخل للعداد من الطرف T0CKI .
يتم توصيل الموجة المربعة إلى الطرف RA4/T0CKI للميكروكونترولر PIC16F877A . يبدأ السجل TMR0 من الصفر ويعد النبضات الواصلة فى فترة زمنية قدرها واحد ثانية . يتم عرض النتيجة على شاشة وحدة عرض LCD .عدد النبضات فى الثانية هو تردد الإشارة الواصلة وهو 50 Hz .
الدائرة الكهربية :
البرنامج :
- الكود:
/*
Timer0 as a counter
Oscillator @ 4MHz */
// 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
// Define Messages
char message1[] = "Frequency= Hz";
char *freq = "00";
void Display_Freq(unsigned int freq2write) {
freq[0] = (freq2write/10)%10 + 48; // Extract tens digit-add 48 >> change to ASCII
freq[1] = freq2write%10 + 48; // Extract ones digit add 48 >> change to ASCII
// Display Frequency on LCD
Lcd_Out(1, 11, freq);
}
void main() {
TRISB = 0; // PORTB All Outputs
TRISA = 0XFF; // INPUTS
OPTION_REG = 0b00101000; // Prescaler (1:1), TOCS =1 for counter mode
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,message1); // Write message1 in 1st row
do {
TMR0=0;
Delay_ms(1000); // Delay 1 Sec TIMER0 COUNT=Hz
Display_Freq(TMR0);
} while(1); // Infinite loop
}
النتائج :
رد: ما هو الميكروكونترولر Microcontroller ؟
برنامج متعدد المهام :
الدائرة الكهربية :
يقوم البرنامج بعمل مهمتين فى نفس الوقت ، المهمة الظاهرة والعادية هى إصدار صوت من سماعة بصفة مستمرة ، ومهمة فى الخلفية وهى وميض ليد عن طريق توليد نبضة كل واحد ثانية باستخدام موديول المؤقت Timer0 كمؤقت والمقاطعة بهذا المؤقت .
الدائرة الكهربية :
يقوم البرنامج بعمل مهمتين فى نفس الوقت ، المهمة الظاهرة والعادية هى إصدار صوت من سماعة بصفة مستمرة ، ومهمة فى الخلفية وهى وميض ليد عن طريق توليد نبضة كل واحد ثانية باستخدام موديول المؤقت Timer0 كمؤقت والمقاطعة بهذا المؤقت .
- الكود:
/*Name : LED & SOUNDER
PICMICRO : PIC16F877A
*/
// Interrupt Routine Service IRS
/* This routine, having the attribute "interrupt"
which called automatically whenever an interrupt occurs.
in this routine , Timer0 will generate an interrupt every millisecond */
void interrupt ( )
{
if( T0IF ) // Interrupt was caused by an overflow of Timer0?
{
TMR0 = 100 ; // Timer0 reloaded
TimerLed ++; // Increment the timer for the blinking LED
if( TimerLed >= TEMP_LED ) // If the time has passed TEMP_LED=250
{
LED = ~LED ; // Invert LED status to flash .
TimerLed = 0 ; // Reloading the LED timer to start again
}
T0IF = 0 ; // Reset the interrupt flag of timer 0
} // end that occurred on Timer0 interrupt
} // end of interrupt service routine
// definitions
#define TEMP_LED 250 // Constant value , 250 ,defined as "TEMP_LED .
#define LED PORTD.B0 //LED at pin RD0=PORTD.B0 defined as "LED" '
#define BUZZER PORTD.B1 //SOUNDER at pin RD1 = PORTD.B1 defined as "BUZZER" .
#define T0IF INTCON.T0IF //Timer0 Interrupt Flag Bit INTCON.F0IF defined as "T0IF"
// Variable decleraion
unsigned char TimerLed = 0;
/*Variable : Char data type is an 8-bit so it can get to hold values up to 255
we need a maximum of 250,TEMP_LED , so it's fine */
// Setting Function
void settings ( void ) // Setting Function
{
//PORTS Setting
TRISD = 0 ; // PORTD as outputs
// Setting the OPTION register
OPTION_reg = 0b11000100 ;
// bit 0 -> Prescaler Rate Select bit 0 >0
// bit 1 -> Prescaler Rate Select bit 0 >0
// bit 2 -> Prescaler Rate Select bit 0 >1 (3 bits 100= 1:32)
// bit 3 -> Prescaler assigned to Timer0 >0
// bit 4 -> It does not matter >0
// bit 5 -> Timer0 Clock derived from internal clock cycle >0
// bit 6 -> It does not matter >1
// bit 7 -> pull-up resistors on port B disabled >1
// Set interrupt
INTCON = 0b10100000;
// bit 0 -> RBIF - Flag of interrupt ports B >0
// bit 1 -> INTF - Interrupt Flag of RB0/INT >0
// bit 2 -> T0IF - on Timer0 interrupt flag >0
// bit 3 -> RBIE, Interrupt on Port B disabled >0
// bit 4 -> INTE, Interrupt port RB0/INT disabled >0
// bit 5 -> TMR0IE, Interrupt on Timer0 enabled >1
// bit 6 -> PEIE, interrupt device disabled >0
// bit 7 -> GIE, Management Interrupt active >1
TMR0 = 100 ; // Set Timer0 to 100 , as initial value
}
// main function
void main ( )
{
settings ( ) ; // Run Setting Function for ports and registers
while ( 1 ) // run a loop
{
/* The only thing that I do during this endless cycle,
is the reversal of the state of BUZZER each 200 micro-sec
in order to generate a square wave of 2.5 KHz,
which applied at the buzzer,
in fact, causing it to emit a note at that frequency*/
Delay_us ( 200);
BUZZER = 1;
Delay_us ( 200);
BUZZER = 0;
}// end loop
} // end main
رد: ما هو الميكروكونترولر Microcontroller ؟
أفضل طريقة لانتخاب وحدات العرض 7-Segment عن طريق مقاطعة المؤقت TIMER0
عرض جميع وحدات العرض فى نفس الوقت غير ممكن لأن كل وحدة تمثل رقم أو خانة لها معلومات مختلفة مطلوب عرضها ، الحل هو عرض وحدة واحدة فى كل مرة . إذا تم عرض جميع الوحدات بتتابع سريع فسوف تظهر بالنسبة للعين كما لو كانت تعرض فى نفس الوقت ، هذه الطريقة تسمى "الانتخاب" multiplexing .
من الأفضل تنفيذ خوارزمية الانتخاب باستخدام مقاطعة المؤقت TIMER0 . عن طريق جعل السجل TMR0 يحدث له طفحان overflow وتوليد مقاطعة كل 5 ms ، حيث يمكن عرض كل وحدة كل 5 ms ومن ثم يكون الزمن الكلى للعرض حوالى 20 ms (4 x 5ms) وهذا الزمن بالفعل كافى لتجنب الإرتعاش الذى يمكن أن يظهر للعين .
عداد تصاعدى تنازلى باستخدام 2 و 4 وحدةعرض 7 SEGMENT
الدائرة الكهربية :
ملاحظات :
• وحدات العرض من نوع الأنود المشترك ، أنودات الوحدات (الخانات) DIG1-DIG4 متصلة بالمنفذ PORTA(RA0-RA3) خلال ترانزستورات التحكم نوع PNP .
• الشرائح السبعة A-G متصلة بالمنفذ PORTD (RD0-RD6) خلال مقاومات تحديد التيار .
• مفتاح ( حساس) التزايد متصل بالطرف RB0 ومفتاح التناقص متل بالطرف RB1 .
البرنامج الأول باستخدام 2 وحدة عرض أى أن مدى التزايد والتناقص هو 0-99 :
عرض جميع وحدات العرض فى نفس الوقت غير ممكن لأن كل وحدة تمثل رقم أو خانة لها معلومات مختلفة مطلوب عرضها ، الحل هو عرض وحدة واحدة فى كل مرة . إذا تم عرض جميع الوحدات بتتابع سريع فسوف تظهر بالنسبة للعين كما لو كانت تعرض فى نفس الوقت ، هذه الطريقة تسمى "الانتخاب" multiplexing .
من الأفضل تنفيذ خوارزمية الانتخاب باستخدام مقاطعة المؤقت TIMER0 . عن طريق جعل السجل TMR0 يحدث له طفحان overflow وتوليد مقاطعة كل 5 ms ، حيث يمكن عرض كل وحدة كل 5 ms ومن ثم يكون الزمن الكلى للعرض حوالى 20 ms (4 x 5ms) وهذا الزمن بالفعل كافى لتجنب الإرتعاش الذى يمكن أن يظهر للعين .
عداد تصاعدى تنازلى باستخدام 2 و 4 وحدةعرض 7 SEGMENT
الدائرة الكهربية :
ملاحظات :
• وحدات العرض من نوع الأنود المشترك ، أنودات الوحدات (الخانات) DIG1-DIG4 متصلة بالمنفذ PORTA(RA0-RA3) خلال ترانزستورات التحكم نوع PNP .
• الشرائح السبعة A-G متصلة بالمنفذ PORTD (RD0-RD6) خلال مقاومات تحديد التيار .
• مفتاح ( حساس) التزايد متصل بالطرف RB0 ومفتاح التناقص متل بالطرف RB1 .
البرنامج الأول باستخدام 2 وحدة عرض أى أن مدى التزايد والتناقص هو 0-99 :
- الكود:
/*
UP Down Counter with two 7-Segment Display Multiplexing
In this project two common anode 7-segment LED displays are connected to
PORTD of a PIC16F877A @ 4MHz .
Digit 1 (left digit) enable pin is connected to port pin RA0 ( TENS)
and digit 2 (right digit) enable pin is connected to port pin RA1 (ONES) .
The program counts up -down from buttons at RB0 , RB1 .
The display is updated in a timer interrupt service routine at every 5ms by :
Reload TMR0=100 & prescaler ratio 1:32>> imer interrupt service routine at
(255-100) *32us=5ms = scanning time
*/
#define TENS_DIG PORTA.F0 //tens unit
#define ONES_DIG PORTA.F1//ones unit
//Global variable
unsigned char Count = 0;
unsigned char Flag = 0;
bit oldstate1;
bit oldstate2;
//-Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0xC0;
case 1 : return 0xF9;
case 2 : return 0xA4;
case 3 : return 0xB0;
case 4 : return 0x99;
case 5 : return 0x92;
case 6 : return 0x82;
case 7 : return 0xF8;
case 8 : return 0x80;
case 9 : return 0x90;
} //case end
}
// TMR0 timer interrupt service routine. The program jumps to the ISR at every 5ms.
void interrupt ()
{
//Local variable
unsigned char TENS_SEG, ONES_SEG; // tens= left unit &ones= right unit
TMR0 = 100; // Re-load TMR0>>255-100=155usx32(prescaler)=5ms
INTCON = 0x20; // >>>>Set T0IE and clear T0IF<<<<
Flag = ~ Flag; // Toggle Flag as switch
if(Flag == 0) // Do digit 1
{
ONES_DIG = 1; // Disable digit 2
TENS_SEG = Count / 10; // TENS_SEG >>tens
PORTD = mask(TENS_SEG); // Send to PORTD
TENS_DIG = 0; // Enable digit 1>>RA0
}
else
{ // Do digit 2
TENS_DIG = 1; // Disable digit 1
ONES_SEG = Count % 10; // ONES_SEG >> ones
PORTD = mask(ONES_SEG); // Send to PORTD
ONES_DIG = 0; // Enable digit 2 >>RA1
}
}
//
// Start of MAIN Program. configure PORTA and PORTD as outputs.
// In addition, configure TMR0 to interrupt at every 5ms
//
void main()
{
ADCON1=0X07; //set A PORT general I/O
TRISD= 0; // PORTD are outputs
TRISA = 0; // RA0, RA1 are outputs
TENS_DIG = 1; // Disable digit 1
ONES_DIG = 1; // Disable digit 2
// Configure TMR0 timer interrupt
OPTION_REG = 0xC4; // Prescaler = 32
TMR0 = 100; // Load TMR0L with 100
INTCON = 0xA0; // Enable TMR0 interrupt
//Delay_ms(1000);
for(;;) // Endless loop
{
//UP Count
if (Button(&PORTB, 0, 1, 0)) { // Button 0 : Detect logical 0
oldstate1 = 1; // Update flag
}
if (oldstate1 && Button(&PORTB, 0, 1, 1)) { // Detect zero-to-one transition
Count = Count +1;
oldstate1 = 0; // Update flag
}
//DOWN Count
if(Button(&PORTB,1,1,0)){ // Button 1 : Detect logical 0
oldstate2 = 1; // Update flag
}
if (oldstate2 && Button(&PORTB, 1, 1, 1)) { // Detect zero-to-one transition
Count = Count -1;
oldstate2 = 0; // Update flag
}
if (Count > 99) // if it's more than 99 go to 0;
Count = 0;
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
البرنامج الثانى باستخدام 4 وحدة عرض أى أن مدى التزايد والتناقص هو 0-9999 :
الدائرة الكهربية :
البرنامج :
الدائرة الكهربية :
البرنامج :
- الكود:
/*
UP Down Counter with Four 7-Segment Display Multiplexing
In this project four common anode 7-segment LED displays are connected to
PORTD of a PIC16F877A @ 4MHz .
Digit 1 (left digit) enable pin is connected to port pin RA0 ( Thousands)
and digit 2 enable pin is connected to port pin RA1 (Hundreds) .
and digit 3 enable pin is connected to port pin RA2 (Tens) .
and digit 4 enable pin is connected to port pin RA3 (Ones) .
The program counts up -down from buttons at RB0 , RB1 .
The display is updated in a timer interrupt service routine at every 5ms by :
Reload TMR0=100 & prescaler ration 1:32>> imer interrupt service routine at
(255-100) *32us=5ms = scanning time
*/
#define Thous_Dig PORTA.B0 //Thousands unit
#define Hund_Dig PORTA.B1//Hndreds unit
#define Tens_Dig PORTA.B2//Tens unit
#define Ones_Dig PORTA.B3//ones unit
//Global variable
unsigned char Count = 0;
unsigned char Flag = 0;
bit oldstate1;
bit oldstate2;
//-Function to Return mask for common anode 7-seg. display
unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0xC0;
case 1 : return 0xF9;
case 2 : return 0xA4;
case 3 : return 0xB0;
case 4 : return 0x99;
case 5 : return 0x92;
case 6 : return 0x82;
case 7 : return 0xF8;
case 8 : return 0x80;
case 9 : return 0x90;
} //case end
}
// TMR0 timer interrupt service routine. The program jumps to the ISR at every 5ms.
void interrupt ()
{
//Local variable
unsigned char Thous_Seg,Hund_Seg,Tens_Seg, Ones_Seg;
TMR0 = 100; // Re-load TMR0>>255-100=155usx32(prescaler)=5ms
INTCON = 0x20; // >>>>Set T0IE and clear T0IF<<<<
if(Flag == 0) // Do digit 1
{
Ones_Dig = 1;
Tens_Dig = 1;
Hund_Dig = 1;
Thous_Seg = Count / 1000; // TENS_SEG >>tens
PORTD = mask(Thous_Seg); // Send to PORTD
Thous_Dig = 0; // Enable digit 1>>RA0
}
else
if(Flag == 1) // Do digit 1
{
Ones_Dig = 1;
Tens_Dig = 1;
Thous_Dig = 1;
Hund_Seg = (Count / 100)%10; // TENS_SEG >>tens
PORTD = mask(hund_Seg); // Send to PORTD
Hund_Dig=0; // Enable digit 1>>RA0
}
else
if(Flag == 2) // Do digit 1
{
Ones_Dig = 1;
Hund_Dig = 1;
Thous_Dig = 1;
Tens_Seg = (Count / 10)%10; // TENS_SEG >>tens
PORTD = mask(Tens_Seg); // Send to PORTD
Tens_Dig=0; // Enable digit 1>>RA0
}
else
if(Flag == 3) // Do digit 1
{
Tens_Dig = 1;
Hund_Dig = 1;
Thous_Dig = 1;
Ones_Seg = Count %10; // TENS_SEG >>tens
PORTD = mask(Ones_Seg); // Send to PORTD
Ones_Dig = 0; // Enable digit 1>>RA0
}
Flag =Flag++;
if (Flag > 3) Flag=0;
// Toggle Flag as switch , Counter
}
//
// Start of MAIN Program. configure PORTA and PORTD as outputs.
// In addition, configure TMR0 to interrupt at every 10ms
//
void main()
{
ADCON1=0X07; //set A PORT general I/O
TRISD= 0; // PORTD are outputs
PORTD=0XFF;
TRISA = 0; // outputs
PORTA=0XFF;
TRISB=0XFF;
PORTB=0XFF;
// Configure TMR0 timer interrupt
OPTION_REG = 0xC4; // Prescaler = 32
TMR0 = 100; // Load TMR0L with 100
INTCON = 0xA0; // Enable TMR0 interrupt
for(;;) // Endless loop
{
//UP Count
if (Button(&PORTB, 0, 1, 0)) { // Button 0 : Detect logical 0
oldstate1 = 1; // Update flag
}
if (oldstate1 && Button(&PORTB, 0, 1, 1)) { // Detect zero-to-one transition
Count = Count +1;
oldstate1 = 0; // Update flag
}
//DOWN Count
if(Button(&PORTB,1,1,0)){ // Button 1 : Detect logical 0
oldstate2 = 1; // Update flag
}
if (oldstate2 && Button(&PORTB, 1, 1, 1)) { // Detect zero-to-one transition
Count = Count -1;
oldstate2 = 0; // Update flag
}
if (Count > 9999) // if it's more than 9999 go to 0;
Count = 0;
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
الموديول TIMER1 :
• الموديول Timer1 هو مؤقت / عداد 16-bit يتكون من سجلين 8-bit هما السجل TMR1H و السجل TMR1L ، وهى قابلة للقراءة منها والكتابة إليها .
• زوج سجلات المؤقت TMR1 تتزايد من 0000h إلى FFFFh وتلف إلى 0000h . مقاطعة المؤقت TMR1 ، إذا كانت ممكنة ، تتولد عند الطفحان overflow حيث يتم تحديد (1) بت علم المقاطعة TMR1IF (PIR1<0>) . هذه المقاطعة يمكن تمكينها / تعطيلها عن طريق تحديد (1) / مسح (0) بت تمكين المقاطعة
TMR1IE (PIE1<0>) .
المؤقت Timer1 يمكن أن يعمل فى نظامين :
• نظام المؤقت timer .
• نظام العداد counter .
يتم تحديد نظام الغمل عن طريق بت اختيار الساعة TMR1CS (T1CON<1>) .
فى نظام المؤقت ، يتزايد المؤقت Timer1 كل دورة تعليمة .
فى نظام العداد ، يتزايد عن كل حافة صاعدة لدخل الساعة الخارجية .
• يمكن تفعيل / تعطيل المؤقت Timer1 عن طريق تحديد (1) / مسح (0) بت التحكم
TMR1ON (T1CON<0>) .
" alt="" />
عمل المؤقت Timer1 فى نظام المؤقت Timer :
يتم اختيار نظام المؤقت timer عن طريق مسح (0) البت TMR1CS (T1CON<1>) . فى هذا النظام ، يكون دخل الساعة إلى المؤقت هو Fosc/4 . بت النحكم فى التزامن T1SYNC (T1CON<2>) لا يكون لها تأثير لأن الساعة الداخلية تكون دائما متزامنة .
عمل المؤقت Timer1 كعداد Counter :
المؤقت Timer1 قد يعمل فى أى من النظام المتزامن أو الغير متزامن اعتمادا على تحديد البت TMR1CS .
عندما يتم تزايد المؤقت Timer1 من خلال مصدر خارجى ، يحدث التزايد عند الحافة الصاعدة . بعد تمكين المؤقت Timer1 فى نظام العداد يجب أن لدى الموديول أولا حافة هابطة قبل أن يبدأ الغداد فى التزايد .
صيغة حساب الزمن :
مثال : توليد زمن قدرة واحد ثانية باستخدام كريستال بتردد 20MHz .
سوف نستخدم المقاطعة للحصول على زمن واحد ثانية بعد 100 مرة مقاطعة .
• الموديول Timer1 هو مؤقت / عداد 16-bit يتكون من سجلين 8-bit هما السجل TMR1H و السجل TMR1L ، وهى قابلة للقراءة منها والكتابة إليها .
• زوج سجلات المؤقت TMR1 تتزايد من 0000h إلى FFFFh وتلف إلى 0000h . مقاطعة المؤقت TMR1 ، إذا كانت ممكنة ، تتولد عند الطفحان overflow حيث يتم تحديد (1) بت علم المقاطعة TMR1IF (PIR1<0>) . هذه المقاطعة يمكن تمكينها / تعطيلها عن طريق تحديد (1) / مسح (0) بت تمكين المقاطعة
TMR1IE (PIE1<0>) .
المؤقت Timer1 يمكن أن يعمل فى نظامين :
• نظام المؤقت timer .
• نظام العداد counter .
يتم تحديد نظام الغمل عن طريق بت اختيار الساعة TMR1CS (T1CON<1>) .
فى نظام المؤقت ، يتزايد المؤقت Timer1 كل دورة تعليمة .
فى نظام العداد ، يتزايد عن كل حافة صاعدة لدخل الساعة الخارجية .
• يمكن تفعيل / تعطيل المؤقت Timer1 عن طريق تحديد (1) / مسح (0) بت التحكم
TMR1ON (T1CON<0>) .
" alt="" />
عمل المؤقت Timer1 فى نظام المؤقت Timer :
يتم اختيار نظام المؤقت timer عن طريق مسح (0) البت TMR1CS (T1CON<1>) . فى هذا النظام ، يكون دخل الساعة إلى المؤقت هو Fosc/4 . بت النحكم فى التزامن T1SYNC (T1CON<2>) لا يكون لها تأثير لأن الساعة الداخلية تكون دائما متزامنة .
عمل المؤقت Timer1 كعداد Counter :
المؤقت Timer1 قد يعمل فى أى من النظام المتزامن أو الغير متزامن اعتمادا على تحديد البت TMR1CS .
عندما يتم تزايد المؤقت Timer1 من خلال مصدر خارجى ، يحدث التزايد عند الحافة الصاعدة . بعد تمكين المؤقت Timer1 فى نظام العداد يجب أن لدى الموديول أولا حافة هابطة قبل أن يبدأ الغداد فى التزايد .
صيغة حساب الزمن :
- الكود:
T = machine cycle * prescaler * count (65536 - TMR1H: TMR1L);
Machine cycle = 4 / Fosc;
Fosc is the crystal oscillator clock frequency
مثال : توليد زمن قدرة واحد ثانية باستخدام كريستال بتردد 20MHz .
- الكود:
Machine cycle = 4 / 20Mhz = 0.2us. T = 0.2 * 4 * 12500 = 10000us or 10ms.
سوف نستخدم المقاطعة للحصول على زمن واحد ثانية بعد 100 مرة مقاطعة .
- الكود:
Char count;
void interrupt () {
Count ++ ; // for each TIMER1 interrupt increments the counting variable
TMR1L = 0x2C ; // recharge the TMR1L;
TMR1H = 0xCF ; // recharge the TMR1H;
PIR1.TMR1IF = 0 ; // clear the overflow.
}
void main () {
INTCON.GIE = 1 ; // enable global interruption;
INTCON.PEIE = 1 ; // enable interruption of peripherals;
PIE1.TMR1IE = 1 ; // enable interrupt of TIMER1;
// TMR1 receives the value 53036 (65536 - 12500), which in Hexadecimal is 0xCF2C
TMR1L = 0x2C ; // least significant byte
TMR1H = 0xCF ; // most significant byte
T1CON = 0b00100001 ; // Timer mode, prescaler 1: 4, internal clock;
while ( 1 ) {
if (count == 100 ) { // when count = 100, that is, when time reaches
PORTB.RB0 = ~ PORTB.RB0 ; // 1s (100 * 10ms) reverses the state of portb, pin RB0.
}
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
موديول المؤقت Timer2 :
موديول المؤقت Timer2 هو مؤقت 8-bit بقاسم تردد سابق prescaler وقاسم تردد لاحق postscaler . هذا الموديول يمكن أن يستخدم مع موديول تعديل عرض النبضة PWM . السجل TMR2 هو سجل قابل للقراءة والكتابة ويتم مسحه عند أى إعادة Reset للجهاز .
ساعة الدخل (Fosc/4) لها خيار لقاسم تردد سابق بنسبة 1:1, 1:4,1:16 ، يتم اختيارها بواسطة بتات التحكم
T2CKPS1:T2CKPS0 (T2CON<1:0>) .
الموديول Timer2 له سجل فترة 8-bit يسمى PR2 .
يتم تزايد المؤقت Timer2 من 00h حتى يطابق السجل PR2 عندئذ يتم يعود reset إلى الصفر 00h عند دورة التزايد التالية . السجل PR2 هو سجل قابل للقراءة والكتابة . عند الإعادة Reset يتم تهيئة السجل PR2 بالقيمة FFh .
الخرج المطابق للسجل TMR2 يذهب خلال مقياس التردد اللاحق 4-bit postscaler ( يعطى مقياس 1:1 إلى 1:16 ) ، لتوليد المقاطعة بالمؤقت TMR2 ، بتحديد علم البت TMR2IF (PIR1<1>) .
يمكن غلق المؤقت Timer2 عن طريق مسح بت التحكم TMR2ON (T2CON<2>) ، لتقليل استهلاك القدرة .
الشكل التالى يبين سجل التحكم فى المؤقت Timer2 :
صيغة حساب زمن المقاطعة بالمؤقت Timer2 :
مثال :
البرنامج :
موديول المؤقت Timer2 هو مؤقت 8-bit بقاسم تردد سابق prescaler وقاسم تردد لاحق postscaler . هذا الموديول يمكن أن يستخدم مع موديول تعديل عرض النبضة PWM . السجل TMR2 هو سجل قابل للقراءة والكتابة ويتم مسحه عند أى إعادة Reset للجهاز .
ساعة الدخل (Fosc/4) لها خيار لقاسم تردد سابق بنسبة 1:1, 1:4,1:16 ، يتم اختيارها بواسطة بتات التحكم
T2CKPS1:T2CKPS0 (T2CON<1:0>) .
الموديول Timer2 له سجل فترة 8-bit يسمى PR2 .
يتم تزايد المؤقت Timer2 من 00h حتى يطابق السجل PR2 عندئذ يتم يعود reset إلى الصفر 00h عند دورة التزايد التالية . السجل PR2 هو سجل قابل للقراءة والكتابة . عند الإعادة Reset يتم تهيئة السجل PR2 بالقيمة FFh .
الخرج المطابق للسجل TMR2 يذهب خلال مقياس التردد اللاحق 4-bit postscaler ( يعطى مقياس 1:1 إلى 1:16 ) ، لتوليد المقاطعة بالمؤقت TMR2 ، بتحديد علم البت TMR2IF (PIR1<1>) .
يمكن غلق المؤقت Timer2 عن طريق مسح بت التحكم TMR2ON (T2CON<2>) ، لتقليل استهلاك القدرة .
الشكل التالى يبين سجل التحكم فى المؤقت Timer2 :
صيغة حساب زمن المقاطعة بالمؤقت Timer2 :
- الكود:
T = machine cycle * prescaler * postscaler * PR2
Machine cycle = 4 / Fosc
مثال :
- الكود:
Using a clock of 12Mhz, prescaler 1:16 and postscaler 1:16.
T = (4/12) * 16 * 16 * 255 = 21760us = 21.7ms
البرنامج :
- الكود:
void interrupt () {
PORTB .F1 = ~ PORTB .F1 ; // reverses the state of pin RB1
PIR1 .TMR2IF = 0 ; // clears the interrupt flag
}
void main () {
INTCON .GIE = 1 ; // enable global interruption
INTCON .PEIE = 1 ; // enable interruption of peripherals
PIE1 .TMR2IE = 1 ; // enable interrupt of TIMER2
T2CON = 0b01111111 ; // Postcaler 1:16, TIMER2 on and prescaler 1:16;
TRISB .F1 = 0 ; // define pin RB1 as output
PORTB .F1 = 0 ; / Sets pin RB1 as initial state at low level
PR2 = 255 ; // sets the value for PR2
}
رد: ما هو الميكروكونترولر Microcontroller ؟
تدريب على المقاطعة باستخدام المؤقتات
الغرض
• استخدام المؤقتات TMR0, TMR1 , TMR2 .
• استخدام المقاطعات .
ربما لاحظت وجود عيب عند تنفيذ التأخير عند استخدام الحلقات.
في مثل تلك الحالة يكون الميكروكونترولر 'أسير' ولا يفعل شيئا. ببساطة ينتظر لحين مرور بعض الوقت.
هذا الوقت الضائع ترفا غير مقبول لذلك يجب تطبيق بعض الطرق الأخرى .
هل تتذكر موضوع المؤقتات ؟
هل تتذكر موضوع المقاطعات ؟
هذا التدريب يصنع رابط بينهما بطريقة عملية .
الدائرة الكهربية :
فكرة البرنامج :
• مطلوب توفير تأخير طويل بما يكفى لملاحظة التغيرات على المنفذ . يستخدم لذلك الموقت TMR0 مع تخصيص "معامل القسمة " prescaler لهذا الغرض.
• يتم إنشاء مقاطعة عند كل حدوث طفحان overflow بسجل المؤقت TMR0 فيتم تنفيذ روتين المقاطعة وفى كل مرة يقوم روتين المقاطعة تلقائيا بتزايد المتغير "cnt" بواحد .
• عندما تصل القيمة الموجودة بهذا المتغير إلى 400 يتم تزايد المنفذ port B بواحد وتظهر النتيجة على شكل إضاءة ليدات .
يتم تنفيذ الإجراء بأكمله من 'وراء الكواليس، مما يمكن الميكروكونترولر بعمل شىء آخر .
النتيجة :
إضاءة الليدات الثمانية المتصلة بالمنفذ PORT B بشكل يمثل الأرقام من 1 إلى 255 بالنظام الثنائى أى من 00000001 إلى 11111111 .
حساب زمن المقاطعة :
البرنامج :
المقاطعة باستخدام المؤقت TMR1 :
فى هذه الحالة يتم تمكين المقاطعة بعد حدوث طفحان فى المؤقت TMR1 والمكون من السجلين
(TMR1H, TMR1L). مزيج من تغيرات الخانات فى المنفذ PORT B يختلف عن البرنامج السابق حيث يتم إضاءة الأربعة خانات الأولى ثم بعد فترة التأخير تنطفأ ويتم إضاءة الأربع خانات الأخيرة وبعد فترة التأخير تتكرر العملية .
حسابات زمن المقاطعة :
البرنامج :
المقاطعة باستخدام المؤقت TMR2
• فى هذه الحالة تحدث المقاطعة بعد حدوث طفحان للمؤقت TMR2 .
• يتم إنشاء دالة جديدة تسمى Replace والتى لا تنتمى للغة السى وتستخدم فى عكس حالة أطراف المنفذ .
النتيجة إضاءة الليدات الفردية والانتظار لفترة ثم العكس أى إضاءة الليدات الزوجية والانتظار لفترة ثم تكرار العملية .
حسابات زمن المقاطعة :
البرنامج :
الغرض
• استخدام المؤقتات TMR0, TMR1 , TMR2 .
• استخدام المقاطعات .
ربما لاحظت وجود عيب عند تنفيذ التأخير عند استخدام الحلقات.
في مثل تلك الحالة يكون الميكروكونترولر 'أسير' ولا يفعل شيئا. ببساطة ينتظر لحين مرور بعض الوقت.
هذا الوقت الضائع ترفا غير مقبول لذلك يجب تطبيق بعض الطرق الأخرى .
هل تتذكر موضوع المؤقتات ؟
هل تتذكر موضوع المقاطعات ؟
هذا التدريب يصنع رابط بينهما بطريقة عملية .
الدائرة الكهربية :
فكرة البرنامج :
• مطلوب توفير تأخير طويل بما يكفى لملاحظة التغيرات على المنفذ . يستخدم لذلك الموقت TMR0 مع تخصيص "معامل القسمة " prescaler لهذا الغرض.
• يتم إنشاء مقاطعة عند كل حدوث طفحان overflow بسجل المؤقت TMR0 فيتم تنفيذ روتين المقاطعة وفى كل مرة يقوم روتين المقاطعة تلقائيا بتزايد المتغير "cnt" بواحد .
• عندما تصل القيمة الموجودة بهذا المتغير إلى 400 يتم تزايد المنفذ port B بواحد وتظهر النتيجة على شكل إضاءة ليدات .
يتم تنفيذ الإجراء بأكمله من 'وراء الكواليس، مما يمكن الميكروكونترولر بعمل شىء آخر .
النتيجة :
إضاءة الليدات الثمانية المتصلة بالمنفذ PORT B بشكل يمثل الأرقام من 1 إلى 255 بالنظام الثنائى أى من 00000001 إلى 11111111 .
حساب زمن المقاطعة :
- الكود:
(4/8MHz) * prescaler * (255-96)
0.5 * 32 * 159 = 2544us = 2.544ms
2.544 * 400 times = 1 sec
البرنامج :
- الكود:
unsigned cnt; // Define variable cnt
void interrupt() {
cnt++; // Interrupt causes cnt to be incremented by 1
TMR0 = 96; // Timer TMR0 is returned its initial value
INTCON = 0x20; // Bit T0IE is set, bit T0IF is cleared
}
void main() {
OPTION_REG = 0x84; // Prescaler is assigned to timer TMR0
TRISB = 0; // All port B pins are configured as outputs
PORTB = 0x0; // Reset port B
TMR0 = 96; // Timer T0 counts from 96 to 255
INTCON = 0xA0; // Enable interrupt TMR0
cnt = 0; // Variable cnt is assigned a 0
do { // Endless loop
if (cnt == 400) { // Increment port B after 400 interrupts
PORTB = PORTB++; // Increment number on port B by 1
cnt = 0; // Reset variable cnt
}
} while(1);
}
المقاطعة باستخدام المؤقت TMR1 :
فى هذه الحالة يتم تمكين المقاطعة بعد حدوث طفحان فى المؤقت TMR1 والمكون من السجلين
(TMR1H, TMR1L). مزيج من تغيرات الخانات فى المنفذ PORT B يختلف عن البرنامج السابق حيث يتم إضاءة الأربعة خانات الأولى ثم بعد فترة التأخير تنطفأ ويتم إضاءة الأربع خانات الأخيرة وبعد فترة التأخير تتكرر العملية .
حسابات زمن المقاطعة :
- الكود:
TMR1H = 0x80; // Set initial value for timer TMR1
TMR1L = 0x00; // TMR1 = 32768
(4/8MHz) * prescaler * (65535 – 32768 )
0.5 * 1 * 32767 = 16383.5 us = 16.384 ms
16.384 ms * 76 times = 1.2 sec
البرنامج :
- الكود:
unsigned short cnt; // Define variable cnt
void interrupt() {
cnt++ ; // Interrupt causes cnt to be incremented by 1
PIR1.TMR1IF = 0; // Reset bit TMR1IF
TMR1H = 0x80; // TMR1H and TMR1L timer registers are returned
TMR1L = 0x00; // their initial values
}
void main() {
PORTB = 0xF0; // Initial value of port B bits
TRISB = 0; // Port B pins are configured as outputs
T1CON = 1; // Set timer TMR1 , prescaler 1:1
PIR1.TMR1IF = 0; // Reset bit TMR1IF
TMR1H = 0x80; // Set initial value for timer TMR1
TMR1L = 0x00;
PIE1.TMR1IE = 1; // Enable interrupt on overflow
cnt = 0; // Reset variable cnt
INTCON = 0xC0; // Enable interrupt (bits GIE and PEIE)
do { // Endless loop
if (cnt == 76) { // Change port B state after 76 interrupts
PORTB = ~PORTB; // Number in port B is inverted
cnt = 0; // Reset variable cnt
}
} while (1);
}
المقاطعة باستخدام المؤقت TMR2
• فى هذه الحالة تحدث المقاطعة بعد حدوث طفحان للمؤقت TMR2 .
• يتم إنشاء دالة جديدة تسمى Replace والتى لا تنتمى للغة السى وتستخدم فى عكس حالة أطراف المنفذ .
النتيجة إضاءة الليدات الفردية والانتظار لفترة ثم العكس أى إضاءة الليدات الزوجية والانتظار لفترة ثم تكرار العملية .
حسابات زمن المقاطعة :
- الكود:
(4/Fosc) * prescaler * postscaler * PR2
(4/8MHz) * 16 * 16 * 255 = 32640 us = 32.640 ms
32.640 * 30 times = 1 sec
البرنامج :
- الكود:
unsigned short cnt; // Define variable cnt
void Replace() {
PORTB = ~PORTB; // Define new function ‘Replace’
} // Function inverts port state
void interrupt() {
if (PIR1.TMR2IF) { // If bit TMR2IF = 1,
cnt++ ; // Increment variable cnt by 1
PIR1.TMR2IF = 0;// Reset bit and
TMR2 = 0; // reset register TMR2
}
}
// main
void main() {
cnt = 0; // Reset variable cnt
PORTB = 0b10101010; // Logic state on port B pins
TRISB = 0; // All port B pins are configured as outputs
T2CON = 0xFF; // Set timer2, prescaler=16, postscaler=16,TMR2ON
TMR2 = 0; // Initial value of timer register TMR2
PIE1.TMR2IE = 1; // Enable interrupt
INTCON = 0xC0; // Set bits GIE and PEIE
while (1) { // Endless loop
if (cnt > 30) { // Change PORTB after more than 30 interrupts
Replace(); // Function Replace inverts the port B state
cnt = 0; // Reset variable cnt
}
}
}
رد: ما هو الميكروكونترولر Microcontroller ؟
التعديل فى عرض النبضات PWM
مقدمة :
الكثير من دوائر التحكم فى القدرة الكهربائية تستخدم تقنية "التعديل فى عرض النبضات" PWM كأساس لعملها .
لفهم كيف تقوم هذه التقنية بالتحكم فى القدرة الكهربائية ، تخيل جزء من دائرة على شكل مفتاح "سريع الفعل" والحمل المراد التحكم فيه (مصباح على سبيل المثال) كما فى الشكل التالى :
عندما يكون المفتاح مفتوح open لا يمر تيار فى المصباح وتكون القدرة المغذاة بصفر . فى لحظة غلق close المفتاح يستقبل الحمل الجهد الكامل للمصدر ويتم الإمداد بأقصى قدرة .
كيف نمد الحمل بقدرة متوسطة ؟ ولتكن 50% على سبيل المثال . أحد الأفكار هى جعل المفتاح يفتح ويغلق بسرعة للحصول على زمن فتح 50% وزمن غلق 50% . هذا يعنى أن ، فى المتوسط ، نصف الزمن يوجد به تيار (قدرة) ونصف الزمن لا يوجد به تيار (قدرة) .
يمكن القول أن القدرة المتوسطة كما لو كنا طبقنا جهد متوسط بقيمة 50% من جهد الدخل .
لاحظ أن غلق المفتاح يمكن أن يحدد عرض (زمن تواجد ) النبضة طالما أنه ظل فى هذه الحالة ، وأن الفترة الزمنية بين النبضات تستمر طالما أنه مفتوح . ويعرف مجموع الإثنين معا "بالزمن الدورى " للدورة والذى يتحكم فى التردد . العلاقة بين زمن تواجد النبضة والزمن الكلى (الزمن الدورى) تعرف"بدورة الخدمة أو العمل " duty cycle .
بتغيير عرض النبضة يمكننا التحكم فى القدرة المتوسطة المغذاة للحمل . وبالتالى عندما يتغير عرض النبضة من الصفر إلى أقصى قدرة تتغير أيضا دورة الخدمة كما هو مبين بالشكل التالى :
هذا المبدأ يستخدم للتحكم الدقيق باستخدام PWM عن طريق تعديل (تغيير) عرض النبضة للتحكم فى دورة الخدمة للإشارة المطبقة على الحمل وبالتالى القدرة المغذاة إليه .
مما سبق نستنج أن إشارة PWM تتحدد عن طريق :
• تردد الإشارة .
• دورة خدمة الإشارة .
العمل بتعديل عرض النبضات PWM والميكروكونترولر PIC :
الميكركونترولر PIC16F877A ، على سبيل المثال ، فى بناءه الداخلى 2 موديول CCP "إلتقاط – مقارنة - تعديل بعرض النبضة) هما CCP1 و CCP2 .
يمكننا التعامل بسهولة مع الدوال الخاصة بتوليد أشارة ذات تعديل عرض النبضة PWM بالميكروسى .
الدوال التى تتناول الموديول CCP1 هى :
1- دالة تهيئة تردد إشارة تعديل عرض النبضة PWM :
فى الميكروسى تستخدم الدالة Pwm_Init() فى تحديد تردد إشارة PWM :
الصيغة :
حيث :
freq : هو التردد المطلوب لإشارة PWM .
مثال:
2- دالة "دورة الخدمة" Duty Cycle
من خلال هذه الدالة يمكن التحكم فى دورة الخدمة لأشارة PWM . قيمة دورة الخدمة تتغير من الصفر إلى 255 ، الصفر يساوى 0% والقيمة 127 تساوى 50% والقيمة 255 تساوى 100% .
الصيغة :
حيث :
duty_ratio : قيمة من نوع الحرف char (0 to 255) تحدد النسبة المئوية لدورة خدمة PWM .
مثال :
ونظرا لأن الميكروكونترولر يتعامل مع الأرقام ، ينبغى تحويل النسبة المئوية لدورة الخدمة إلى رقم .
يتم حساب قيمة دورة الخدمة من العلاقة :
• لحساب القيمة المناظرة لدورة خدمة 10 % :
ولأن القيمة يجب أن تكون من نوع الحرف char فيجب أن تكون عدد صحيح بين الصفر و 255 , بالتالى نأخد القيمة 25 أى :
• Duty of 50%
• Duty of 90%
3- دالة البدء Start ودالة الانتهاء Stop :
من خلال دالة البدء PWM1_Start(); نقوم ببدء توليد إشارة PWM بالميكروكونترولر PIC ومن خلال دالة النهاية PWM1_Stop(); يتم إنهاء توليد إشارة PWM .
الصيغة :
مثال بسيط :
فى هذا البرنامج يتم تهيئة الموديول CCP1 بالميكروكونترولر PIC ليعمل بنظام PWM بتردد 5Khz ودورة خدمة 50% كما هو مبين فى الشكل التالى :
مثال آخر :
استخدام الموديول CCP2 بالميكروكونترولر PIC16F877A :
مقدمة :
الكثير من دوائر التحكم فى القدرة الكهربائية تستخدم تقنية "التعديل فى عرض النبضات" PWM كأساس لعملها .
لفهم كيف تقوم هذه التقنية بالتحكم فى القدرة الكهربائية ، تخيل جزء من دائرة على شكل مفتاح "سريع الفعل" والحمل المراد التحكم فيه (مصباح على سبيل المثال) كما فى الشكل التالى :
عندما يكون المفتاح مفتوح open لا يمر تيار فى المصباح وتكون القدرة المغذاة بصفر . فى لحظة غلق close المفتاح يستقبل الحمل الجهد الكامل للمصدر ويتم الإمداد بأقصى قدرة .
كيف نمد الحمل بقدرة متوسطة ؟ ولتكن 50% على سبيل المثال . أحد الأفكار هى جعل المفتاح يفتح ويغلق بسرعة للحصول على زمن فتح 50% وزمن غلق 50% . هذا يعنى أن ، فى المتوسط ، نصف الزمن يوجد به تيار (قدرة) ونصف الزمن لا يوجد به تيار (قدرة) .
يمكن القول أن القدرة المتوسطة كما لو كنا طبقنا جهد متوسط بقيمة 50% من جهد الدخل .
لاحظ أن غلق المفتاح يمكن أن يحدد عرض (زمن تواجد ) النبضة طالما أنه ظل فى هذه الحالة ، وأن الفترة الزمنية بين النبضات تستمر طالما أنه مفتوح . ويعرف مجموع الإثنين معا "بالزمن الدورى " للدورة والذى يتحكم فى التردد . العلاقة بين زمن تواجد النبضة والزمن الكلى (الزمن الدورى) تعرف"بدورة الخدمة أو العمل " duty cycle .
بتغيير عرض النبضة يمكننا التحكم فى القدرة المتوسطة المغذاة للحمل . وبالتالى عندما يتغير عرض النبضة من الصفر إلى أقصى قدرة تتغير أيضا دورة الخدمة كما هو مبين بالشكل التالى :
هذا المبدأ يستخدم للتحكم الدقيق باستخدام PWM عن طريق تعديل (تغيير) عرض النبضة للتحكم فى دورة الخدمة للإشارة المطبقة على الحمل وبالتالى القدرة المغذاة إليه .
مما سبق نستنج أن إشارة PWM تتحدد عن طريق :
• تردد الإشارة .
• دورة خدمة الإشارة .
العمل بتعديل عرض النبضات PWM والميكروكونترولر PIC :
الميكركونترولر PIC16F877A ، على سبيل المثال ، فى بناءه الداخلى 2 موديول CCP "إلتقاط – مقارنة - تعديل بعرض النبضة) هما CCP1 و CCP2 .
يمكننا التعامل بسهولة مع الدوال الخاصة بتوليد أشارة ذات تعديل عرض النبضة PWM بالميكروسى .
الدوال التى تتناول الموديول CCP1 هى :
- الكود:
• Pwm1_Init
• Pwm1_ Set _Duty
• Pwm1_Start
• Pwm1_Stop
1- دالة تهيئة تردد إشارة تعديل عرض النبضة PWM :
فى الميكروسى تستخدم الدالة Pwm_Init() فى تحديد تردد إشارة PWM :
الصيغة :
- الكود:
Pwm1_Init (freq);
حيث :
freq : هو التردد المطلوب لإشارة PWM .
مثال:
- الكود:
Pwm1_Init (4000) // بدء توليد إشارة بتعديل عرض النبضة بتردد 4 كيلوهرتز
2- دالة "دورة الخدمة" Duty Cycle
من خلال هذه الدالة يمكن التحكم فى دورة الخدمة لأشارة PWM . قيمة دورة الخدمة تتغير من الصفر إلى 255 ، الصفر يساوى 0% والقيمة 127 تساوى 50% والقيمة 255 تساوى 100% .
الصيغة :
- الكود:
PWM1_Set_Duty (duty_ratio);
حيث :
duty_ratio : قيمة من نوع الحرف char (0 to 255) تحدد النسبة المئوية لدورة خدمة PWM .
مثال :
- الكود:
PWM1_Set_ Duty (192); // تحديد دورة الخدمة بالقيمة 75 بالمئة
ونظرا لأن الميكروكونترولر يتعامل مع الأرقام ، ينبغى تحويل النسبة المئوية لدورة الخدمة إلى رقم .
يتم حساب قيمة دورة الخدمة من العلاقة :
- الكود:
(Percent * 255) / 100
• لحساب القيمة المناظرة لدورة خدمة 10 % :
- الكود:
(10 * 255) / 100 = 25.5
ولأن القيمة يجب أن تكون من نوع الحرف char فيجب أن تكون عدد صحيح بين الصفر و 255 , بالتالى نأخد القيمة 25 أى :
- الكود:
PWM1_Set_Duty(25);
• Duty of 50%
- الكود:
(50 * 255) / 100 = 127.50
- الكود:
PWM1_Set_Duty(127);
• Duty of 90%
- الكود:
(90 * 255) / 100 = 229.50
- الكود:
PWM1_Set_Duty(229);
3- دالة البدء Start ودالة الانتهاء Stop :
من خلال دالة البدء PWM1_Start(); نقوم ببدء توليد إشارة PWM بالميكروكونترولر PIC ومن خلال دالة النهاية PWM1_Stop(); يتم إنهاء توليد إشارة PWM .
الصيغة :
- الكود:
Pwm1_Start (); // initial signal generation module CCP1 PWM PIC
Pwm1_Stop (); / / stops the PWM signal generation module CCP1 PIC
مثال بسيط :
- الكود:
void main () {
Pwm1_init (5000);
Pwm1_ Set_Duty (127);
Pwm1_Start ();
while (1);
}
فى هذا البرنامج يتم تهيئة الموديول CCP1 بالميكروكونترولر PIC ليعمل بنظام PWM بتردد 5Khz ودورة خدمة 50% كما هو مبين فى الشكل التالى :
مثال آخر :
استخدام الموديول CCP2 بالميكروكونترولر PIC16F877A :
- الكود:
void main() {
Pwm2_init(5000);
Pwm2_Set_Duty(127);
Pwm2_Start();
while(1);.
}
صفحة 4 من اصل 5 • 1, 2, 3, 4, 5
مواضيع مماثلة
» برمجة الميكروكونترولر CHAPTER 2 - Programming Microcontroller
» دوائر ربط (توصيل) الميكروكونترولر MICROCONTROLLER INTERFACING CIRCUITS
» مدخلك الشخصى إلى الميكروكونترولر Your Personal Introductory Course :The PIC Microcontroller
» مراجعة برمجة الميكروكونترولر PIC من خلال مشاريع الميكروكونترولر PIC16F877A مع الدايودات المشعة للضوء والمترجم ميكروسى برو :
» 2.1 أنظمة الميكروكونترولر :
» دوائر ربط (توصيل) الميكروكونترولر MICROCONTROLLER INTERFACING CIRCUITS
» مدخلك الشخصى إلى الميكروكونترولر Your Personal Introductory Course :The PIC Microcontroller
» مراجعة برمجة الميكروكونترولر PIC من خلال مشاريع الميكروكونترولر PIC16F877A مع الدايودات المشعة للضوء والمترجم ميكروسى برو :
» 2.1 أنظمة الميكروكونترولر :
منتديات الهندسة الكهربية والإلكترونية والميكاترونكس والكومبيوتر :: الميكروكونترولر PIC والبرجة بلغة السى والمترجم مسكروسى برو :: الميكروكونترولر PIC والبرمجة بلغة السى والمترجم ميكروسى برو
صفحة 4 من اصل 5
صلاحيات هذا المنتدى:
لاتستطيع الرد على المواضيع في هذا المنتدى