قسم الميكروكنترولر والروبوت ودوائر الاتصال بالحاسب الالي قسم المتحكمات الـ microcontroller و المعالجات microprocessor و التحكم الرقمي بالكمبيوتر CNC والانظمة الآلية والروبوت Robots

   

WRHLAMDA
:: عضو فضي ::
تاريخ التسجيل: Feb 2005
المشاركات: 630
نشاط [ WRHLAMDA ]
قوة السمعة:
قديم 07-10-2013, 02:35 PM المشاركة 9   
افتراضي



أخي، فكر في أن تجعل كود المقاطعة كالتالي:
كود:
void interrupt()
{
  if(T0IF_bit ==1) 
  {
    tmr0=231;
    T0IF_bit=0;
    cont=cont+50;
    if(cont<=500)pwm=on;
    if(cont>500 && cont<=1000)pwm=off;
    if(cont>1000)cont=0;
  }
}
بمعنى أن تغير قيمة العداد في بداية كود المقاطعة، وليس في نهايته
والسبب في هذا أن العداد يعد 25 فقط، أي 25 دورة تعليمات، بينما كود المقاطعة يحتاج أيضا عدد من دورات التعليمات، يصعب علي تقديرها، ولكنها بالتأكيد تمثل نسبة معتبرة من 25، أي أن تأثيرها سيكون واضحا جدا (بعكس مثلا لو العداد يعد 1000، فإضافة بضع عدات عليه لن يحدث فارقا كبيرا)

جرب وأخبرنا بالنتيجة

في حالة أن الكود يحتاج عدد دورات أكبر من 25 دورة، فلن يصل كود المقاطعة أبدا لنهايته، وفي هذه الحالة، عليك أن تقلل الرقم 231 بعض الشيء (مثلا تجعله 206 أو 156) وتغير الأرقام الأخرى بداخل كود المقاطعة بحيث تحصل على ال1 ميلي ثانية التي تريدها

جرب وأخبرنا بالنتيجة
السلا م عليكم

ملاحظة جيدة اخي العزيز ... وبالفعل تؤدي الى بعض التزحيف في الوقت .... لكن ليس بالمقدار الذي تم الحصول علية ... تقريبا اكثر من ضعف الزمن المتوقع ... كما ان التايمر يعذ 50 نبظة وليس 25 وهو بالتأكيد اكبر من الزمن الذي يحتاجة في انجاز المقاطعة

اعلانات

zamalkawi
:: مهندس جيد ::
تاريخ التسجيل: May 2013
المشاركات: 260
نشاط [ zamalkawi ]
قوة السمعة:
قديم 07-10-2013, 03:26 PM المشاركة 10   
افتراضي


عندك حق أخي
ولكن الكود لا أرى فيه أي مشاكل (باستثناء اقتراحي أعلاه) ومن المفترض أن يعمل جيدا
وحيث أنني لا أعلم كيف يعمل الكومبايلر مايكرو سي، لذا لا أعرف كم خطوة تعليمات يحتاجها لتنفيذ الكود، لذلك فكرت في هذا الاحتمال
ولكن عندك حق، التعليمات بسيطة، ولا أظن أنها تستغرق أكثر من بضع دورات، ولن تصل لل50 بأي حال من الأحوال

اعلانات اضافية ( قم بتسجيل الدخول لاخفائها )

الصورة الرمزية حسن هادي محمود
حسن هادي محمود
:: عضو ذهبي ::
تاريخ التسجيل: Sep 2012
الدولة: العراق /البصره
المشاركات: 2,673
نشاط [ حسن هادي محمود ]
قوة السمعة:
قديم 07-10-2013, 08:24 PM المشاركة 11   
افتراضي


أخي، فكر في أن تجعل كود المقاطعة كالتالي:
كود:
void interrupt()
{
  if(T0IF_bit ==1) 
  {
    tmr0=231;
    T0IF_bit=0;
    cont=cont+50;
    if(cont<=500)pwm=on;
    if(cont>500 && cont<=1000)pwm=off;
    if(cont>1000)cont=0;
  }
}
بمعنى أن تغير قيمة العداد في بداية كود المقاطعة، وليس في نهايته
والسبب في هذا أن العداد يعد 25 فقط، أي 25 دورة تعليمات، بينما كود المقاطعة يحتاج أيضا عدد من دورات التعليمات، يصعب علي تقديرها، ولكنها بالتأكيد تمثل نسبة معتبرة من 25، أي أن تأثيرها سيكون واضحا جدا (بعكس مثلا لو العداد يعد 1000، فإضافة بضع عدات عليه لن يحدث فارقا كبيرا)

