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

   

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 01-05-2015, 09:01 PM المشاركة 41   
افتراضي




أستاذي العزيز في هذا المثال لماذا لا يتكرر البرنامج عند كل ضغط للمفتاح
فإنه يظهر قيمة D0=1 ولا يتغير شيء فيما بعد

وأيضا المثال الذي يليه نفس الشي وعند استخدام حلقة FOR
يتم تنفيذ الأمر لمرة واحدة فقط وحتى لو تكرر الضغط

أرجو توضيح هذه النقاط

أقوم بتطبيق المثال في المترجم وتجربته في بروتوس


مع كل الشكر وبالتوفيق
أخى الكريم شكرا جزيل لك
شكرا لك على السؤال
بالفعل هذا الجزء من البرنامج يفعل ما ذكرته فقط وهو لتوضيح اتخاذ القرار ولم نذكر أن الليد عاد إلى حالته الابتدائية حتى يتأثر مرة أخرى وإذا أردنا ذلك يمكننا على سبيل المثال كتابة البرنامج بالشكل التالى

كود:
//Lesson1-EX4 Tests an input
#include <16F877A.h>
void main()
{
   int x;                // Declare variable
   output_D(0);             // Clear all outputs

  while(1)                // Loop always
    {
         x = input(PIN_C0);          // Get input state
        if(x == 1)output_high(PIN_D0);    // Change output 
        else output_low(PIN_D0);
   }
}
عندئذ حالة الليد تتبع حالة المفتاح
مع العلم بأنه يمكن كتابة البرنامج بالشكل التالى :
كود:
//Lesson1-EX4 Tests an input
#include <16F877A.h>
void main()
{
   //int x;                // Declare variable
   output_D(0);             // Clear all outputs

  while(TRUE)                // Loop always
    {
         
        if(input(PIN_C0))output_high(PIN_D0);    // Change output
        else output_low(PIN_D0);
   }
}

اعلانات

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 01-05-2015, 10:52 PM المشاركة 42   
افتراضي مثال بسيط الاستخدام المقاطعة الخارجية :


مثال بسيط الاستخدام المقاطعة الخارجية :



فى البداية يكون الليد LED6 مضاء والليد LED7 مطفأ . عند الضغط على الزر المتصل بطرف المقاطعة الخارجية وهو RB0 ، يصبح الليد LED6 مطفأ والليد LED7 مضاء لمدة نصف ثانية ، تعود بعدها الحالة الابتدائية ، الليد LED6 مضاء والليد LED7 مطفأ .

كود:
#include <16F877A.h>
#use delay(clock=4000000)

void high_b6_low_b7() {
output_high(PIN_B6);
output_low(PIN_B7);
}

void low_b6_high_b7() {
output_low(PIN_B6);
output_high(PIN_B7);
}
///////////////////////////////////////////////////////////

#INT_EXT
void RB0_handler() {
low_b6_high_b7();
delay_ms(500);
high_b6_low_b7();
}
///////////////////////////////////////////////////////////
/*
* Keep B6 on and B7 off. Pressing the button causes interrupt:
* B6 off and B7 on, delay half second, then B6 on and B7 off
*/
void main() {
enable_interrupts(GLOBAL); // enable all interrupts
enable_interrupts(INT_EXT); // enable external interrupt from pin RB0/INT

high_b6_low_b7();

while (true) {
// do nothing
}
}

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

الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 02-05-2015, 02:22 AM المشاركة 43   
افتراضي


برنامج مولد نبضات بتردد 1KHz باستخدام المقاطعة بالمؤقت Timer0
البرنامج :

كود:
#INCLUDE <16F877A.h>
#use delay(clock=4000000)

#int_TIMER0
void TIMER0_isr(void) {
   output_toggle(PIN_B0);
   set_timer0 (26);  }               //Set initial value  

void main() {
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);   //Timer0 setup : internal & divided by 2 

  set_timer0 (26);                    //Set initial value  
  enable_interrupts(INT_TIMER0);       //Enable local timer0 interrupt 
  enable_interrupts(global);           //Enable global interrupts 

  while (1);         //endless loop 
}
فى هذا البرنامج :
• نبضات الساعة الخارجية المستخدمة ترددها 4 ميجاهرتز ، إذا تردد الساعة الداخلية يكون واحد ميجا هرتز أى نبضة كل واحد ميكروثانية .
• تمر هذه النبضات على قاسم التردد السابق للمؤقت بمعامل قسمة على “2” فيكون خرجه نبضات بتردد 500 كيلوهرتز أى نبضة كل 2 ميكروثانية .
• تصل هذه النبضات إلى دخل المؤقت timer0 حيث تم وضع قيمة ابتدائية قدرها “26” ليصل إلى التجاوز overflow بعد (256 – 26 = 230 ) أى يحدث تجاوز بعد زمن قدره (2 * 230 = 460 us) والتى تصل عمليا إلى 500 ملى ثانية توصيل و500 ملى ثانية فصل ويكون الومن الدورى واحد ملى ثانية وبالتالى فإن تردد النبضات الناتجة يكون 1000 هرتز (مقلوب الزمن الدورى بالثوانى) أى واحد كيلوهرتز .









