اطلاعیه

Collapse
No announcement yet.

مشکل i2c (TWI) در Atmel Studio

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    مشکل i2c (TWI) در Atmel Studio

    سلام به همه مهندسین
    میخواستم سنسور SHT30 رو با اتمگا 16 راه اندازی کنم ، با کدویژن به راحتی این رو کار رو انجام دادم و هیچ مشکلی نبوده ولی با پروتکل i2c اتمل استودیو به مشکل برخورد کردم.
    چه به صورت نرم افزاری و چه i2c سخت افزاری
    از کتابخانه های مختلفی در اتمل استودیو استفاده کردم ولی زمان خواندن سنسور و پروتکل i2c کلا میکرو هنگ میکنه و روی متنی که روی ال سی دی نمایش داده بوده میمونه.
    حتی یه برنامه مطمئن از ایسی ساعت DS1307 برای تست استفاده کردم که با مگا8 بود ولی اون هم همین مشکل رو داشت و روی نوشته ال سی دی هنگ میکرد.
    آیا برای استفاده از i2c اتمل استودیو کار خاصی باید انجام بدیم؟ یا اینکه فیوزبیت خاصی نیاز به تغییر داره؟
    این هم کتابخانه i2c که استفاده کردم
    کد PHP:
    /*************************************************************************
    * Title:    I2C master library using hardware TWI interface
    * Author:   Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
    * File:     $Id: twimaster.c,v 1.4 2015/01/17 12:16:05 peter Exp $
    * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
    * Target:   any AVR device with hardware TWI 
    * Usage:    API compatible with I2C Software Library i2cmaster.h
    **************************************************************************/
    #include <inttypes.h>
    #include <compat/twi.h>

    #include "i2cmaster.h"


    /* define CPU frequency in hz here if not defined in Makefile */
    #ifndef F_CPU
    #define F_CPU 8000000UL
    #endif

    /* I2C clock in Hz */
    #define SCL_CLOCK  100000L


    /*************************************************************************
     Initialization of the I2C bus interface. Need to be called only once
    *************************************************************************/
    void i2c_init(void)
    {
      
    /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
      
      
    TWSR 0;                         /* no prescaler */
      
    TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation */

    }/* i2c_init */


    /*************************************************************************    
      Issues a start condition and sends address and transfer direction.
      return 0 = device accessible, 1= failed to access device
    *************************************************************************/
    unsigned char i2c_start(unsigned char address)
    {
        
    uint8_t   twst;

        
    // send START condition
        
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

        
    // wait until transmission completed
        
    while(!(TWCR & (1<<TWINT)));

        
    // check value of TWI Status Register. Mask prescaler bits.
        
    twst TW_STATUS 0xF8;
        if ( (
    twst != TW_START) && (twst != TW_REP_START)) return 1;

        
    // send device address
        
    TWDR address;
        
    TWCR = (1<<TWINT) | (1<<TWEN);

        
    // wail until transmission completed and ACK/NACK has been received
        
    while(!(TWCR & (1<<TWINT)));

        
    // check value of TWI Status Register. Mask prescaler bits.
        
    twst TW_STATUS 0xF8;
        if ( (
    twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

        return 
    0;

    }
    /* i2c_start */


    /*************************************************************************
     Issues a start condition and sends address and transfer direction.
     If device is busy, use ack polling to wait until device is ready
     
     Input:   address and transfer direction of I2C device
    *************************************************************************/
    void i2c_start_wait(unsigned char address)
    {
        
    uint8_t   twst;


        while ( 
    )
        {
            
    // send START condition
            
    TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
        
            
    // wait until transmission completed
            
    while(!(TWCR & (1<<TWINT)));
        
            
    // check value of TWI Status Register. Mask prescaler bits.
            
    twst TW_STATUS 0xF8;
            if ( (
    twst != TW_START) && (twst != TW_REP_START)) continue;
        
            
    // send device address
            
    TWDR address;
            
    TWCR = (1<<TWINT) | (1<<TWEN);
        
            
    // wail until transmission completed
            
    while(!(TWCR & (1<<TWINT)));
        
            
    // check value of TWI Status Register. Mask prescaler bits.
            
    twst TW_STATUS 0xF8;
            if ( (
    twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) 
            {            
                
    /* device busy, send stop condition to terminate write operation */
                
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
                
                
    // wait until stop condition is executed and bus released
                
    while(TWCR & (1<<TWSTO));
                
                continue;
            }
            
    //if( twst != TW_MT_SLA_ACK) return 1;
            
    break;
         }

    }
    /* i2c_start_wait */


    /*************************************************************************
     Issues a repeated start condition and sends address and transfer direction 

     Input:   address and transfer direction of I2C device
     
     Return:  0 device accessible
              1 failed to access device
    *************************************************************************/
    unsigned char i2c_rep_start(unsigned char address)
    {
        return 
    i2c_startaddress );

    }
    /* i2c_rep_start */


    /*************************************************************************
     Terminates the data transfer and releases the I2C bus
    *************************************************************************/
    void i2c_stop(void)
    {
        
    /* send stop condition */
        
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
        
        
    // wait until stop condition is executed and bus released
        
    while(TWCR & (1<<TWSTO));

    }
    /* i2c_stop */


    /*************************************************************************
      Send one byte to I2C device
      
      Input:    byte to be transfered
      Return:   0 write successful 
                1 write failed
    *************************************************************************/
    unsigned char i2c_writeunsigned char data )
    {    
        
    uint8_t   twst;
        
        
    // send data to the previously addressed device
        
    TWDR data;
        
    TWCR = (1<<TWINT) | (1<<TWEN);

        
    // wait until transmission completed
        
    while(!(TWCR & (1<<TWINT)));

        
    // check value of TWI Status Register. Mask prescaler bits
        
    twst TW_STATUS 0xF8;
        if( 
    twst != TW_MT_DATA_ACK) return 1;
        return 
    0;

    }
    /* i2c_write */


    /*************************************************************************
     Read one byte from the I2C device, request more data from device 
     
     Return:  byte read from I2C device
    *************************************************************************/
    unsigned char i2c_readAck(void)
    {
        
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
        while(!(
    TWCR & (1<<TWINT)));    

        return 
    TWDR;

    }
    /* i2c_readAck */


    /*************************************************************************
     Read one byte from the I2C device, read is followed by a stop condition 
     
     Return:  byte read from I2C device
    *************************************************************************/
    unsigned char i2c_readNak(void)
    {
        
    TWCR = (1<<TWINT) | (1<<TWEN);
        while(!(
    TWCR & (1<<TWINT)));
        
        return 
    TWDR;

    }
    /* i2c_readNak */ 

    #2
    پاسخ : مشکل i2c (TWI) در Atmel Studio

    کسی یه راهنمایی میتونه کنه ؟ ممنون میشم

    دیدگاه


      #3
      پاسخ : مشکل i2c (TWI) در Atmel Studio

      نوشته اصلی توسط mzselec نمایش پست ها
      سلام به همه مهندسین
      میخواستم سنسور SHT30 رو با اتمگا 16 راه اندازی کنم ، با کدویژن به راحتی این رو کار رو انجام دادم و هیچ مشکلی نبوده ولی با پروتکل i2c اتمل استودیو به مشکل برخورد کردم.
      چه به صورت نرم افزاری و چه i2c سخت افزاری
      از کتابخانه های مختلفی در اتمل استودیو استفاده کردم ولی زمان خواندن سنسور و پروتکل i2c کلا میکرو هنگ میکنه و روی متنی که روی ال سی دی نمایش داده بوده میمونه.
      حتی یه برنامه مطمئن از ایسی ساعت DS1307 برای تست استفاده کردم که با مگا8 بود ولی اون هم همین مشکل رو داشت و روی نوشته ال سی دی هنگ میکرد.
      آیا برای استفاده از i2c اتمل استودیو کار خاصی باید انجام بدیم؟ یا اینکه فیوزبیت خاصی نیاز به تغییر داره؟
      این هم کتابخانه i2c که استفاده کردم
      کد PHP:
      /*************************************************************************
      * Title:    I2C master library using hardware TWI interface
      * Author:   Peter Fleury <pfleury@gmx.ch>  http://jump.to/fleury
      * File:     $Id: twimaster.c,v 1.4 2015/01/17 12:16:05 peter Exp $
      * Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
      * Target:   any AVR device with hardware TWI 
      * Usage:    API compatible with I2C Software Library i2cmaster.h
      **************************************************************************/
      #include <inttypes.h>
      #include <compat/twi.h>

      #include "i2cmaster.h"


      /* define CPU frequency in hz here if not defined in Makefile */
      #ifndef F_CPU
      #define F_CPU 8000000UL
      #endif

      /* I2C clock in Hz */
      #define SCL_CLOCK  100000L


      /*************************************************************************
       Initialization of the I2C bus interface. Need to be called only once
      *************************************************************************/
      void i2c_init(void)
      {
        
      /* initialize TWI clock: 100 kHz clock, TWPS = 0 => prescaler = 1 */
        
        
      TWSR 0;                         /* no prescaler */
        
      TWBR = ((F_CPU/SCL_CLOCK)-16)/2;  /* must be > 10 for stable operation */

      }/* i2c_init */


      /*************************************************************************    
        Issues a start condition and sends address and transfer direction.
        return 0 = device accessible, 1= failed to access device
      *************************************************************************/
      unsigned char i2c_start(unsigned char address)
      {
          
      uint8_t   twst;

          
      // send START condition
          
      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);

          
      // wait until transmission completed
          
      while(!(TWCR & (1<<TWINT)));

          
      // check value of TWI Status Register. Mask prescaler bits.
          
      twst TW_STATUS 0xF8;
          if ( (
      twst != TW_START) && (twst != TW_REP_START)) return 1;

          
      // send device address
          
      TWDR address;
          
      TWCR = (1<<TWINT) | (1<<TWEN);

          
      // wail until transmission completed and ACK/NACK has been received
          
      while(!(TWCR & (1<<TWINT)));

          
      // check value of TWI Status Register. Mask prescaler bits.
          
      twst TW_STATUS 0xF8;
          if ( (
      twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) return 1;

          return 
      0;

      }
      /* i2c_start */


      /*************************************************************************
       Issues a start condition and sends address and transfer direction.
       If device is busy, use ack polling to wait until device is ready
       
       Input:   address and transfer direction of I2C device
      *************************************************************************/
      void i2c_start_wait(unsigned char address)
      {
          
      uint8_t   twst;


          while ( 
      )
          {
              
      // send START condition
              
      TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
          
              
      // wait until transmission completed
              
      while(!(TWCR & (1<<TWINT)));
          
              
      // check value of TWI Status Register. Mask prescaler bits.
              
      twst TW_STATUS 0xF8;
              if ( (
      twst != TW_START) && (twst != TW_REP_START)) continue;
          
              
      // send device address
              
      TWDR address;
              
      TWCR = (1<<TWINT) | (1<<TWEN);
          
              
      // wail until transmission completed
              
      while(!(TWCR & (1<<TWINT)));
          
              
      // check value of TWI Status Register. Mask prescaler bits.
              
      twst TW_STATUS 0xF8;
              if ( (
      twst == TW_MT_SLA_NACK )||(twst ==TW_MR_DATA_NACK) ) 
              {            
                  
      /* device busy, send stop condition to terminate write operation */
                  
      TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
                  
                  
      // wait until stop condition is executed and bus released
                  
      while(TWCR & (1<<TWSTO));
                  
                  continue;
              }
              
      //if( twst != TW_MT_SLA_ACK) return 1;
              
      break;
           }

      }
      /* i2c_start_wait */


      /*************************************************************************
       Issues a repeated start condition and sends address and transfer direction 

       Input:   address and transfer direction of I2C device
       
       Return:  0 device accessible
                1 failed to access device
      *************************************************************************/
      unsigned char i2c_rep_start(unsigned char address)
      {
          return 
      i2c_startaddress );

      }
      /* i2c_rep_start */


      /*************************************************************************
       Terminates the data transfer and releases the I2C bus
      *************************************************************************/
      void i2c_stop(void)
      {
          
      /* send stop condition */
          
      TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
          
          
      // wait until stop condition is executed and bus released
          
      while(TWCR & (1<<TWSTO));

      }
      /* i2c_stop */


      /*************************************************************************
        Send one byte to I2C device
        
        Input:    byte to be transfered
        Return:   0 write successful 
                  1 write failed
      *************************************************************************/
      unsigned char i2c_writeunsigned char data )
      {    
          
      uint8_t   twst;
          
          
      // send data to the previously addressed device
          
      TWDR data;
          
      TWCR = (1<<TWINT) | (1<<TWEN);

          
      // wait until transmission completed
          
      while(!(TWCR & (1<<TWINT)));

          
      // check value of TWI Status Register. Mask prescaler bits
          
      twst TW_STATUS 0xF8;
          if( 
      twst != TW_MT_DATA_ACK) return 1;
          return 
      0;

      }
      /* i2c_write */


      /*************************************************************************
       Read one byte from the I2C device, request more data from device 
       
       Return:  byte read from I2C device
      *************************************************************************/
      unsigned char i2c_readAck(void)
      {
          
      TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
          while(!(
      TWCR & (1<<TWINT)));    

          return 
      TWDR;

      }
      /* i2c_readAck */


      /*************************************************************************
       Read one byte from the I2C device, read is followed by a stop condition 
       
       Return:  byte read from I2C device
      *************************************************************************/
      unsigned char i2c_readNak(void)
      {
          
      TWCR = (1<<TWINT) | (1<<TWEN);
          while(!(
      TWCR & (1<<TWINT)));
          
          return 
      TWDR;

      }
      /* i2c_readNak */ 
      سلام
      فکر نکنم مورد خاصی رو لازم باشه رعایت کنید! برای اطمینان این کتابخونه رو هم تست کنید. فقط توجه داشته باشید این کتابخونه برای چند پلتفرم مختلف نوشته شده و باید برای AVR کانفیگش کنید. توضیحات لازم توی همون صفحه وجود داره:

      دیدگاه


        #4
        پاسخ : مشکل i2c (TWI) در Atmel Studio

        نوشته اصلی توسط hossein.m98 نمایش پست ها
        سلام
        فکر نکنم مورد خاصی رو لازم باشه رعایت کنید! برای اطمینان این کتابخونه رو هم تست کنید. فقط توجه داشته باشید این کتابخونه برای چند پلتفرم مختلف نوشته شده و باید برای AVR کانفیگش کنید. توضیحات لازم توی همون صفحه وجود داره:
        https://github.com/Hossein-M98/DS1307
        ممنون تست میکنم ایشالا که درست میشه ، ولی خیلی از کتابخونه ها رو تست کردم و کار نکرد ، و راستی این رو یادم رفت بگم که روی پروتئوس به خوبی کار میکنه ولی در عمل نه ، پروژه رو هم روی بردبرد درست بستم و حتی با کدویژن تست کردم راحت جواب میده

        دلیل: ادغام دو پست برای جلوگیری از اسپم

        نوشته اصلی توسط mzselec نمایش پست ها
        ممنون تست میکنم ایشالا که درست میشه ، ولی خیلی از کتابخونه ها رو تست کردم و کار نکرد ، و راستی این رو یادم رفت بگم که روی پروتئوس به خوبی کار میکنه ولی در عمل نه ، پروژه رو هم روی بردبرد درست بستم و حتی با کدویژن تست کردم راحت جواب میده
        الان نگاه کردم این برای آی سی ساعت هست ولی من نیاز به کتابخانه i2c دارم
        حالا باز تست میکنم ببینم که میکرو هنگ میکنه یا نه ، بازم ممنون
        و اینکه میتونم از این کتابخونه اگه جواب داد برای پورت i2c استفاده کنم؟
        جدیدترین ویرایش توسط mzselec; ۱۲:۱۵ ۱۴۰۰/۱۱/۲۷.

        دیدگاه


          #5
          پاسخ : مشکل i2c (TWI) در Atmel Studio

          نوشته اصلی توسط mzselec نمایش پست ها
          ممنون تست میکنم ایشالا که درست میشه ، ولی خیلی از کتابخونه ها رو تست کردم و کار نکرد ، و راستی این رو یادم رفت بگم که روی پروتئوس به خوبی کار میکنه ولی در عمل نه ، پروژه رو هم روی بردبرد درست بستم و حتی با کدویژن تست کردم راحت جواب میده

          دلیل: ادغام دو پست برای جلوگیری از اسپم



          الان نگاه کردم این برای آی سی ساعت هست ولی من نیاز به کتابخانه i2c دارم
          حالا باز تست میکنم ببینم که میکرو هنگ میکنه یا نه ، بازم ممنون
          و اینکه میتونم از این کتابخونه اگه جواب داد برای پورت i2c استفاده کنم؟
          ببینید کتابخونه ۲ تا فایل مربوط به پلتفرم داره اسم DS1307_platform که اگر بازشون کنید کدهای I2C رو میبینید. از اونا میتونید الگو بگیرید برای استفاده در هر کجای دیگه.

          دیدگاه


            #6
            پاسخ : مشکل i2c (TWI) در Atmel Studio

            نوشته اصلی توسط hossein.m98 نمایش پست ها
            ببینید کتابخونه ۲ تا فایل مربوط به پلتفرم داره اسم DS1307_platform که اگر بازشون کنید کدهای I2C رو میبینید. از اونا میتونید الگو بگیرید برای استفاده در هر کجای دیگه.
            ممنون ، مشکلم حل شد ، آدرسهای sht رو دست کاری کرده بودم و یادم رفته بود درستشون کنم . ولی یه مشکل دیگه ایجاد شده الان توی دوتا برنامه ازش استفاده کردم داخل یکی به خوبی کار میکنه ولی داخل برنامه دوم که با glcd هم هست یکی از دیتاهای رطوبت رو نمیتونم دریافت کنم.
            مشکل از چی میتونه باشه؟ الان دما خوبه ولی رطوبت به خاطر نبود دیتای دوم منفی نشون مییده

            دیدگاه


              #7
              پاسخ : مشکل i2c (TWI) در Atmel Studio

              نوشته اصلی توسط mzselec نمایش پست ها
              ممنون ، مشکلم حل شد ، آدرسهای sht رو دست کاری کرده بودم و یادم رفته بود درستشون کنم . ولی یه مشکل دیگه ایجاد شده الان توی دوتا برنامه ازش استفاده کردم داخل یکی به خوبی کار میکنه ولی داخل برنامه دوم که با glcd هم هست یکی از دیتاهای رطوبت رو نمیتونم دریافت کنم.
              مشکل از چی میتونه باشه؟ الان دما خوبه ولی رطوبت به خاطر نبود دیتای دوم منفی نشون مییده
              از چه کتابخونه ای استفاده میکنید؟ ممکنه کدها مشکل داشته باشن یا این که شما یک جای کار رو دارید اشتباه میکنید و حواستون نیست.

              دیدگاه


                #8
                پاسخ : مشکل i2c (TWI) در Atmel Studio

                نوشته اصلی توسط hossein.m98 نمایش پست ها
                از چه کتابخونه ای استفاده میکنید؟ ممکنه کدها مشکل داشته باشن یا این که شما یک جای کار رو دارید اشتباه میکنید و حواستون نیست.
                از کتابخونه peter fleur استفاده میکنم

                دیدگاه


                  #9
                  پاسخ : مشکل i2c (TWI) در Atmel Studio

                  نوشته اصلی توسط hossein.m98 نمایش پست ها
                  ببینید کتابخونه ۲ تا فایل مربوط به پلتفرم داره اسم DS1307_platform که اگر بازشون کنید کدهای I2C رو میبینید. از اونا میتونید الگو بگیرید برای استفاده در هر کجای دیگه.
                  سلامی دوباره ، ممنون بابت کمکتون
                  الان لازم شد از کتابخونه DS1307 استفاده کنم ، همه مقادیر درست خوانده و نوشته میشن ولی برای تنظیم دستی مقادیر مشکل دارم.
                  وقتی با کلید روی برد ساعت رو تغییر میدم اعداد به هگزادسیمال تغییر میکنن ، مثلا بعد از عدد 9 به جای اینکه دهگان تغییر کنه عدد 9 به A تغییر میکنه!
                  برای حل این مشکل باید چیکار کنم؟

                  دیدگاه


                    #10
                    پاسخ : مشکل i2c (TWI) در Atmel Studio

                    نوشته اصلی توسط mzselec نمایش پست ها
                    سلامی دوباره ، ممنون بابت کمکتون
                    الان لازم شد از کتابخونه DS1307 استفاده کنم ، همه مقادیر درست خوانده و نوشته میشن ولی برای تنظیم دستی مقادیر مشکل دارم.
                    وقتی با کلید روی برد ساعت رو تغییر میدم اعداد به هگزادسیمال تغییر میکنن ، مثلا بعد از عدد 9 به جای اینکه دهگان تغییر کنه عدد 9 به A تغییر میکنه!
                    برای حل این مشکل باید چیکار کنم؟
                    خوب حتما برنامه تو قسمت پردازش کلید یا قسمت مربوط به نمایش مشکل داره دیگه. بدون اطلاعات بیشتر نمیشه پاسخ بهتر داد.

                    دیدگاه


                      #11
                      پاسخ : مشکل i2c (TWI) در Atmel Studio

                      نوشته اصلی توسط hossein.m98 نمایش پست ها
                      خوب حتما برنامه تو قسمت پردازش کلید یا قسمت مربوط به نمایش مشکل داره دیگه. بدون اطلاعات بیشتر نمیشه پاسخ بهتر داد.
                      ممنون ، بررسی میکنم ببینم میتونم مشکل رو پیدا کنم یا نه ، راستی مشکل اون قسمت که رطوبت رو منفی میخوند رو هم با هزار دردسر پیداش کردم .
                      چون دیتایی که میخوندم از نوع float بود باید حتما اعشار اعداد ثابت رو صفر میکردم

                      دیدگاه


                        #12
                        پاسخ : مشکل i2c (TWI) در Atmel Studio

                        نوشته اصلی توسط mzselec نمایش پست ها
                        ممنون تست میکنم ایشالا که درست میشه ، ولی خیلی از کتابخونه ها رو تست کردم و کار نکرد ، و راستی این رو یادم رفت بگم که روی پروتئوس به خوبی کار میکنه ولی در عمل نه ، پروژه رو هم روی بردبرد درست بستم و حتی با کدویژن تست کردم راحت جواب میده

                        دلیل: ادغام دو پست برای جلوگیری از اسپم



                        الان نگاه کردم این برای آی سی ساعت هست ولی من نیاز به کتابخانه i2c دارم
                        حالا باز تست میکنم ببینم که میکرو هنگ میکنه یا نه ، بازم ممنون
                        و اینکه میتونم از این کتابخونه اگه جواب داد برای پورت i2c استفاده کنم؟
                        این DataTime داخل نمونه کد همون DateTime هست؟

                        دیدگاه


                          #13
                          پاسخ : مشکل i2c (TWI) در Atmel Studio

                          نوشته اصلی توسط mzselec نمایش پست ها
                          این DataTime داخل نمونه کد همون DateTime هست؟
                          بله همونه؛ اشتباه تایپی رخ داده. ممنون که اطلاع دادید.

                          دیدگاه

                          لطفا صبر کنید...
                          X