جرب وأخبرنا بالنتيجة

في حالة أن الكود يحتاج عدد دورات أكبر من 25 دورة، فلن يصل كود المقاطعة أبدا لنهايته، وفي هذه الحالة، عليك أن تقلل الرقم 231 بعض الشيء (مثلا تجعله 206 أو 156) وتغير الأرقام الأخرى بداخل كود المقاطعة بحيث تحصل على ال1 ميلي ثانية التي تريدها

جرب وأخبرنا بالنتيجة
سلام عليكم
اولا اشكر اخي كريم
يوجد نوع ما من تحسن الاشاره ولكن ليست مضبوطه
بالنسبه كل تعليمه يتم تنفيذها بزمن قدره 1us لاني أستخدم كرستاله داخليه 4mhz
اليك صوره حسب كود الذي اعطيتني اياه
http://img02.arabsh.com/uploads/imag...414d6df507.png
وهذا كود نهائي علما انه وضعت شاشه لعرض وقت لما pwm=on
مع علم اعتقد انه لا مشكله في الكود الا اذا رى احدا غير ذلك
كود:
#define on      1
#define off     0
// Lcd pinout settings
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D4 at RD0_bit;

// Pin direction
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D7_Direction at TRISD3_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD0_bit;

sbit pwm at rb0_bit;
char x=0;
char txt[7];
unsigned int cont=0, time=0;
void interrupt()
{
 if(T0IF_bit ==1)
  {
    tmr0=231;
   T0IF_bit=0;
   cont=cont+50;

   if(cont<=500)pwm=on;

  else if(cont>500&& cont<1000){pwm=off; }
  else if(cont>1000)cont=0;

  }
}
void main()
{
 intcon    =0b10100000;
 OPTION_REG=0b00000000 ;// Prescaler Rate1/2
 trisb=0;
 portb=0;
 Lcd_Init();
 Lcd_Cmd(_lcd_cursor_off);
 lcd_cmd(1);
 PWM1_Init(1000);
 tmr0=231;// interrupt happened every 50usec
 while(1)
   {
   PWM1_Start();
    PWM1_Set_Duty(127);
   while(pwm==off)time=0;
   while(pwm==on)time=cont;

  if(time>0 && x==0)
   {

     lcd_chr(1,1,(time/1000)+48);
     lcd_chr_cp( ((time%1000)/100)+48);
     lcd_chr_cp( ((time%1000%100)/10)+48);
     lcd_chr_cp( (time%1000%100%10)+48);
     portb.f5=~portb.f5;
     inttostr(cont,txt);
     lcd_out(1,6,txt);
    }
    x=1;
   }
}
هذا هو مشروع
http://arabsh.com/files/0c37434b60f2...t-ccp-rar.html
بنسبه انا استطيع تغير بقيمه تايمر0 لكي احاول حصول على 1ms ولكن ما الفائده من ذلك لكوني انا اريد تجاوز هذه خطوه بعدها اريد ان ارتب كود لكي استطيع ان اتحكم بأشاره يعني غير dyte_cycle وبتالي حصل على موجه مشابه لموجه pwm قابله للتحكم بزمن تشغيل والاطفاء ولكن مشكله ولااعرف سبب ذلك موجه اكبر من مطلوب مع علم اني أستخدام تايمر0 وهذا حسب معرفتي يعمل مستقل عن عمل مايكرو فليس له علاقه به أطلاقا فهو يعتمد على تردد كرستاله
وحسب قيمه تايمر0=231 يعني لكي اصل الى 256 احتاج تايمر 0 يعد الى 25 ولكن وضعت معامل تقسيم =1/2 هذا يعني عليه ان يعد الى 50 من مفروض انك سوف تحصل على اشاره صحيحه


