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

   

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



البرنامج :
سوف نكتب برنامج لاختبار الاتصال بالناقل I2C بين الميكروكونترولر PIC18F2550 وثلاثة أجهزة متصلة بالناقل . سوف يقوم البرنامح أولا بالتحقق (اختبار) من وجود جميع الأجهزة الثلاثة على الناقل , ثم يرسل أمر تحويل درجة الحرارة إلى الجهاز DS1631 . عندئذ يتم قراءة درجة الحرارة فى شكل 2 بايت وتخزينها فى شريحتى الذاكرة ( البايت المرتفع فى شريحة EEPROM الأولى والبايت المنخفض فى شريحة EEPROM الثانية . بدءا من الموقع صفر ). بعد تسجيل خمس عينات , يتم قراءتها بشكل تسلسلى من مواقع ذاكرة EEPROM , وتحويلها إلى وحدات درجة حرارة فعلية (°C) وعرضها على شاشة وحدة العرض LCD .
المترجم mikroC Pro for PIC يقدم مكتبة روتينات للعامل مع الاتصال بالناقل I2C , فيما يلى ملخص لها :
void I2C1_Init(const unsigned long clock);



  • أول شىء يتعين علينا القيام به هو تهيئة ( إعداد ) الوحدة (الموديول) MSSP للاتصال I2C . يمكن أم يتم ذلك بالدالة I2C1_Init , على سبيل المثال I2C_Init(100000) سوف تهىء الموديول MSSP من أجل الاتصال I2C يتردد (سرعة) 100 KHz .

unsigned short I2C1_Start(void);



  • هذه الدالة تحدد ما إذا كان الناقل IC حرا free فيتم إصدار إشارة حالة "البدء" Start . عائد (نتيجة) هذه الدالة بالصفر إذا لم يكن هناك خطأ .

void I2C1_Repeated_Start(void);
  • إصدار حالة "تكرار البدء" repeated-start .

unsigned short I2C1_Is_Idle(void);



  • تتحقق مما إذا كان الناقل I2Cحرار . إذا كان حرار تعود بواحد وإن لم يكن حرا (مشغول) تعود بالصفر .

unsigned short I2C1_Rd(unsigned short ack);

  • قراءة بايت واحد من التابع وإرسال إشارة "عدم التسلم" NACK إذا كان البارامتر ack وإلا ترسل "التسلم" acknowledge . على سبيل المثال , إذا احتاج الميكروكونترولر لقراءة درجة حرارة قى شكل 2 بايت من DS1631 فيجب عليه استخدام I2C1_Rd(1) لقراءة البايت الأول و I2C1_Rd(0) لقراءة البايت الثانى .
unsigned short I2C1_Wr(unsigned short data);


  • إرسال بيانات بايت من خلال الناقل I2C bus . هذه الدالة تعود بالصفر إذا لم يكن هناك خطأ .
void I2C1_Stop(void);



  • إصدار حالة الإيقاف Stop .

اعلانات

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


فى برنامجنا , سوف يقوم PIC18F2550 أولا من التحقق تواجد (إتاحة) الثلاثة أجهزة على الناقل . يتم ذلك بإرسال عنوان الجهاز لكل منهم فإذا تسلمه , فهذا يعنى أنه موجود . روتين الميكروسى للتحقق من وجود الجهاز على الناقل I2C كما يلى :

كود:
void check_device(unsigned short dev_address){ I2C1_Start(); if (I2C1_Wr(dev_address)){ Lcd_Out(2,1,"Device not found"); } else Lcd_Out(2,1,"Device is OK"); I2C1_Stop(); }

الروتين التالى يسمح للميكروكونترولر PIC18F2550 بإرسال أمر "بدء تحويل درجة الحرارة"
Start Convert T إلى DS1631 , ثم الانتظار لمدة 750 ms حتى يتم إجراء تحويل درجة الحرارة فى شكل 12-bit , وفى النهاية يتم استقبال قراءة درجة الحرارة المكونة من 2 بايت .