http://fathallaabdelaziz.forumarabia.com/



الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 02-05-2015, 01:34 PM المشاركة 44   
افتراضي فكرة إنشاء ثرموستات باستخدام المقاومة السالبة NTC والمحول ADC ووحدة العرض LCD مع المت


فكرة إنشاء ثرموستات باستخدام المقاومة السالبة NTC والمحول ADC ووحدة العرض LCD مع المترجم CCS C
المقاومة السالبة المستخدم من النوع 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)
البرنامج :


كود:
#include "16f877A.h"
#device adc=10
#use delay(clock=4000000)
#include <math.h>                //Needed for mathematical calculations
#include <lcd.c>

void main() {

   float tv,tr,temp,y;                 //Equation variables
   int16 value;
   
   lcd_init();
   
   setup_port_a( ALL_ANALOG );
   setup_adc( ADC_CLOCK_INTERNAL );
   set_adc_channel( 0 );
   delay_us(10);
   
   do {
      value = Read_ADC();
      
      tv = 5.0 * value / 1024.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;
      
      printf(lcd_putc,"\nT = %04.2fC", temp);
   } while (TRUE);
}
طريقة التنفيذ وحل المعادلات :
الخطوة الأولى :
تحويل نتيجة التحويل من تناظرى إلى رقمى ADC إلى الجهد المعبر عن درجة الحرارة tv بضرب القراءةvalue فى “5” (جهد المرجع) والقسمة على أقصى قيمة تحويل “1024” أو مباشرة بما يعرف بدقة المحول 0.0048828125 5/1024 = لكننا سوف نترك ذلك للمترجم يقوم به نيابة عنا :

كود:
value = Read_ADC();
 tv = 5.0 * value / 1024.0;
ملحوظة :
تم تعريف المتغير value بالنوع int16 ليستوعب القيمة 1024 ، فى حين تم تعريف متغير نتيجة عملية التحويل السابقة بالنوع float حتى يستوعب النتيجة والتى تحتوى على عدد صحيح كسر عشرى .

الخطوة الثانية :
إيجاد قيمة المقاومة المعتمدة على الحرارة tr بمعلومية الجهد المعبر عن درجة حرارة tv كما هو موضح بالمعادلة :

كود:
RT = 10000VT/(5-VT)
كما يلى :

كود:
tr = tv * 10000.0 / (5.0 – tv) ;

الخطوة الثالثة :
إيجاد درجة الحرارة بمعلومية المقاومة المعتمدة على الحرارة tr كما هو موضح بالمعادلة :



حل هذه المعادلة يتم على مراحل :
إيجاد قيمة اللوغاريتم :

كود:
y = log(tr / 20000.0);
ملحوظة :
تم إدراج مكتبة الدوال الرياضية فى مقدمة البرنامج لحل هذه المعادلة :

كود:
#include <math.h>
إيجاد مقام الحد الأول بقسمة y على 4050 وجمع الكسر 1/298.15 كما يلى :
y = (1.0/289.15) + (y * ( 1.0 / 4050.0) ) ;
إيجاد نتيجة الحد الأول :

كود:
temp = 1.0 / y ;
أخيرا أيجاد درجة الحرارة بطرح 273.15 من الحد الأول :


كود:
temp = temp – 273.15 ;

عرض النتيجة على شاشة LCD :

كود:
printf(lcd_putc , “\nT = %04.2fC”, temp);



http://fathallaabdelaziz.forumarabia.com/


الصورة الرمزية Sallam
Sallam
:: مهندس متميز ::
تاريخ التسجيل: Mar 2006
الدولة: Syria
المشاركات: 515
نشاط [ Sallam ]
قوة السمعة:
قديم 02-05-2015, 04:58 PM المشاركة 45   
افتراضي




أخى الكريم شكرا جزيل لك
شكرا لك على السؤال
بالفعل هذا الجزء من البرنامج يفعل ما ذكرته فقط وهو لتوضيح اتخاذ القرار ولم نذكر أن الليد عاد إلى حالته الابتدائية حتى يتأثر مرة أخرى وإذا أردنا ذلك يمكننا على سبيل المثال كتابة البرنامج بالشكل التالى