zamalkawi
:: مهندس جيد ::
تاريخ التسجيل: May 2013
المشاركات: 260
نشاط [ zamalkawi ]
قوة السمعة:
قديم 07-10-2013, 11:01 PM المشاركة 12   
افتراضي


يؤسفني أنني لا أستطيع المساعدة. لقد قرأت الكود وحللته (دون أن أجربه على بروتس) وآظن أنه صحيح
ولكن أقترح عليك تغيير الأرقام بجعل التردد عالي جدا، ثم منخفض جدا، بحيث تفهم ما الذي يحدث


WRHLAMDA
:: عضو فضي ::
تاريخ التسجيل: Feb 2005
المشاركات: 630
نشاط [ WRHLAMDA ]
قوة السمعة:
قديم 07-10-2013, 11:15 PM المشاركة 13   
افتراضي


السلام عليكم

واحدة من الامور الصعبة في استخدام لغات البرمجة العالية المستوى في برمجة المايكرو كونترولر هي حساب الوقت اللازم لانجاز عدد معين من الخطوات ... فانت لاتعرف بالتحديد كيف سيتم ترجمة الكود الذي كتبتة

عموما .. عندي نقطتان اضافيتان تؤثران على حساب الوقت

الاولى ... عند كتابة قيمة الى التايمر ... في حالتنا هذه 231 فان التايمر سوف يتوقف لمدة نبظتان قبل معاودة العمل ... فيجب اضافة ذلك الى الحسابات

الثانية الروتين الخاص بالمقاطعة يبدأ بعملية فحص لراية المقاطعة الخاصة بالتايمر وهذه ايضا تأخذ نبظة واحدة .... يجب ان تضاف الى الحسابات

وهناك امر ثالث ... وهو عملية القفز الى روتين المقاطعة .... عموما عمليات القفز العادية تأخذ نبظتين من المعالج .... لكن لا اعرف بالضبط ماهي الحالة مع عملية القفز الى روتين المقاطعة ....

وهناك امر رابع ... عند استخدام روتين للمقاطعات لابد من اجراء بعض الاحتياطات لضمان الرجوع الى البرنامج الاصلي بصورة صحيحة وبدون فقد بعض المعلومات المهمة عند الانتهاء من برنامج المقاطعة ... هذه الاجراءات تتمثل عادتا بخزن قيمة الرجستر w والرجستر status في الرام ثم اكمال روتين المقاطعة ... وقبل الرجوع الى البرنامج الاصلي يتم ارجاع القيم الاصلية لهذه الرجسترات من الذاكرة وانهاء روتين المقاطعة ... يبدو ان هذه العملية يقوم بها المترجم الخاص بمايكروسي بدون ان يحتاج كاتب البرنامج بوضعها في البرنامج .... لكن طبعا يجب ان تضاف الى العمليات الحسابية الخاصة بنا والمتعلقة بالوقت ... على الاقل ستأخذ ثلاث نبظات من المعالج


عموما وكما قلت في بداية حديثي من الصعب تتبع الزمن بالضبط .... لكن ربما افضل طريقة لحسم الامر ربما يكون كالتالي

بعد ترجمة البرنامج قم باظهاره بكود الاسمبلي .... ثم قم بتشغيل مصحح الاخطاء واستخدم ساعة التوقيت لحساب الزمن المستغرق من قبل اي مجموعة اوامر ... ذلك سيعطيك فكرة كاملة عن تصرف البرنامج ... والزمن الذي تستغرقة كل عملية

كما يمكنك الاستعانة بالموقع التالي حيث فية برنامج لحساب الزمن الخاص بالتايمرات والمقاطعات ويعطيك الكود باكثر من لغة برمجة
http://www.mikroe.com/forum/viewtopic.php?f=3&t=49698
تحياتي


التعديل الأخير تم بواسطة : WRHLAMDA بتاريخ 07-10-2013 الساعة 11:37 PM

الصورة الرمزية حسن هادي محمود
حسن هادي محمود
:: عضو ذهبي ::
تاريخ التسجيل: Sep 2012
الدولة: العراق /البصره
المشاركات: 2,673
نشاط [ حسن هادي محمود ]
قوة السمعة:
قديم 08-10-2013, 07:59 PM المشاركة 14   
افتراضي


السلام عليكم