كود:
// Read temperature
 I2C1_Start();
 I2C1_Wr(DS1631);               // Send device address
 I2C1_Wr(0x51);                 // Start Convert Temp command
 I2C1_Stop();
 Delay_ms(750);
 I2C1_Start();
 I2C1_Wr(DS1631);               // DS1631 Address again
 I2C1_Wr(0xAA);                 // Read Temperature command
 I2C1_Repeated_Start();
 I2C1_Wr(DS1631+1);              // Address with Read
 MS_Byte = I2C1_Rd(1);           // Read MSB and send ACK
 LS_Byte = I2C1_Rd(0);            // Read LSB and send NAK
 I2C1_Stop();

يمكنك ملاحظة أنه عند قراءة البايت الأخير فإن PIC18F2550 ليس بحاجة لإرسال نبضة "تسلم" acknowledge.
الروتينات التالية سوف تؤدى عمليات قراءة وكتابة بايت مع شرائح الذاكرة EEPROMs .

كود:
//--------------- Reads data from 24LC512 EEPROM - single location
unsigned short EEPROM_ReadByte(unsigned short EEPROM_Select, unsigned short rAddress) {
 unsigned short rAddrH, rAddrL, result;
 rAddrH = 0;
 rAddrL = rAddress;
 I2C1_Start();             // issue I2C1 start signal
 I2C1_Wr(EEPROM_Select);    // send byte via I2C1  (device address + W)
 I2C1_Wr(rAddrH);           // send Higher address byte
 I2C1_Wr(rAddrL);           // send Lower address byte
 I2C1_Repeated_Start();    // issue I2C1 signal repeated start
 I2C1_Wr(EEPROM_Select+1);   // send byte (device address + R)
 result = I2C1_Rd(0u);     // Read the data (NO acknowledge)
 while (!I2C1_Is_Idle())
 asm nop;                // Wait for the read cycle to finish
 I2C1_Stop();
 return result;
}
//--------------- Writes data to 24LC512 EEPROM - single location
void EEPROM_WriteByte(unsigned DeviceSelect, unsigned short wAddress, unsigned short wData) {
 unsigned short wAddrH, wAddrL;
 wAddrH = 0;
 wAddrL = wAddress;
 I2C1_Start();        // issue I2C1 start signal
 I2C1_Wr(DeviceSelect);   // send control byte
 I2C1_Wr(wAddrH);     // send higher address byte
 I2C1_Wr(wAddrL);     // send lower address byte
 I2C1_Wr(wData);      // send data to be written
 I2C1_Stop();
}



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

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


كود البرنامج :

كود:
/*
  Project: Multiple I2C devices on a common bus
  MCU: PIC18F2550 * 48.0 MHz (StartUSB for PIC board)
  Copyright * Rajendra Bhatt
  May 6, 2011
*/
// Define LCD module connections.
 sbit LCD_RS at RC6_bit;
 sbit LCD_EN at RC7_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 TRISC6_bit;
 sbit LCD_EN_Direction at TRISC7_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 connection definition