كود:
//Lesson1-EX4 Tests an input
#include <16F877A.h>
void main()
{
   int x;                // Declare variable
   output_D(0);             // Clear all outputs

  while(1)                // Loop always
    {
         x = input(PIN_C0);          // Get input state
        if(x == 1)output_high(PIN_D0);    // Change output 
        else output_low(PIN_D0);
   }
}
عندئذ حالة الليد تتبع حالة المفتاح
مع العلم بأنه يمكن كتابة البرنامج بالشكل التالى :
كود:
//Lesson1-EX4 Tests an input
#include <16F877A.h>
void main()
{
   //int x;                // Declare variable
   output_D(0);             // Clear all outputs

  while(TRUE)                // Loop always
    {
         
        if(input(PIN_C0))output_high(PIN_D0);    // Change output
        else output_low(PIN_D0);
   }
}
أشكرك أستاذي الكريم على التوضيح

الفكرة اصبحت واضحة باستخدام جملة الشرط التي تتحقق فيما اذا كان المفتاح قيمته واحد سيضيء الليد والا سينطفئ.

اشكرك لتعبك


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-05-2015, 03:29 AM المشاركة 46   
افتراضي استخدام وحدة LCD لعرض بيانات المفتاح الذى تم الضغط عليه باستخدام الربط مع منفذ واحد :


استخدام وحدة LCD لعرض بيانات المفتاح الذى تم الضغط عليه باستخدام الربط مع منفذ واحد :
يتضمن المترجم CCS C مكتبة دوال لتشغيل لوحة مفاتيح 3 X 4 تسمى KBD.C ، تحتوى على المكتبات التالية :

• الدالة kbd_init() :

لتهيئة لوحة المفاتيح ، ويجب وضعها فى الدالة الرئيسية .

• الدالة kbd_getc() : للحصول على بيانات المفتاح الذى تم الضغط عليه وفقا لما هو مذكور بالملف kbd.c ، كما هو مبين بالشكل التالى :



كما هو موضح بالملف kbd.c ، يمكن ربط لوحة المفاتيح مع المنفذ PORTB أو المنفذ PORTD



المنفذ الافتراضى اربط لوحة المفاتيح هو المنفذ PORTD ، ولربطها مع المنفذ PORTB يتم إزالة رمز التعليق “//” من أمام السطر المبين بالشكل التالى ، مع التأكد من المنفذ المستخدم به مقامات رفع (أو وحدة LCD) فى أطراف الأعمدة :



تدريب : استخدام وحدة LCD لعرض بيانات المفتاح الذى تم الضغط عليه باستخدام الربط مع منفذ واحد :
الأدوات المستخدمة فى برنامج المحاكاة ISIS : PIC16F877A , LM016L , KEYPAD-PHONE .




البرنامج :

كود:
#include <16F877A.h>
#use delay(clock= 4000000)

#define use_portb_kbd TRUE
#define use_portb_lcd TRUE
#include <lcd.c>
#include <kbd.c>
        
void main() {
   char k; 
   int  x;
          
   lcd_init(); 
   kbd_init();
   port_b_pullups(TRUE); 

   lcd_putc("\fPreee Key...\n"); // Initially clear screen and print fPreee Key... , then new line 
                                    
   while (TRUE) {
      k=kbd_getc(); // get key as character , save in k
      x=k-48;                             //convert character k to numeric value x 
      if(k!=0){  // if any key is pressed
        
        if(k=='*') // if k is * 
          lcd_putc('\f'); // clear screen 
          
        else
           lcd_putc(k);             //  r print character k 
           delay_ms(1000);
           
           //after that or both cases
           printf(lcd_putc,"\f Char=%c",k); // clear and print k as character %c 
           delay_ms(1000);
           
           printf(lcd_putc,"\f Char=%u",k); //clear and Print k as ASCII value %u
           delay_ms(1000);
           
           printf(lcd_putc,"\f Nume=%u",x); //clear and Print the numerical value of the character
           delay_ms(1000);
           
           lcd_putc("\fPress Key...\n");
      }
   }
}


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-05-2015, 03:32 AM المشاركة 47   
افتراضي مشروع قفل إلكترونى بسيط باستخدام ذاكرة EEPROM بالميكروكونترولر ولوحة مفاتيح وشاشة LCD


مشروع قفل إلكترونى بسيط باستخدام ذاكرة EEPROM بالميكروكونترولر ولوحة مفاتيح وشاشة LCD :
الأدوات المستخدمة فى برنامج المحاكاة ISIS : PIC16F877A , KEYPAD , RES , BD135 , CELL , RELAY .
الدائرة الكهربية :



البرنامج :

كود:
#include <16F877a.h>
#use delay(clock= 4000000)
//#use standard_io(a) 
#define use_portb_kbd TRUE
#define use_portb_lcd TRUE
#include <lcd.c>
#include <kbd.c>
//#include <stdlib.h>

#rom 0x2100={'7','2','3'}  // Save data 7 , 2 , 3 in position 0,1 and 2 of the EEPROM respectively 
                           