واحدة من الامور الصعبة في استخدام لغات البرمجة العالية المستوى في برمجة المايكرو كونترولر هي حساب الوقت اللازم لانجاز عدد معين من الخطوات ... فانت لاتعرف بالتحديد كيف سيتم ترجمة الكود الذي كتبتة

عموما .. عندي نقطتان اضافيتان تؤثران على حساب الوقت

الاولى ... عند كتابة قيمة الى التايمر ... في حالتنا هذه 231 فان التايمر سوف يتوقف لمدة نبظتان قبل معاودة العمل ... فيجب اضافة ذلك الى الحسابات

الثانية الروتين الخاص بالمقاطعة يبدأ بعملية فحص لراية المقاطعة الخاصة بالتايمر وهذه ايضا تأخذ نبظة واحدة .... يجب ان تضاف الى الحسابات

وهناك امر ثالث ... وهو عملية القفز الى روتين المقاطعة .... عموما عمليات القفز العادية تأخذ نبظتين من المعالج .... لكن لا اعرف بالضبط ماهي الحالة مع عملية القفز الى روتين المقاطعة ....

وهناك امر رابع ... عند استخدام روتين للمقاطعات لابد من اجراء بعض الاحتياطات لضمان الرجوع الى البرنامج الاصلي بصورة صحيحة وبدون فقد بعض المعلومات المهمة عند الانتهاء من برنامج المقاطعة ... هذه الاجراءات تتمثل عادتا بخزن قيمة الرجستر w والرجستر status في الرام ثم اكمال روتين المقاطعة ... وقبل الرجوع الى البرنامج الاصلي يتم ارجاع القيم الاصلية لهذه الرجسترات من الذاكرة وانهاء روتين المقاطعة ... يبدو ان هذه العملية يقوم بها المترجم الخاص بمايكروسي بدون ان يحتاج كاتب البرنامج بوضعها في البرنامج .... لكن طبعا يجب ان تضاف الى العمليات الحسابية الخاصة بنا والمتعلقة بالوقت ... على الاقل ستأخذ ثلاث نبظات من المعالج


عموما وكما قلت في بداية حديثي من الصعب تتبع الزمن بالضبط .... لكن ربما افضل طريقة لحسم الامر ربما يكون كالتالي

بعد ترجمة البرنامج قم باظهاره بكود الاسمبلي .... ثم قم بتشغيل مصحح الاخطاء واستخدم ساعة التوقيت لحساب الزمن المستغرق من قبل اي مجموعة اوامر ... ذلك سيعطيك فكرة كاملة عن تصرف البرنامج ... والزمن الذي تستغرقة كل عملية

كما يمكنك الاستعانة بالموقع التالي حيث فية برنامج لحساب الزمن الخاص بالتايمرات والمقاطعات ويعطيك الكود باكثر من لغة برمجة
http://www.mikroe.com/forum/viewtopic.php?f=3&t=49698
تحياتي
شكرا أحي كريم برنامج ممتاز
عندما أتبعت حسب خطوات برنامج أعطاني بشاشه زمن =500 مايكروثانيه اي قيمه صحيحه 100% ولكن باسلوسكوب قيمه مختلفه اي هما بنظرك صحيح
يمكنك ملاحظه كود سابق لحساب الزمن عندما يكون pwm على وضع on
http://img02.arabsh.com/uploads/imag...414361f20c.png
http://img02.arabsh.com/uploads/imag...414361f105.png
http://img02.arabsh.com/uploads/imag...414361f104.png


WRHLAMDA
:: عضو فضي ::
تاريخ التسجيل: Feb 2005
المشاركات: 630
نشاط [ WRHLAMDA ]
قوة السمعة:
قديم 08-10-2013, 09:22 PM المشاركة 15   
افتراضي


السلام عليكم

لم افهم بالتحديد كيف وما يتم كتابتة على الشاشة .... لذلك لا استطيع ابداء اي حكم

لكن هناك نقطة ممكن اشير اليها وهي ان اول نبظة يتم توليدها لن تكون قيمها صحيحة فلا تعتمد عليها في القياس بل اعتمد على النبظة الثانية وما بعدها

