اطلاعیه

Collapse
No announcement yet.

تغییر اسیلاتور خارجی به داخلی در اتمل استادیو

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

    تغییر اسیلاتور خارجی به داخلی در اتمل استادیو

    دوستان عزیز یک پروژه دارم مربوط به sd card هست
    این پروژه با
    اسیلاتور
    خارجی 16 مگاهرتز تنظیم شده
    من نمیخوام از
    اسیلاتور
    خارجی استفاده کنم
    میخوام از فرکانس داخلی 1 مگا هرتز استفاده کنم
    کسی میتونه راهنماییم کنه چطور کد برنامه رو تغییر بدم تا تنظیم بشه روی 1مگا هرتز داخلی ؟

    میکرو Atmga328 هست و کامپایلر atmel studio

    این لینک دانلود پروژه است

    کد زیر فکر میکنم مربوط باشه به بخش تنظیم فرکانس کاری / من فقط میخوام پروژه بدون کریستال خارجی و با فرکانس 1 مگاهرتز داخلی کار کنه



    uint8_t sd_raw_init()
    {
    /* enable inputs for reading card status */
    configure_pin_available();
    configure_pin_locked();


    /* enable outputs for MOSI, SCK, SS, input for MISO */
    configure_pin_mosi();
    configure_pin_sck();
    configure_pin_ss();
    configure_pin_miso();


    unselect_card();


    /* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
    SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
    (1 << SPE) | /* SPI Enable */
    (0 << DORD) | /* Data Order: MSB first */
    (1 << MSTR) | /* Master mode */
    (0 << CPOL) | /* Clock Polarity: SCK low when idle */
    (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
    (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
    (1 << SPR0);
    SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */


    /* initialization procedure */
    sd_raw_card_type = 0;

    if(!sd_raw_available())
    return 0;


    /* card needs 74 cycles minimum to start up */
    for(uint8_t i = 0; i < 10; ++i)
    {
    /* wait 8 clock cycles */
    sd_raw_rec_byte();
    }


    /* address card */
    select_card();


    /* reset card */
    uint8_t response;
    for(uint16_t i = 0; ; ++i)
    {
    response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
    if(response == (1 << R1_IDLE_STATE))
    break;


    if(i == 0x1ff)
    {
    unselect_card();
    return 0;
    }
    }


    #if SD_RAW_SDHC
    /* check for version of SD card specification */
    response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 3.6V */ | 0xaa /* test pattern */);
    if((response & (1 << R1_ILL_COMMAND)) == 0)
    {
    sd_raw_rec_byte();
    sd_raw_rec_byte();
    if((sd_raw_rec_byte() & 0x01) == 0)
    return 0; /* card operation voltage range doesn't match */
    if(sd_raw_rec_byte() != 0xaa)
    return 0; /* wrong test pattern */


    /* card conforms to SD 2 card specification */
    sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
    }
    else
    #endif
    {
    /* determine SD/MMC card type */
    sd_raw_send_command(CMD_APP, 0);
    response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
    if((response & (1 << R1_ILL_COMMAND)) == 0)
    {
    /* card conforms to SD 1 card specification */
    sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
    }
    else
    {
    /* MMC card */
    }
    }


    /* wait for card to get ready */
    for(uint16_t i = 0; ; ++i)
    {
    if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
    {
    uint32_t arg = 0;
    #if SD_RAW_SDHC
    if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
    arg = 0x40000000;
    #endif
    sd_raw_send_command(CMD_APP, 0);
    response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
    }
    else
    {
    response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
    }


    if((response & (1 << R1_IDLE_STATE)) == 0)
    break;


    if(i == 0x7fff)
    {
    unselect_card();
    return 0;
    }
    }


    #if SD_RAW_SDHC
    if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
    {
    if(sd_raw_send_command(CMD_READ_OCR, 0))
    {
    unselect_card();
    return 0;
    }


    if(sd_raw_rec_byte() & 0x40)
    sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);


    sd_raw_rec_byte();
    sd_raw_rec_byte();
    sd_raw_rec_byte();
    }
    #endif


    /* set block size to 512 bytes */
    if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
    {
    unselect_card();
    return 0;
    }


    /* deaddress card */
    unselect_card();


    /* switch to highest SPI frequency possible */
    SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */
    SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */


    #if !SD_RAW_SAVE_RAM
    /* the first block is likely to be accessed first, so precache it here */
    raw_block_address = (offset_t) -1;
    #if SD_RAW_WRITE_BUFFERING
    raw_block_written = 1;
    #endif
    if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
    return 0;
    #endif


    return 1;
    }




    #2
    پاسخ : تغییر اسیلاتور خارجی به داخلی در اتمل استادیو

    نوشته اصلی توسط mnopamin نمایش پست ها
    دوستان عزیز یک پروژه دارم مربوط به sd card هست
    این پروژه با
    اسیلاتور
    خارجی 16 مگاهرتز تنظیم شده
    من نمیخوام از
    اسیلاتور
    خارجی استفاده کنم
    میخوام از فرکانس داخلی 1 مگا هرتز استفاده کنم
    کسی میتونه راهنماییم کنه چطور کد برنامه رو تغییر بدم تا تنظیم بشه روی 1مگا هرتز داخلی ؟

    میکرو Atmga328 هست و کامپایلر atmel studio

    این لینک دانلود پروژه است

    کد زیر فکر میکنم مربوط باشه به بخش تنظیم فرکانس کاری / من فقط میخوام پروژه بدون کریستال خارجی و با فرکانس 1 مگاهرتز داخلی کار کنه



    uint8_t sd_raw_init()
    {
    /* enable inputs for reading card status */
    configure_pin_available();
    configure_pin_locked();


    /* enable outputs for MOSI, SCK, SS, input for MISO */
    configure_pin_mosi();
    configure_pin_sck();
    configure_pin_ss();
    configure_pin_miso();


    unselect_card();


    /* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
    SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
    (1 << SPE) | /* SPI Enable */
    (0 << DORD) | /* Data Order: MSB first */
    (1 << MSTR) | /* Master mode */
    (0 << CPOL) | /* Clock Polarity: SCK low when idle */
    (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
    (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
    (1 << SPR0);
    SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */


    /* initialization procedure */
    sd_raw_card_type = 0;

    if(!sd_raw_available())
    return 0;


    /* card needs 74 cycles minimum to start up */
    for(uint8_t i = 0; i < 10; ++i)
    {
    /* wait 8 clock cycles */
    sd_raw_rec_byte();
    }


    /* address card */
    select_card();


    /* reset card */
    uint8_t response;
    for(uint16_t i = 0; ; ++i)
    {
    response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
    if(response == (1 << R1_IDLE_STATE))
    break;


    if(i == 0x1ff)
    {
    unselect_card();
    return 0;
    }
    }


    #if SD_RAW_SDHC
    /* check for version of SD card specification */
    response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 3.6V */ | 0xaa /* test pattern */);
    if((response & (1 << R1_ILL_COMMAND)) == 0)
    {
    sd_raw_rec_byte();
    sd_raw_rec_byte();
    if((sd_raw_rec_byte() & 0x01) == 0)
    return 0; /* card operation voltage range doesn't match */
    if(sd_raw_rec_byte() != 0xaa)
    return 0; /* wrong test pattern */


    /* card conforms to SD 2 card specification */
    sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
    }
    else
    #endif
    {
    /* determine SD/MMC card type */
    sd_raw_send_command(CMD_APP, 0);
    response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
    if((response & (1 << R1_ILL_COMMAND)) == 0)
    {
    /* card conforms to SD 1 card specification */
    sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
    }
    else
    {
    /* MMC card */
    }
    }


    /* wait for card to get ready */
    for(uint16_t i = 0; ; ++i)
    {
    if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
    {
    uint32_t arg = 0;
    #if SD_RAW_SDHC
    if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
    arg = 0x40000000;
    #endif
    sd_raw_send_command(CMD_APP, 0);
    response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
    }
    else
    {
    response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
    }


    if((response & (1 << R1_IDLE_STATE)) == 0)
    break;


    if(i == 0x7fff)
    {
    unselect_card();
    return 0;
    }
    }


    #if SD_RAW_SDHC
    if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
    {
    if(sd_raw_send_command(CMD_READ_OCR, 0))
    {
    unselect_card();
    return 0;
    }


    if(sd_raw_rec_byte() & 0x40)
    sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);


    sd_raw_rec_byte();
    sd_raw_rec_byte();
    sd_raw_rec_byte();
    }
    #endif


    /* set block size to 512 bytes */
    if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
    {
    unselect_card();
    return 0;
    }


    /* deaddress card */
    unselect_card();


    /* switch to highest SPI frequency possible */
    SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */
    SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */


    #if !SD_RAW_SAVE_RAM
    /* the first block is likely to be accessed first, so precache it here */
    raw_block_address = (offset_t) -1;
    #if SD_RAW_WRITE_BUFFERING
    raw_block_written = 1;
    #endif
    if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
    return 0;
    #endif


    return 1;
    }



    سلام
    تعیین منبع و سرعت کلاک میکروکنترلرهای avr از طریق فیوزبیت و هنگام پروگرام کردن انجام میشه نه خطوط برنامه. اگر جایی از خطوط برنامه هم دیدید که کلاک تعیین شده، صرفا برای برخی محاسبات خاص مثل محاسبه تاخیر در توابع delay به کار میره و تغییری در کلاک ایجاد نمیکنه.
    ضمنا توجه داشته باشید که نرخ تبادل داده در واحد spi (منظورم سرعت کلاک اونه)، نهایتا نصف سرعت کلاک اصلی میتونه باشه و با کم کردن اون از 16 به 1 مگاهرتز، سرعت تبادل داده با کارت sd به شدت کم میشه!

    دیدگاه


      #3
      پاسخ : تغییر اسیلاتور خارجی به داخلی در اتمل استادیو

      ممنون از پاسخ تون

      پس یعنی اگر ی برنامه رو با کریستال خارجی 16 مگاهرتز اجرا کنیم و فیوز بیت ها رو ست کنیم
      و همون برنامه رو با اسیلاتور داخلی مثلا 1 مگ اجرا کنیم . هیچ تفاونی نداره ؟
      و هردو باید به درستی اجرا بشن ؟

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

      ممنون از پاسخ تون

      پس یعنی اگر ی برنامه رو با کریستال خارجی 16 مگاهرتز اجرا کنیم و فیوز بیت ها رو ست کنیم
      و همون برنامه رو با اسیلاتور داخلی مثلا 1 مگ اجرا کنیم . هیچ تفاونی نداره ؟
      و هردو باید به درستی اجرا بشن ؟


      نوشته اصلی توسط hossein.m98 نمایش پست ها
      سلام
      تعیین منبع و سرعت کلاک میکروکنترلرهای avr از طریق فیوزبیت و هنگام پروگرام کردن انجام میشه نه خطوط برنامه. اگر جایی از خطوط برنامه هم دیدید که کلاک تعیین شده، صرفا برای برخی محاسبات خاص مثل محاسبه تاخیر در توابع delay به کار میره و تغییری در کلاک ایجاد نمیکنه.
      ضمنا توجه داشته باشید که نرخ تبادل داده در واحد spi (منظورم سرعت کلاک اونه)، نهایتا نصف سرعت کلاک اصلی میتونه باشه و با کم کردن اون از 16 به 1 مگاهرتز، سرعت تبادل داده با کارت sd به شدت کم میشه!

      دیدگاه


        #4
        پاسخ : تغییر اسیلاتور خارجی به داخلی در اتمل استادیو

        نوشته اصلی توسط mnopamin نمایش پست ها
        ممنون از پاسخ تون
        پس یعنی اگر ی برنامه رو با کریستال خارجی 16 مگاهرتز اجرا کنیم و فیوز بیت ها رو ست کنیم
        و همون برنامه رو با اسیلاتور داخلی مثلا 1 مگ اجرا کنیم . هیچ تفاونی نداره ؟
        و هردو باید به درستی اجرا بشن ؟
        ببینید این بستگی به نوع برنامه هم داره. مثلا اگر برنامه ای برای کلاک 1 مگاهرتز نوشته و داخلش از توابع تاخیر یا واحدهایی مثل تایمر و spi استفاده بشه، اگر روی میکروکنترلری که کلاکش روی مقدار دیگه ای تنظیم شده باشه بخواد اجرا بشه، مسلما رفتارش با خواست ما تفاوت خواهد داشت. این به خاطر اینه که در برنامه مقدار 1 مگاهرتز برای کلاک در نظر گرفته شده و محاسبات بر اساس این مقدار انجام شده، ولی در عمل کلاک چیز دیگه ای هستش.
        اگر شما تصمیم دارید فرکانس کلاک رو تغییر بدید، باید هم داخل برنامه این کار رو انجام بدید، هم موقع پروگرام کردن فیوز بیت ها رو تنظیم کنید. در اتمل استدیو کلاک برای توابع delay به این صورت مشخص میشه:

        #define F_CPU 1000000UL

        شما باید بگردید این خط رو پیدا کنید و مقدار مورد نظرتون رو به عنوان کلاک تنظیم کنید. ضمنا توجه داشته باشید که برای کارکرد درست همه واحدها باید تقسیم کننده های فرکانسی هر واحد هم نسبت به فرکانس جدید درست تنظیم بشه. مثلا اگر تایمر استفاده کردید باید تقسیم کننده های اون رو هم درست تنظیم کنید تا برنامه عملکرد درستی داشته باشه. از اونجایی که برنامه برای راه اندازی sd card هستش و از واحد spi استفاده شده، باید تقسیم کننده کلاک spi رو هم پیدا، و بر اساس فرکانس جدید تنظیم کنید.

        دیدگاه

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