void main() {
   char k;
   int i;
   char data[3], key[3];  //Storage arrays for data and key 

   lcd_init();
   kbd_init();
   port_b_pullups(TRUE);

   while (TRUE) {
   i=0;            //array index position

   printf(lcd_putc,"\fPress Key 1\n");  //clear screen , print Press Key 1 , go to a new line 

   while(i<=2){                //Three data
      k=kbd_getc();            //Read keypad
      if (k!=0)                //If any key is Pressed 
         {data[i]=k;           //It is stored in the corresponding position
          i++;                //of the array
          printf(lcd_putc,"\fPress Key %u\n",i+1);  //Next item
         }
    }

   for (i=0;i<=2;i++) {             //EEPROM passes data to the key array 
     key[i]=read_eeprom(i);}

   if ((data[0]==key[0])&&(data[1]==key[1])&&(data[2]==key[2]))
      { printf(lcd_putc,"\fDoor Open"); //Compares the data with the key
        output_high(PIN_A0);                //If equal gives pulse to relay
        delay_ms(2000);
        output_low(PIN_A0);}
   else printf(lcd_putc,"\fDoor Closed");  //key error
   delay_ms(1000);
   }
}


الصورة الرمزية F.Abdelaziz
F.Abdelaziz
:: استاذ و مشرف قسم الالكترونيات ::
تاريخ التسجيل: May 2007
المشاركات: 6,832
نشاط [ F.Abdelaziz ]
قوة السمعة:
قديم 03-05-2015, 03:38 AM المشاركة 48   
افتراضي مشروع التحكم فى محرك تيار مستمر باستخدام التعديل فى عرض النبضات ولوحة المفاتيح :


مشروع التحكم فى محرك تيار مستمر باستخدام التعديل فى عرض النبضات ولوحة المفاتيح :
الأدوات المطلوبة فى برنامج المحاكاة ISIS : PIC16F877A , KEYPAD-PHONE , RES , 2SK1058 , CELL , MOTOR .
الدائرة الكهربية :







البرنامج :
مبدأ العمل:
تتكون النبضات المربعة من جزء مرتفع (موجب) يسمى PWMH وجزء منخفص (سالب) يسمى PWML . التحكم فى عرض النبضة PWM يعنى التحكم فى عرض هذه الأجزاء ، فزيادة الجزء المرتفع يؤدى إلى زيادة متوسط جهد النبضة والعكس بالعكس وبالتالى التحكم فى محرك التيار المستمر عن طريق الجهد المطبق على طرفيه .




أقصى قيمة لعرض النبضة ككل يمكن اعتبارها “255” قسم ( بايت ) ، الجزء المرتفع يمكن أن يكون من الصفر وحتى “255” . فى هذا المثال ، عند الضغط على مفتاح لوحة التحكم يتم توليد نبضات بعرض متغير تبعا لهذا المفتاح وصولا إلى المفتاح “9” حيث يتم جعل الجزء الموجب عند أقصى قيمة له ، وبالتالى يتم التحكم فى سرعة دوران المحرك حتى نصل إلى أقصى سرعة . بناء على ذلك يمكن التعبير عن عرض جزء النبضة المرتفع بالمعادلة :
PWMH = (255/9) * Key =~ 28 * Key
فعند الضغط على المفتاح “0” يكون الجزء الموجب بصفر والسرعة بصفر ، حتى نصل إلى المفتاح “9” فيكون الجزء الموجب بالقيمة “255” وهى تناظر القيمة القصوى ويكون المحرك عند أقصى سرعة له .
للحصول على جزء النبضة المنخفص نطرح قيمة جزء النبضة الموجب من القيمة “255” .


كود:
#include <16f877A.h>
#USE DELAY (CLOCK=4000000)
#define use_portb_kbd TRUE
#INCLUDE <kbd.c>
//#USE STANDARD_IO (a)

VOID MAIN()
{
   CHAR k,kant='0';     //Keyboard k value, previous value k keyboard
   char PWMH=0,PWML=0;  //High and low half period
   
   kbd_init();
   PORT_B_PULLUPS(TRUE);

WHILE (1) {                    //Infinite loop 
      k=kbd_getc();            //Reads ASCII value of the pressed key 
      if (k=='\0') k=kant;     //If key (\ 0) is pressed the former value is used
      if ((k=='*') || (k=='#')) k='0';  //Pressing * or # is assigned a zero value.
      kant=k;                          //Pressed key is saved
       k=k-48;                         //It becomes a numerical value ASCII
       PWMH=k*28;                     //Key ratio value and half period Alto.
       PWML=255-PWMH;                 //Under half period
      for(PWMH;PWMH>0;PWMH--){        //Getting high-level output
       OUTPUT_HIGH(PIN_A0);}
      for(PWML;PWML>0;PWML--){      //Getting output at low level
      OUTPUT_LOW(PIN_A0);}
  }
}




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