void Delay2s(){
 Delay_ms(2000);
}
void check_device(unsigned short dev_address){
 I2C1_Start();
 if (I2C1_Wr(dev_address)){
  Lcd_Out(2,1,"Device not found");
 }
 else Lcd_Out(2,1,"Device is OK");
 I2C1_Stop();
}
//--------------- Writes data to 24LC512 EEPROM - single location
void EEPROM_WriteByte(unsigned DeviceSelect, unsigned short wAddress, unsigned short wData) {
    unsigned short wAddrH, wAddrL;
    wAddrH = 0;
    wAddrL = wAddress;
    I2C1_Start();        // issue I2C1 start signal
    I2C1_Wr(DeviceSelect);   // send control byte
    I2C1_Wr(wAddrH);     // send higher address byte
    I2C1_Wr(wAddrL);     // send lower address byte
    I2C1_Wr(wData);      // send data (data to be written)
    I2C1_Stop();
}
//--------------- Reads data from 24LC512 EEPROM - single location
unsigned short EEPROM_ReadByte(unsigned short EEPROM_Select, unsigned short rAddress) {
    unsigned short rAddrH, rAddrL, result;
    rAddrH = 0;
    rAddrL = rAddress;
    I2C1_Start();             // issue I2C1 start signal
    I2C1_Wr(EEPROM_Select);   // send byte via I2C1  (device address + W)
    I2C1_Wr(rAddrH);          // send Higher address byte
    I2C1_Wr(rAddrL);          // send Lower address byte
    I2C1_Repeated_Start();    // issue I2C1 signal repeated start
    I2C1_Wr(EEPROM_Select+1);            // send byte (device address + R)
    result = I2C1_Rd(0u);     // Read the data (NO acknowledge)
    while (!I2C1_Is_Idle())
      asm nop;                // Wait for the read cycle to finish
    I2C1_Stop();
    return result;
}
char message1[] = "I2C Devices ";
char message2[] = "with PIC18F2550" ;
char Sample[] = "Sample 0";
char temp[] = "00.0000 C";
unsigned int address, Fraction_Temp;
unsigned short i,MS_Byte, LS_Byte, Whole_Temp;
const int EEPROM1 = 0xA0, EEPROM2 = 0xA2, DS1631 = 0x90;
void main() {
  CMCON = 0x07;   // Disable comparators
  ADCON1 = 0x0F;  // Disable Analog functions
  TRISC = 0x00;
  TRISB = 0x00;
  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
  Lcd_Out(2,1,message2);   // Write message1 in 1st row
  Delay2s();
  I2C1_Init(100000);   // Initiate I2C
  // Check EEPROM1
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,1,"EEPROM1");
  check_device(EEPROM1);
  Delay2s();
  
  // Check EEPROM2
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,1,"EEPROM2");
  check_device(EEPROM2);
  Delay2s();
  
  // Check Sensor
  Lcd_Cmd(_LCD_CLEAR);
  Lcd_Out(1,1,"DS1631");
  check_device(DS1631);
  Delay2s();
  for (i=0; i<5; i++) {
    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Out(1,1,"Reading Temp.");
    // Read temperature
    I2C1_Start();
    I2C1_Wr(DS1631);               // Send device address
    I2C1_Wr(0x51);                 // Start Convert Temp command
    I2C1_Stop();
    Delay_ms(750);
    I2C1_Start();
    I2C1_Wr(DS1631);               // DS1631 Address again
    I2C1_Wr(0xAA);                 // Read Temperature command
    I2C1_Repeated_Start();
    I2C1_Wr(DS1631+1);              // Address with Read
    MS_Byte = I2C1_Rd(1);           // Read MSB and send ACK
    LS_Byte = I2C1_Rd(0);            // Read LSB and send NAK
    I2C1_Stop();
    Delay2s();
    // Write the MS Byte to EEPROM1
    
    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Out(1,1,"Writing MS Byte");
    EEPROM_WriteByte(EEPROM1, i, MS_Byte);
    Delay2s();
    // Write the LS Byte to EEPROM2
    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Out(1,1,"Writing LS Byte");
    EEPROM_WriteByte(EEPROM2, i, MS_Byte);
    Delay2s();
  }
    // Reading stored temperature samples
    Lcd_Cmd(_LCD_CLEAR);
    Lcd_Out(1,1,"Reading EEPROMs");
    Delay2s();
    for (i=0; i<5; i++){
     Lcd_Cmd(_LCD_CLEAR);
     Sample[7] = i+49;
     Lcd_Out(1,1,Sample);
     Whole_Temp = EEPROM_ReadByte(EEPROM1, i);
     Fraction_Temp = EEPROM_ReadByte(EEPROM2, i);
     Fraction_Temp = Fraction_Temp >>4;
     Fraction_Temp = 625*Fraction_Temp; // 12 bit resolution is 0.0625C
     temp[0] = Whole_Temp/10+48;
     temp[1] = Whole_Temp%10+48;
     temp[3] = Fraction_Temp/1000+48;
     temp[4] = (Fraction_Temp/100)%10+48;
     temp[5] = (Fraction_Temp/10)%10+48;
     temp[6] = Fraction_Temp%10+48;
     Lcd_Out(2,5,temp);
     Delay2s();
    }
  }


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