.... والامر يعود الى عملية المقارنة التي تجريها وعلى اساسها تحدد ان كان الاخراج صفر او 1 ......... حيث ان الاخراج سوف يتحول الى 0 بعد 550 نبظة وليس 500 نبظة حيث عند وصول العداد count الى 500 لن يتحقق الشرط ولن يتحول الاخراج الى 0 بل ينتظر زمن مقاطعة اخرى ليصبح 550 فيتحقق الشرط ويتحول الاخراج الى 0

if(cont<=500)pwm=on
.... عموما بما اني لا استخدم لغة سي فربما فسرت خطروات المقارنة الشرطة بشكل خاطئ او ربما هي مكتوبة بحيث تتصرف ليس كما نتوقع ... ربما عليك مراجعة هذه الخطوات بشكل دقيق وطريقة كتابتها

تحياتي


الصورة الرمزية حسن هادي محمود
حسن هادي محمود
:: عضو ذهبي ::
تاريخ التسجيل: Sep 2012
الدولة: العراق /البصره
المشاركات: 2,673
نشاط [ حسن هادي محمود ]
قوة السمعة:
قديم 08-10-2013, 09:41 PM المشاركة 16   
افتراضي


السلام عليكم

لم افهم بالتحديد كيف وما يتم كتابتة على الشاشة .... لذلك لا استطيع ابداء اي حكم

لكن هناك نقطة ممكن اشير اليها وهي ان اول نبظة يتم توليدها لن تكون قيمها صحيحة فلا تعتمد عليها في القياس بل اعتمد على النبظة الثانية وما بعدها

.... والامر يعود الى عملية المقارنة التي تجريها وعلى اساسها تحدد ان كان الاخراج صفر او 1 ......... حيث ان الاخراج سوف يتحول الى 0 بعد 550 نبظة وليس 500 نبظة حيث عند وصول العداد count الى 500 لن يتحقق الشرط ولن يتحول الاخراج الى 0 بل ينتظر زمن مقاطعة اخرى ليصبح 550 فيتحقق الشرط ويتحول الاخراج الى 0

if(cont<=500)pwm=on
.... عموما بما اني لا استخدم لغة سي فربما فسرت خطروات المقارنة الشرطة بشكل خاطئ او ربما هي مكتوبة بحيث تتصرف ليس كما نتوقع ... ربما عليك مراجعة هذه الخطوات بشكل دقيق وطريقة كتابتها

تحياتي
اخي كريم كتابه شرط صحيح
جربت فكرتك بعدم قياس من اول نبضه فقسمت من نبضه خامسه وجدت قراءه على شاشه صحيحه انظر الى هذه صور
http://img02.arabsh.com/uploads/imag...414362f501.png
كود:
void interrupt()
{
 if(T0IF_bit ==1)
  {
   T0IF_bit=0;
    tmr0=230;
   cont=cont+50;

   if(cont<=350)pwm=on;

  else if(cont>350&& cont<1000){pwm=off; }
  else if(cont>=1000)cont=0;

  }
}
وهذه من نبضه خامسه
كود:
  while(pwm==off)time=0;
   while(pwm==on)time=cont;

  if(time>0 && x==5)
   {

     lcd_chr(1,1,(time/1000)+48);
     lcd_chr_cp( ((time%1000)/100)+48);
     lcd_chr_cp( ((time%1000%100)/10)+48);
     lcd_chr_cp( (time%1000%100%10)+48);
     portb.f5=~portb.f5;
     inttostr(cont,txt);
     lcd_out(1,6,txt);
    }
    x++;
    if(x>6)x=10;
   }
حتى لو اجعلها من نبضه ثانيه تعطي بشاشه قراءه صحيحه ولكن في اسلسكوب مشكله واضحه
تحياتي لك أخي كريم وشكرا على تعاونك



الساعة معتمدة بتوقيت جرينتش +3 الساعة الآن: 01:43 AM
موقع القرية الالكترونية غير مسؤول عن أي اتفاق تجاري أو تعاوني بين الأعضاء
فعلى كل شخص تحمل مسئولية نفسه إتجاه مايقوم به من بيع وشراء وإتفاق وأعطاء معلومات موقعه
التعليقات المنشورة لا تعبر عن رأي موقع القرية الالكترونية ولايتحمل الموقع أي مسؤولية قانونية حيال ذلك (ويتحمل كاتبها مسؤولية النشر)