النتائج :
فيما يلى صور توضح تتابع العمليات المنفذة عند تنفيذ برنامج اختبار الناقل I2C .
1- رسالة البدء :



2- تمام وجود الشريح EEPROM1 :



3- تمام وجود الشريح EEPROM2 :






4- تمام وجود المستشعر DS1631 :




5- عند نزع (عدم وجود) أى من الأجهزة نحصل على بيان بذلك :




6- قراءة درجة الحرارة من المستشعر DS1631 :




7- كتابة البايت العلوى لدرجة الحرارة على EEPROM1 :




8- كتابة البايت السفلى لدرجة الحرارة على EEPROM2




9- قراءة العينات التى تم تسجيلها



10- أول عينة لدرجة الحرارة :


11- خامس عينة لدرجة الحرارة :



الخاتمة :
فى هذا التدريب تناولنا باختصار ما هو الناقل I2C وكيفية استخدامه لاتصال البيانات من وإلى الميكروكونترولر PIC كجهاز ماستر والاجهزة المتوافقة مع الناقل I2C كأجهزة تابعة . ولقد تم استكشاف عمليات القراءة والكتابة والعنونة لأجهزة متعددة على ناقل I2C مشترك وتنفيذ ذلك عن طريق المترجم mikroC Pro for PIC .
الناقل I2C أصبح شائع الاستخدام جدا فى عالم الأنظمة المدمجة حيث يوجد المئات من الأجهزة المتوافقة مع I2C متوفرة فى الأسواق فى شكل محول تناظرى لرقمى ADC و محول من رقمى لتناظرى DAC وكارت الذاكرة SRAM وكروت توسعة (زيادة) المداخل والمخارج I/O ومستشعرات الرطوبة ودرجة الحرارة ..ألخ.الآن فهمنا كيفية عمل بروتوكولها , وإلى أن يحين وقت تناول تفاصيل أكثر .


الصورة الرمزية king5star
king5star
:: مهندس جيد ::
تاريخ التسجيل: Jun 2008
الدولة: Alexandria, Egypt
المشاركات: 238
نشاط [ king5star ]
قوة السمعة:
قديم 30-08-2012, 04:58 AM المشاركة 13   
افتراضي


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


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


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

أخى الكريم

شكرا جزيلا لك

بارك الله فيك

مع تمنياتى بدوام التوفيق


hesham mohamed
:: مهندس متواجد ::
تاريخ التسجيل: Jun 2010
الدولة: مصر - الأسكندرية
المشاركات: 192
نشاط [ hesham mohamed ]
قوة السمعة:
قديم 05-09-2012, 07:44 PM المشاركة 15   
افتراضي


الف شكر على الشرح الرائع

هذا الشرح بصيغة pdf
http://arabsh.com/files/0e32444365f1...rcuit-pdf.html

هذا الشرح بصيغة mht
http://arabsh.com/files/0e32444364fb...rcuit-mht.html


mokhtarragab
:: مهندس متواجد ::
تاريخ التسجيل: Jan 2006
المشاركات: 61
نشاط [ mokhtarragab ]
قوة السمعة:
قديم 06-09-2012, 10:12 AM المشاركة 16   
افتراضي


شكرا ياباشمهندس علي الشرح الاكثر من رائع



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