نصب و راه‌اندازی بوت لودر آردوینو روی میکروکنترلرهای AVR

فهرست مطالب

مقدمه

گاهی اوقات پیش آمده که:

  • میکروکنترلر آردوینوی شما سوخته و نیاز به تعویض دارد،
  • و یا میکرکنترلر جدیدی تهیه کرده‌اید و قصد دارید به ساده‌ترین روش و با کوتاه‌ترین زمان آن را برنامه‌نویسی کنید،

قبل از همه این کارها شما نیاز به نصب Bootloader برای میکروکنترلر خود دارید. وقتی یک میکروکنترلر خام AVR تهیه می‌کنید، نمی‌توانید آن را مستقیما از طریق اتصال به کامپیوتر و  مبدل USB به TTL پروگرام کنید. ابتدا باید از طریق پایه های  ISP، بوت لودر را بر روی میکروکنترلر نصب کرده و سپس از طریق مبدل USB به TTL برنامه دلخواهتان را بر روی آن Upload  کنید.

بدین منظور می‌توانیم از پایه های ISP(In-Circuit Serial Programmer) آردوینو برای نصب Bootloader و همچنین پروگرام کردن میکروهای گوناگون AVR استفاده کنیم.

در  این آموزش توسط نرم‌افزار Arduino IDE  و به واسطه‌ی پایه های برد Arduino UNO، بوت لودر را بر روی میکروکنترلرهای AVR  نصب کرده و سپس آن‌ها را پروگرام می‌کنیم. در واقع از برد Arduino UNO به عنوان پروگرامر ISP بهره می‌بریم.

نکته

اکثر بردهای آردوینو از میکروکنترلرهای AVR بهره می برند.  بنابراین می‌توانیم این عملیات را بین دو برد آردوینو نیز انجام دهیم. یعنی یکی را به عنوان پروگرامر ISP و دیگری را به عنوان هدف پروگرام قرار دهیم. برای اطلاعات بیشتر در این زمینه این لینک را مطالعه کنید.

آنچه در این آموزش یاد می‌گیرید:

ما در این آموزش قصد داریم توسط برد آردوینو uno و با استفاده از نرم‌افزار Arduino IDE، یک میکروکنترلر خام AVR را برنامه نویسی و پروگرام کنیم. جهت این کار ابتدا برنامه Bootloader را توسط برد آردوینو بر روی میکروکنترلر نصب می‌کنیم. سپس میکرو را پروگرام کرده و برنامه‌ای ساده بر روی آن می‌ریزیم. یعنی تمام مراحل پروگرام کردن یک میکروی خام AVR را از طریق برد آردوینو انجام می‌دهیم.

شما بعد از اتمام این آموزش قادر خواهید بود از طریق برد آردوینوی UNO، بر روی میکروکنترلرهای AVR خود Bootloader را نصب کرده و آن‌ها را پروگرام کنید.

معرفی پایه های (Pinout) برد آردوینو به عنوان پروگرامر ISP

یکی از ساده‌ترین راه‌ها برای پروگرام کردن میکروهای AVR، به کار‌گیری پایه های ISP بردهای Arduino می‌باشد. پایه های ISP آردوینو این امکان را برایمان مهیا می‌کند تا از آن به عنوان پروگرامر میکروکنترلرهای AVR استفاده کنیم. این پایه ها به دو صورت قابل دسترسی‌اند:

  • پایه‌های خروجی 11، 12 و 13 برای آردوینو UNO (این اعداد برای آردوینوهای دیگر متفاومت است)
  • کانکتور ISP (دارای 6 پین‌هدر) که به صورت مستقیم قابل استفاده‌ااست.

این 6 پایه ISP به شرح زیر می‌باشند:

  • VCC: تغذیه 5 ولت
  • GND: زمین الکتریکی
  • MOSI: پایه دیتای خروجی Master به ورودی Slave
  • MISO: پایه دیتای خروجی Slave به ورودی Master
  • SCK: پایه کلاک
  • RESET: پایه ریست
نکته

معمولا  اگر برد آردوینو به عنوان پروگرامر استفاده شود، 3 پایه 11، 12 و 13 به کاربرده می‌شود.
ولی اگر به عنوان هدف پروگرام باشد، از کانکتور ISP جهت پروگرام می‌توان بهره برد.

بوت لودر (Bootloader) چیست؟

همانطور که گفته شد، میکروکنترلرهای خام قابلیت برنامه نویسی و پروگرام توسط مبدل‌های USB به TTL را ندارند. به همین منظور قبل از استفاده از آن‌ها بایستی برنا‌مه‌ای به نام Bootloader بر روی آن‌ها ذخیره شود تا قابلیت پروگرام از طریق مبدل‌های USB TL را پیدا کنند. پس از نصب بوت لودر بر روی میکروکنترلر، می‌توانید از طریق نرم‌افزار Arduino IDE برنامه موردنظر خود را  بر روی آن آپلود نمائید.  

حجم این کد حدود 512 بایت بوده و در انتهای آدرس حافظه Flash ذخیره ‌می‌شود. با هر بار ریست شدن میکروکنترلر، این دستور دوباره اجرا می‌شود. برای مثال حافظه Flash میکروکنترلر Atmega8 دارای حجم 8KB است. این حافظه به دو بخش تقسیم می‌شود. انتهای این حافظه متعلق به برنامه Bootloader و مابقی آن برای حافظه برنامه نویسی به کار می‌رود. تصویر زیر توصیفی از حافظه های Flash، SRAM و EEPROM میکروکنترلر Atmega8 نشان می‌دهد

انواع میکروکنترلرهای AVR

میکروکنترلرهای AVR در ابعاد و تعداد پایه های متفاوت عرضه می‌شوند. به صورت کلی می‌توان آن‌ها را به 5 گروه زیر تقسیم کرد:

  • MightyCore
  • MegaCore
  • MiniCore
  • MicroCore
  • MegaCoreX

 

برای به دست آورن اطلاعات بیشتر در مورد هر کدام یک از انواع میکروهای بالا و مشاهده پین‌اوت آنها، اینجا کلیک کنید.

Atmega8 از انواع مدل MiniCore می‌باشد. این میکروکنترلر ها دارای 28 پایه هستند. پین‌اوت میکروهای MiniCore به صورت زیر می‌باشند:

برای نصب بوت لودر و پروگرام کردن یک میکروکنترلر AVR نیاز به بعضی از اطلاعات پین‌اوت آن میکروکنترلر داریم :

  • این پایه ها جهت نصب بوت لودر بر روی میکرو استفاده می‌شوند.
  • 2: پایه های تغذیه میکرو‌کنترلر (صفر و 5 ولت)
  • 3: این دو پایه برای اتصال به کریستال خارجی برای تنظیم فرکانس کاری میکرو کاربرد دارد.
  • 4: پایه‌های RX و TX جهت پروگرام کردن میکرو از طریق مبدل USB به  TTL

دقت کنید که برای هر میکروکنترلر AVR ، همین پایه ها مورد استفاده قرار می‌گیرند. فقط امکان دارد که شماره پایه های آن در میکروهای دیگر متفاوت باشد.

لوازمی که به آن احتیاج دارید

تمام مراحل آموزش را بر روی میکروکنترلر Atmage 8 از خانواده میکروهای AVR پیاده‌سازی می‌کنیم. برای پروگرام صحیح میکروکنترلر، قطعات جانبی دیگری نیز به کار برده می‌شوند. وجود این قطعات جانبی برای عملکرد صحیح این پروسه موردنیاز می‌باشد. تمام موارد مورد نیاز در زیر آورده شده‌است:

قطعات مورد نیاز

آردوینو UNO R3 × 1
میکروکنترلر Atmega 8 × 1
برد بورد 400 حفره ای × 1
سیم جامپر نری به نری × 1
کریستال 16 مگاهرتز × 1
خازن 22 pF × 2
خازن الکترولیت 10 uF × 1
مقاومت 10K × 1
تک سوئیچ (میکرو سوئیچ) 6x6x4.3 × 1
5mm Red Led × 1

نرم افزارهای مورد نیاز

آردوینو IDE

نصب بوت لودر آردوینو بر روی میکروکنترلر AVR

گام‌ اول: آردوینو به عنوان پروگرامر ISP

می‌خواهیم از آردوینو UNO به عنوان پروگرامر استفاده کنیم. بدین منظور ابتدا از منوی Tools نوع برد را Arduino UNO وارد کرده و پورت آن را  نیز انتخاب می‌کنیم.


از همین منو و از بخش Programmer گزینه Arduino as ISP را انتخاب می‌کنیم.


حال از مسیر File -> Examples گزینه ArduinoISP را انتخاب و بر روی برد آردوینو آپلود می‌کنیم.

برنامه زیر را بر روی برد آردوینوی خود آپلود کنید:

/*
  Made on 18 may 2021
  
Home
based on Arduino Library */ // ArduinoISP // Copyright (c) 2008-2011 Randall Bohn // If you require a license, see // http://www.opensource.org/licenses/bsd-license.php // // This sketch turns the Arduino into a AVRISP using the following Arduino pins: // // Pin 10 is used to reset the target microcontroller. // // By default, the hardware SPI pins MISO, MOSI and SCK are used to communicate // with the target. On all Arduinos, these pins can be found // on the ICSP/SPI header: // // MISO °. . 5V (!) Avoid this pin on Due, Zero... // SCK . . MOSI // . . GND // // On some Arduinos (Uno,...), pins MOSI, MISO and SCK are the same pins as // digital pin 11, 12 and 13, respectively. That is why many tutorials instruct // you to hook up the target to these pins. If you find this wiring more // practical, have a define USE_OLD_STYLE_WIRING. This will work even when not // using an Uno. (On an Uno this is not needed). // // Alternatively you can use any other digital pin by configuring // software ('BitBanged') SPI and having appropriate defines for PIN_MOSI, // PIN_MISO and PIN_SCK. // // IMPORTANT: When using an Arduino that is not 5V tolerant (Due, Zero, ...) as // the programmer, make sure to not expose any of the programmer's pins to 5V. // A simple way to accomplish this is to power the complete system (programmer // and target) at 3V3. // // Put an LED (with resistor) on the following pins: // 9: Heartbeat - shows the programmer is running // 8: Error - Lights up if something goes wrong (use red if that makes sense) // 7: Programming - In communication with the slave // #include "Arduino.h" #undef SERIAL #define PROG_FLICKER true // Configure SPI clock (in Hz). // E.g. for an ATtiny @ 128 kHz: the datasheet states that both the high and low // SPI clock pulse must be > 2 CPU cycles, so take 3 cycles i.e. divide target // f_cpu by 6: // #define SPI_CLOCK (128000/6) // // A clock slow enough for an ATtiny85 @ 1 MHz, is a reasonable default: #define SPI_CLOCK (1000000/6) // Select hardware or software SPI, depending on SPI clock. // Currently only for AVR, for other architectures (Due, Zero,...), hardware SPI // is probably too fast anyway. #if defined(ARDUINO_ARCH_AVR) #if SPI_CLOCK > (F_CPU / 128) #define USE_HARDWARE_SPI #endif #endif // Configure which pins to use: // The standard pin configuration. #ifndef ARDUINO_HOODLOADER2 #define RESET 10 // Use pin 10 to reset the target rather than SS #define LED_HB 9 #define LED_ERR 8 #define LED_PMODE 7 // Uncomment following line to use the old Uno style wiring // (using pin 11, 12 and 13 instead of the SPI header) on Leonardo, Due... // #define USE_OLD_STYLE_WIRING #ifdef USE_OLD_STYLE_WIRING #define PIN_MOSI 11 #define PIN_MISO 12 #define PIN_SCK 13 #endif // HOODLOADER2 means running sketches on the ATmega16U2 serial converter chips // on Uno or Mega boards. We must use pins that are broken out: #else #define RESET 4 #define LED_HB 7 #define LED_ERR 6 #define LED_PMODE 5 #endif // By default, use hardware SPI pins: #ifndef PIN_MOSI #define PIN_MOSI MOSI #endif #ifndef PIN_MISO #define PIN_MISO MISO #endif #ifndef PIN_SCK #define PIN_SCK SCK #endif // Force bitbanged SPI if not using the hardware SPI pins: #if (PIN_MISO != MISO) || (PIN_MOSI != MOSI) || (PIN_SCK != SCK) #undef USE_HARDWARE_SPI #endif // Configure the serial port to use. // // Prefer the USB virtual serial port (aka. native USB port), if the Arduino has one: // - it does not autoreset (except for the magic baud rate of 1200). // - it is more reliable because of USB handshaking. // // Leonardo and similar have an USB virtual serial port: 'Serial'. // Due and Zero have an USB virtual serial port: 'SerialUSB'. // // On the Due and Zero, 'Serial' can be used too, provided you disable autoreset. // To use 'Serial': #define SERIAL Serial #ifdef SERIAL_PORT_USBVIRTUAL #define SERIAL SERIAL_PORT_USBVIRTUAL #else #define SERIAL Serial #endif // Configure the baud rate: #define BAUDRATE 19200 // #define BAUDRATE 115200 // #define BAUDRATE 1000000 #define HWVER 2 #define SWMAJ 1 #define SWMIN 18 // STK Definitions #define STK_OK 0x10 #define STK_FAILED 0x11 #define STK_UNKNOWN 0x12 #define STK_INSYNC 0x14 #define STK_NOSYNC 0x15 #define CRC_EOP 0x20 //ok it is a space... void pulse(int pin, int times); #ifdef USE_HARDWARE_SPI #include "SPI.h" #else #define SPI_MODE0 0x00 class SPISettings { public: // clock is in Hz SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) : clock(clock) { (void) bitOrder; (void) dataMode; }; private: uint32_t clock; friend class BitBangedSPI; }; class BitBangedSPI { public: void begin() { digitalWrite(PIN_SCK, LOW); digitalWrite(PIN_MOSI, LOW); pinMode(PIN_SCK, OUTPUT); pinMode(PIN_MOSI, OUTPUT); pinMode(PIN_MISO, INPUT); } void beginTransaction(SPISettings settings) { pulseWidth = (500000 + settings.clock - 1) / settings.clock; if (pulseWidth == 0) pulseWidth = 1; } void end() {} uint8_t transfer (uint8_t b) { for (unsigned int i = 0; i < 8; ++i) { digitalWrite(PIN_MOSI, (b & 0x80) ? HIGH : LOW); digitalWrite(PIN_SCK, HIGH); delayMicroseconds(pulseWidth); b = (b << 1) | digitalRead(PIN_MISO); digitalWrite(PIN_SCK, LOW); // slow pulse delayMicroseconds(pulseWidth); } return b; } private: unsigned long pulseWidth; // in microseconds }; static BitBangedSPI SPI; #endif void setup() { SERIAL.begin(BAUDRATE); pinMode(LED_PMODE, OUTPUT); pulse(LED_PMODE, 2); pinMode(LED_ERR, OUTPUT); pulse(LED_ERR, 2); pinMode(LED_HB, OUTPUT); pulse(LED_HB, 2); } int error = 0; int pmode = 0; // address for reading and writing, set by 'U' command unsigned int here; uint8_t buff[256]; // global block storage #define beget16(addr) (*addr * 256 + *(addr+1) ) typedef struct param { uint8_t devicecode; uint8_t revision; uint8_t progtype; uint8_t parmode; uint8_t polling; uint8_t selftimed; uint8_t lockbytes; uint8_t fusebytes; uint8_t flashpoll; uint16_t eeprompoll; uint16_t pagesize; uint16_t eepromsize; uint32_t flashsize; } parameter; parameter param; // this provides a heartbeat on pin 9, so you can tell the software is running. uint8_t hbval = 128; int8_t hbdelta = 8; void heartbeat() { static unsigned long last_time = 0; unsigned long now = millis(); if ((now - last_time) < 40) return; last_time = now; if (hbval > 192) hbdelta = -hbdelta; if (hbval < 32) hbdelta = -hbdelta; hbval += hbdelta; analogWrite(LED_HB, hbval); } static bool rst_active_high; void reset_target(bool reset) { digitalWrite(RESET, ((reset && rst_active_high) || (!reset && !rst_active_high)) ? HIGH : LOW); } void loop(void) { // is pmode active? if (pmode) { digitalWrite(LED_PMODE, HIGH); } else { digitalWrite(LED_PMODE, LOW); } // is there an error? if (error) { digitalWrite(LED_ERR, HIGH); } else { digitalWrite(LED_ERR, LOW); } // light the heartbeat LED heartbeat(); if (SERIAL.available()) { avrisp(); } } uint8_t getch() { while (!SERIAL.available()); return SERIAL.read(); } void fill(int n) { for (int x = 0; x < n; x++) { buff[x] = getch(); } } #define PTIME 30 void pulse(int pin, int times) { do { digitalWrite(pin, HIGH); delay(PTIME); digitalWrite(pin, LOW); delay(PTIME); } while (times--); } void prog_lamp(int state) { if (PROG_FLICKER) { digitalWrite(LED_PMODE, state); } } uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { SPI.transfer(a); SPI.transfer(b); SPI.transfer(c); return SPI.transfer(d); } void empty_reply() { if (CRC_EOP == getch()) { SERIAL.print((char)STK_INSYNC); SERIAL.print((char)STK_OK); } else { error++; SERIAL.print((char)STK_NOSYNC); } } void breply(uint8_t b) { if (CRC_EOP == getch()) { SERIAL.print((char)STK_INSYNC); SERIAL.print((char)b); SERIAL.print((char)STK_OK); } else { error++; SERIAL.print((char)STK_NOSYNC); } } void get_version(uint8_t c) { switch (c) { case 0x80: breply(HWVER); break; case 0x81: breply(SWMAJ); break; case 0x82: breply(SWMIN); break; case 0x93: breply('S'); // serial programmer break; default: breply(0); } } void set_parameters() { // call this after reading parameter packet into buff[] param.devicecode = buff[0]; param.revision = buff[1]; param.progtype = buff[2]; param.parmode = buff[3]; param.polling = buff[4]; param.selftimed = buff[5]; param.lockbytes = buff[6]; param.fusebytes = buff[7]; param.flashpoll = buff[8]; // ignore buff[9] (= buff[8]) // following are 16 bits (big endian) param.eeprompoll = beget16(&buff[10]); param.pagesize = beget16(&buff[12]); param.eepromsize = beget16(&buff[14]); // 32 bits flashsize (big endian) param.flashsize = buff[16] * 0x01000000 + buff[17] * 0x00010000 + buff[18] * 0x00000100 + buff[19]; // AVR devices have active low reset, AT89Sx are active high rst_active_high = (param.devicecode >= 0xe0); } void start_pmode() { // Reset target before driving PIN_SCK or PIN_MOSI // SPI.begin() will configure SS as output, so SPI master mode is selected. // We have defined RESET as pin 10, which for many Arduinos is not the SS pin. // So we have to configure RESET as output here, // (reset_target() first sets the correct level) reset_target(true); pinMode(RESET, OUTPUT); SPI.begin(); SPI.beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0)); // See AVR datasheets, chapter "SERIAL_PRG Programming Algorithm": // Pulse RESET after PIN_SCK is low: digitalWrite(PIN_SCK, LOW); delay(20); // discharge PIN_SCK, value arbitrarily chosen reset_target(false); // Pulse must be minimum 2 target CPU clock cycles so 100 usec is ok for CPU // speeds above 20 KHz delayMicroseconds(100); reset_target(true); // Send the enable programming command: delay(50); // datasheet: must be > 20 msec spi_transaction(0xAC, 0x53, 0x00, 0x00); pmode = 1; } void end_pmode() { SPI.end(); // We're about to take the target out of reset so configure SPI pins as input pinMode(PIN_MOSI, INPUT); pinMode(PIN_SCK, INPUT); reset_target(false); pinMode(RESET, INPUT); pmode = 0; } void universal() { uint8_t ch; fill(4); ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]); breply(ch); } void flash(uint8_t hilo, unsigned int addr, uint8_t data) { spi_transaction(0x40 + 8 * hilo, addr >> 8 & 0xFF, addr & 0xFF, data); } void commit(unsigned int addr) { if (PROG_FLICKER) { prog_lamp(LOW); } spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0); if (PROG_FLICKER) { delay(PTIME); prog_lamp(HIGH); } } unsigned int current_page() { if (param.pagesize == 32) { return here & 0xFFFFFFF0; } if (param.pagesize == 64) { return here & 0xFFFFFFE0; } if (param.pagesize == 128) { return here & 0xFFFFFFC0; } if (param.pagesize == 256) { return here & 0xFFFFFF80; } return here; } void write_flash(int length) { fill(length); if (CRC_EOP == getch()) { SERIAL.print((char) STK_INSYNC); SERIAL.print((char) write_flash_pages(length)); } else { error++; SERIAL.print((char) STK_NOSYNC); } } uint8_t write_flash_pages(int length) { int x = 0; unsigned int page = current_page(); while (x < length) { if (page != current_page()) { commit(page); page = current_page(); } flash(LOW, here, buff[x++]); flash(HIGH, here, buff[x++]); here++; } commit(page); return STK_OK; } #define EECHUNK (32) uint8_t write_eeprom(unsigned int length) { // here is a word address, get the byte address unsigned int start = here * 2; unsigned int remaining = length; if (length > param.eepromsize) { error++; return STK_FAILED; } while (remaining > EECHUNK) { write_eeprom_chunk(start, EECHUNK); start += EECHUNK; remaining -= EECHUNK; } write_eeprom_chunk(start, remaining); return STK_OK; } // write (length) bytes, (start) is a byte address uint8_t write_eeprom_chunk(unsigned int start, unsigned int length) { // this writes byte-by-byte, page writing may be faster (4 bytes at a time) fill(length); prog_lamp(LOW); for (unsigned int x = 0; x < length; x++) { unsigned int addr = start + x; spi_transaction(0xC0, (addr >> 8) & 0xFF, addr & 0xFF, buff[x]); delay(45); } prog_lamp(HIGH); return STK_OK; } void program_page() { char result = (char) STK_FAILED; unsigned int length = 256 * getch(); length += getch(); char memtype = getch(); // flash memory @here, (length) bytes if (memtype == 'F') { write_flash(length); return; } if (memtype == 'E') { result = (char)write_eeprom(length); if (CRC_EOP == getch()) { SERIAL.print((char) STK_INSYNC); SERIAL.print(result); } else { error++; SERIAL.print((char) STK_NOSYNC); } return; } SERIAL.print((char)STK_FAILED); return; } uint8_t flash_read(uint8_t hilo, unsigned int addr) { return spi_transaction(0x20 + hilo * 8, (addr >> 8) & 0xFF, addr & 0xFF, 0); } char flash_read_page(int length) { for (int x = 0; x < length; x += 2) { uint8_t low = flash_read(LOW, here); SERIAL.print((char) low); uint8_t high = flash_read(HIGH, here); SERIAL.print((char) high); here++; } return STK_OK; } char eeprom_read_page(int length) { // here again we have a word address int start = here * 2; for (int x = 0; x < length; x++) { int addr = start + x; uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF); SERIAL.print((char) ee); } return STK_OK; } void read_page() { char result = (char)STK_FAILED; int length = 256 * getch(); length += getch(); char memtype = getch(); if (CRC_EOP != getch()) { error++; SERIAL.print((char) STK_NOSYNC); return; } SERIAL.print((char) STK_INSYNC); if (memtype == 'F') result = flash_read_page(length); if (memtype == 'E') result = eeprom_read_page(length); SERIAL.print(result); } void read_signature() { if (CRC_EOP != getch()) { error++; SERIAL.print((char) STK_NOSYNC); return; } SERIAL.print((char) STK_INSYNC); uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00); SERIAL.print((char) high); uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00); SERIAL.print((char) middle); uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00); SERIAL.print((char) low); SERIAL.print((char) STK_OK); } ////////////////////////////////////////// ////////////////////////////////////////// //////////////////////////////////// //////////////////////////////////// void avrisp() { uint8_t ch = getch(); switch (ch) { case '0': // signon error = 0; empty_reply(); break; case '1': if (getch() == CRC_EOP) { SERIAL.print((char) STK_INSYNC); SERIAL.print("AVR ISP"); SERIAL.print((char) STK_OK); } else { error++; SERIAL.print((char) STK_NOSYNC); } break; case 'A': get_version(getch()); break; case 'B': fill(20); set_parameters(); empty_reply(); break; case 'E': // extended parameters - ignore for now fill(5); empty_reply(); break; case 'P': if (!pmode) start_pmode(); empty_reply(); break; case 'U': // set address (word) here = getch(); here += 256 * getch(); empty_reply(); break; case 0x60: //STK_PROG_FLASH getch(); // low addr getch(); // high addr empty_reply(); break; case 0x61: //STK_PROG_DATA getch(); // data empty_reply(); break; case 0x64: //STK_PROG_PAGE program_page(); break; case 0x74: //STK_READ_PAGE 't' read_page(); break; case 'V': //0x56 universal(); break; case 'Q': //0x51 error = 0; end_pmode(); empty_reply(); break; case 0x75: //STK_READ_SIGN 'u' read_signature(); break; // expecting a command, not CRC_EOP // this is how we can get back in sync case CRC_EOP: error++; SERIAL.print((char) STK_NOSYNC); break; // anything else we will return STK_UNKNOWN default: error++; if (CRC_EOP == getch()) SERIAL.print((char)STK_UNKNOWN); else SERIAL.print((char)STK_NOSYNC); } }

گام دوم: مدار میکروکنترلر

در این مرحله میکروکنترلر را به همراه قطعات موردنیاز بر روی برد بورد وصل کرده و آن را به آردوینو متصل میکنیم:

  • پایه ریست با مقاومت 10K اهم Pull-Up شده است.
  • یک خازن 10 UF در دو سمت تغذیه برای جلوگیری از نویزپذیری و همچنین تثبیت ولتاژ به کار‌ می‌رود.

2 پایه کریستال 16MHz نیز با دو خازن 22 pF به زمین متصل شده‌است.

نکته

مقدار خازن های کریستال می‌تواند بین 18 تا 22 pF باشد.

گام سوم: اضافه کردن میکروکنترلر هدف

حال مدار آماده شده و جهت نصب بوت لودر بایستی میکروکنترلر هدف را به نرم‌افزار Arduino IDE اضافه کنیم. بدین منظور مراحل زیر را طی می‌کنیم:

 

  • مرحله 1: برای شروع ابتدا از طریق این لینک Github ، دسته‌ای را که میکروکنترلر شما در آن قرار دارد را انتخاب کنید. برای مثال ما Atmega 8 که در دسته‎ی MiniCore است را انتخاب می‌کنیم.
  • مرحله 2: در صفحه باز شده به قسمت How to install رفته و لینک زیر را کپی کنید:
  • مرحله 3: نرم‌افزار Arduino IDE را باز کرده و از منوی File گزینه‌ی Preferences را انتخاب می‌کنیم. در صفحه باز شده بر روی آیکون بخش Additional Boards Manager URLs کلیلک کرده و مانند تصویر زیر لینک کپی شده را Paste نمائید:
  • مرحله 4: از مسیر Tools->Board آیکون Board Manager را باز کنید.
  • مرحله 5: اندکی صبر کنید تا دانلود کامل شود. سپس عبارت Minicore را سرچ کرده و آنرا نصب نمائید.
نکته

برای هر میکروکنترلر AVR می‌توانید مانند بالا مراحل را تکرار کنید.

گام چهارم: نصب بوت لودر آردوینو بر روی میکروکنترلر AVR

پس از اینکه مدار را آماده کردید، بایستی دوباره وارد محیط نرم‌افزار Arduino IDE شوید و ابتدا از مسیر Tools->Board آیکون MiniCore را باز کرده و میکروکنترلر هدف که در این آموزش Atmega 8 است را انتخاب کنید.

در آخر نیز از منوی Tools بر روی آیکون Burn Bootloader کلیک کنید. صبر کنید تا عمل نصب بوت لودر کامل انجام شود. با انجام صحیح این فرآیند، عبارت Done Burning Bootloader ظاهر می‌گردد.

نکته

در بعضی از کاربردها برای پروگرام کردن میکروکنترلر به کل فضای حافظه نیاز داریم. به همین جهت پس از نصب بوت‌لودر، برنامه موردنظر را  نوشته و به جای Upload، به منوی Sketch رفته و گزینه Upload Using Programmer را بزنید.
با این کار بوت لودر شما حذف شده و برنامه‌ای که آپلود کرده‌اید، به میزان خود آن برنامه،  فضای حافظه را اشغال می‌کند.

پروگرام کردن میکروکنترلر

بوت لودر به درستی بر روی میکرو نصب شد. هم‌اکنون میکروکنترلر آماده برنامه‌نویسی و پروگرام از طریق آردوینو و یا مبدل USB به TTL می‌باشد. می‌خواهیم یک برنامه ساده بر روی میکروکنترلر آپلود کنیم و عملکرد صحیح آن را بسنجیم.

برای این کار بایستی از آردوینو به عنوان مبدل USB به TTL استفاده کنیم و از طریق 2 پایه RX و TX، میکروکنترلر را پروگرام کرده و برنامه دلخواه خود را بر روی آن بریزیم.

مرحله اول: سیم بندی

همانطور که گفته شد، از دو پایه‌ی RX و TX برای تبادل اطلاعات بین میکروکنترلر و نرم‌افزار استفاده می‌شود. دقت شود که پایه RX آردوینو را RX میکروکنترلر Atmega 8 و  پایه TX آردوینو را TX آن متصل می‌کنیم. در اصل میخواهیم از مبدل USB به TTL آردوینو UNO، میکروکنترلر را پروگرام کنیم. به همین منظور بایستی میکروکنترلر خود آردوینو را از مدار خارج کنیم. برای این کار پایه RESET آردوینو را به زمین وصل می‌کنیم.

یک عدد LED نیز به پایه شماره 8 متصل کرده تا بتوانیم با اجرای یک برنامه ساده، صحت عملکرد پروگرام را بسنجیم.

مرحله دوم: پروگرام کردن برنامه

پس از اینکه مدار آن را متصل نمودید، آردوینو را دوباره به کامپیوتر متصل کرده و تنظیمات بخش Tools را بررسی نمائید:

  • از منوی Tools و بخش Board، میکروکنترلر Atmega 8 را انتخاب کنید.
  • از همین منو و بخش Port، همان پورت Arduino Uno  را قرار دهید. 


برای اینکه بتوانیم از پروگرام صحیح میکرو مطمئن شویم، یک برنامه ساده مانند Blink  را بر روی پایه شماره 8 میکروکنترلر Atmega 8 ذخیره کرده و خروجی آن را مشاهده می‌کنیم.

نکته

از طرفی برای اینکه فرآیند Uploading به درستی محقق شود، یک سوئیچ به پایه RESET میکروکنترلر وصل کرده و سر دیگر سوئیچ را به زمین وصل می‌کنیم. زمانی که دکمه Upload را برای نصب برنامه بر روی میکروکنترلر می‌زنیم، بایستی همزمان دکمه ریست را نیز نگه داریم. در این وضعیت نرم‌افزار شروع به Compile برنامه می‌کند. وقتی از Compile به وضعیت Upload  تغییر وضعیت داد، ما نیز باید بلافاصله دست خود را از روی دکمه برداریم. بدین صورت عملیات Upload کامل انجام می‌شودو عبارت Done Uploading ظاهر می‌گردد.

برنامه زیر را بر روی میکروکنترلر Upload نمائید:

/*
  Made on 18 may 2021
  
Home
based on Arduino Library */ // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin LED_BUILTIN as an output. pinMode(8, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(8, HIGH); // turn the LED on (HIGH is the voltage level) delay(100); // wait for a second digitalWrite(8, LOW); // turn the LED off by making the voltage LOW delay(100); // wait for a second }

اگر تمام مراحل بالا را به درستی انجام داده باشید، LED شما شروع به چشمک زدن می‌کند. می‌توانید زمان Delay را تغییر داده و دوباره آپلود نمائید تا از عملکرد صحیح آن مطمئن شوید.

یک گام جلوتر

هدف از این آموزش نصب بوت لودر (Bootloader) بر روی میکروکنترلر دلخواه AVR  و  همچنین پروگرام کردن آنها بود. در ضمن همه‌ی این مراحل به کمک برد Arduino  و توسط نرم‌افزار Arduino IDE انجام شد.

حال پیشنهادها و ایده‌هایی مطرح می‌کنیم تا شما بتوانید در گام‌های بعد سراغ آنها رفته و با توجه به اطلاعاتی که در این آموزش کسب کردید،  چالش های جدیدی را برای خود رقم بزنید:

  • استفاده از کلاک 8 مگاهرتز و تغییر فیوزهای میکروکنترلر
  • راه‌اندازی میکروکنترلر با کلاک داخلی
  • استفاده از مبدل USB به TTL جهت پروگرام کردن میکروکنترلر
  • پروگرام شدن یک برد آردوینو توسط یک برد دیگر آردوینو
  • پروگرام میکروهای STM32 با نرم‌افزار IDE

آموزش های مشابه

Comments (35)

  • بابک Reply

    با سلام
    ممنون از آموزش های که قرار میدهید.
    اگر با این روش برنامه مون رو آپلود کنیم ، اون وقت تو مدار نهایی میتونیم فقط آی سی پروگرم شده رو استفاده کنیم ، یعنی بدون آردوینوی کامل؟
    قرار دادن IC جدید توی مدار نهایی pcb ؟

    ممنون از توجه شما کارشناس گرامی

    سپتامبر 7, 2021 at 3:14 ق.ظ
    • مهران ملکی Reply

      سلام.
      بله موقعی که میکروکنترلرتون رو به این روش (و یا به هر روش دیگه‌ای که پیدا کردید) پروگرم کنید، میتونید تو مدار نهاییتون صرفا همون میکروکنترلر رو استفاده کنید.

      سپتامبر 7, 2021 at 10:18 ق.ظ
      • اسماعیل Reply

        سلام من هرکاری میکنم نمیتونم atmega 8 رو پروگرام کنم نمیدونم مشکل کجاست اتصالات رو هم چک کردم
        ای سی خراب نیست خطای عدم شناسی میده

        می 19, 2022 at 11:10 ب.ظ
  • متین Reply

    پایه ISP یا SPI ?????????!!!!!!!!!!!

    بعد اینکه میشه میکروکنترلری که پروگرم شده قبلا به اردوینو متصل کنیم و کد روشو ببینیم چیه؟ اگه بله حتما به اردوینو نیازه یا روش دیگه ای هم داره؟؟؟

    اکتبر 25, 2022 at 5:55 ب.ظ
    • مهران ملکی Reply

      سلام.
      پایه‌های ISP.
      و اینکه دیدن کد پروگرم شده در یک میکروکنترلر تنها به صورت HEX امکانپذیره و اون هم کار سختیه که کاملا بستگی به میکروکنترلر در حال استفادتون داره.

      اکتبر 28, 2022 at 4:05 ب.ظ
  • امیرمهدی Reply

    سلام من وقتی که میخواهم بوت لودر را نصب کنم
    error while burning bootloader
    ارور بالا رو میده، همه اتصالات هم دروسته ممنون میشم پاسخ بدید.

    ژانویه 20, 2023 at 1:12 ق.ظ
  • mobin Reply

    من تازه این برد رو خریدار کردم هر کار میکنم این خطا میا میشه راهنمایی کنید
    processing.app.debug.RunnerException
    at cc.arduino.Compiler.callArduinoBuilder(Compiler.java:317)
    at cc.arduino.Compiler.loadPreferences(Compiler.java:216)
    at cc.arduino.Compiler.build(Compiler.java:175)
    at processing.app.SketchController.build(SketchController.java:664)
    at processing.app.Editor$BuildHandler.run(Editor.java:1638)
    at java.lang.Thread.run(Thread.java:748)
    Caused by: java.io.IOException: Cannot run program “C:\Program Files (x86)\arduino-1.8.19\arduino-builder”: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at processing.app.helpers.ProcessUtils.exec(ProcessUtils.java:26)
    at cc.arduino.Compiler.callArduinoBuilder(Compiler.java:297)
    … 5 more
    Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.(ProcessImpl.java:386)
    at java.lang.ProcessImpl.start(ProcessImpl.java:137)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    … 7 more

    ژانویه 26, 2023 at 4:35 ب.ظ
    • علی عبدالملکی Reply

      سلام
      ممکنه مشکل از ide آردوینو باشه، یه ورژن دیگه رو نصب کنید و دوباره امتحان کنید

      فوریه 28, 2023 at 9:55 ق.ظ
  • Soheilr1 Reply

    سلام
    ممنون از سایت و مطالب و فروشگاه خوبتون
    من به راحتی atmega8 رو پروگرام و تست کردم.
    فقط من با آردوینو مگا اینکارو انجام دادم که باید تو کد اولیه پایه های miso , mosi , sck رو تغییر بدید.
    یک مشکلی دارم فقط اینکه یه کد نوشتم برای راه اندازی nrf24l01 بعد روی atmega8 آپلود کردم ولی کار نمیکنه قبلا همین کد رو روی آردوینو نانو ریختم کار میکرد میخواستم بدونم این مشکل بخاطر 8 بیت بودن میکرو هست یا اینکه به قطعه دیگری نیاز داره؟

    می 4, 2023 at 5:21 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      امکان دارد مربوط به شماره پایه هایی باشد که شما انتخاب کرده اید از آموزش NRF24 که در سایت موجود می باشد استفاده کنید و مود دیباگ را در کد فعال کنید. از آن بخش می توانید بررسی کنید مشکل از کجا می تواند باشد.

      می 6, 2023 at 11:06 ق.ظ
  • آرش Reply

    سلام من بارها از این روش روی at mega 8 بوت لود ریختم و داخل پروژه ازش استفاده کردم
    اما این دفعه ارور بوت لودر میده و بوت نمیشه .مدار هم چک کردم و هیچ مشگلی نداره و حتی آی سی و قطعات هم تعویض کردم اما بایده نداره
    میشه بگید مشگل کجاست

    ژوئن 18, 2023 at 7:02 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      بیشتر مواقع مربوط به سیم کشی می شود که به درستی وصل نشده باشد.
      مورد دیگر در پایه کریستال حتما فرکانسی که قبلا بوت لودر ریخته اید را نیز باید قرار بدهید.(امکان دارد بدون کریستال باید وصل کنید)
      زمانی که بر روی دکمه بوت لودر میزنید یکسری اطلاعات به شما میدهد. آنها را بررسی کنید امکان دارد مشکل را توضیح داده باشد.

      ژوئن 19, 2023 at 10:25 ق.ظ
  • محمد Reply

    سلام ، آیا میشه یه برنامه به زبان c که در کدویژن نوشته شده رو روی بورد آردوینو آپلود کرد؟ یعنی از بورد آردوینو صرفا به عنوان پروگرامر میکرو کنترلر استفاده کرد.

    جولای 12, 2023 at 2:33 ق.ظ
    • محمد دمیرچی Reply

      با سلام
      برد آردوینو را به عنوان ISP پروگرام کنید و سپس در کدویژن نوع پروگرامر خود را بر روی STK500 قرار بدهید. به احتمال زیاد پروگرام انجام می شود. در صورتی که انجام نشد نوع پروگرامر خود را عوض کنید تا مورد مناسب خود را پیدا کنید.

      جولای 12, 2023 at 11:20 ق.ظ
  • سروش Reply

    سلام من تونستم این کارو انجام بدم خیلی ممنون فقط چند تا مشکل داشتم

    ۱ وقتی بوت لودر رو می ریختم ارور میداد بعد که دوتا خازن نویز گیر کریستال رو برداشتم درست شد .

    ۲ از طریق سیم نتونستم برنامه رو آپلود کنم
    و میکرو رو با میکرو آردوینو جابه جا کردم

    آگوست 13, 2023 at 7:14 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      وقتی میکرو را با میکرویی که بر روی آردوینو می باشد جا به جا میکنید زمانی کار میکند که از قبل بوت لودر بر روی میکرو دوم وجود داشته باشد.
      وقتی میکرو دوم کامل خالی باشد امکان پروگرام کردن وجود ندارد ، چون میکرو اول می باشد که بوت لودر میکرو دوم را میریزد روش.
      آن خازن ها نیز باید در رنج 18 الی 28 پیکو فاراد باشند و در صورتی که خارج از این رنج باشید کار نمیکند. همچنین کریستال نیز باید درست انتخاب شده باشد و با فیوز های داخلی میکرو مچ باشد و در غیر این صورت کار نمیکند.
      امکان دارد فیوز بیت اولیه میکرو شما بر روی 8 مگ از روی اوسیلاتور داخلی بوده و از این رو نباید خازن ها و کریستال را بر روی مدار قرار بدهید و با یکبار پروگرام کردن میکرو این تنظیمات فیوز انجام می شود و سپس باید کریستال و خازن ها قرار داده شود.

      آگوست 14, 2023 at 1:14 ب.ظ
  • علیرضا سلیمی Reply

    سلام خسته نباشید اموزش عالی بود من جواب گرفتم … فقط ایا میشه با اردوینو فیوز بیت های میکروکنترلری که بهش وصل میکنیم (برای پروگرام کردن) رو تغییر داد ؟

    اکتبر 9, 2023 at 4:58 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      خواهش میکنم.
      بله می توانید از همین روش برای تغییر فیوز بیت ها استفاده استفاده کنید.
      از این نرم افزار برای این کار می توانید استفاده کنید. البته نرم افزار های دیگر نیز این امکان را دارند.

      اکتبر 11, 2023 at 8:37 ق.ظ
  • حسام Reply

    Sketch uses 4354 bytes (13%) of program storage space. Maximum is 32256 bytes.
    Global variables use 482 bytes (23%) of dynamic memory, leaving 1566 bytes for local variables. Maximum is 2048 bytes.
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x67
    avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00
    Failed uploading: uploading error: exit status 1
    یعنی چی؟

    اکتبر 11, 2023 at 9:08 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      یعنی پروگرام انجام نشده است.
      شما در چه مرحله ای این ارور را دریافت کرده اید؟؟

      اکتبر 14, 2023 at 8:43 ق.ظ
  • احمدرضا خدام Reply

    سلام و ابرترادت من هر چه تلاش کردم نشد این ارور رو میده امضا نا معتبر
    avrdude: Yikes! Invalid device signature.
    Double check connections and try again, or use -F to override
    this check.

    دسامبر 2, 2023 at 4:37 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      متن ارور را مطالعه کنید ارور مشخصه میکرو را میدهد.
      در خط قبلی مشخصه میکرو برای شما نوشته می شود.
      در صورتی که مشخصه برای میکرو دیگری می باشد آن را انتخاب کنید.
      در صورتی که مقادیر نامشخص به شما میدهد سیم کشی شما جایی مشکل دارد یا میکرو شما آسیب دیده می باشد.

      دسامبر 3, 2023 at 8:48 ق.ظ
  • مصطفی Reply

    avrdude error: cannot open port \\.\COM3: Access is denied.

    avrdude error: unable to open programmer stk500v1 on port COM3
    Failed chip erase: uploading error: exit status 1

    وقتی Burn Bootloader رو میزنم این ارور رو دریافت میکنم

    دسامبر 13, 2023 at 5:48 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      در مرحله اول، ابتدا باید طبق آموزش کد Arduino as ISP رو روی برد خود آپلود کرده باشید.
      در مرحله بعدی نوع میکرو را انتخاب کنید و سریال مانیتور را به درستی انتخاب کرده باشید و Burn Bootloader رو بزنید

      دسامبر 16, 2023 at 10:26 ق.ظ
  • کیانی Reply

    حتما باید آردینو باشه نمیشه فقط با usbasp میکرو کنترلر رو پروگرام کرد؟

    ژانویه 5, 2024 at 2:49 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      می توانید از usbasp نیز استفاده کنید

      ژانویه 6, 2024 at 10:56 ق.ظ
  • سعید Reply

    سلام دوست عزیز
    بنده یک مداری بستم و پس از آپلود و ریختن برنامه روی میکرو اون رو داخل مدار قراردادم ، مشکل اینجاست که در قسمتی از برنامه از millis استفاده کردم و وقتی میکرو روی برد آردوینو هست همه چیز درست کار میکند ولی وقتی میکرو را به برد انتقال میدم اونجا تابع millis کار نمیکنه لطفاً راهنمایی بفرمایید تشکر

    ژانویه 19, 2024 at 3:46 ق.ظ
    • محمد دمیرچی Reply

      با سلام
      پیشنهاد میکنم این موارد سوال ها را در بخش انجمن مطرح کنید.
      در صورتی که مشکل شما خطا در زمان بندی می باشد (یعنی زمانی که با millis میخواهید حساب بشود اشتباه است) مربوط به کریستال روی برد شما می باشد که درست کار نمیکند و خطا به وجود می آید.
      در صورتی که مشکل شما در اجرا نشدن دستور می باشد. باید کد شما بررسی شود . از این رو بهتر هست در بخش انجمن تکه کد خودتان را قرار بدهید تا بررسی شود.

      ژانویه 20, 2024 at 9:22 ق.ظ
  • احسان Reply

    سلام من می خواهم یک بوت لود روی atmega2560
    نصب کنم تمام مراحل را به درستی انجام دادم و پیغام
    Done Burning Bootloader
    برای من نمایش داد ولی وقتی دکمه ریست را می زنم led که به پایه ۱۳ متصل هست چشمک نمی زند که نشان‌ دهنده این است بوت لودر روی آن نصب نشده و هرچه تلاش می‌کنم چیزی روی آن پرو گرام کنم نمی شود مشکل از کجاست؟

    ژانویه 26, 2024 at 2:21 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      برای اینکه مطمئن بشوید که عملیات پروگرام بوت لودر شما به درستی انجام می شود
      یک پروژه چشمک زن را باز کنید و اتصالات را وصل کرده و از منو بالا Tools نوع پروگرامر را بر روی دستگاهی که دارید قرار بدهید (اگر از آردوینیو استفاده میکیند بر روی Arduino as ISP قرار بدهید)
      سپس از تب Sketch بر روی گزینه Upload using Programmer را بزنید. در صورتی که عملیات پروگرام به درستی انجام شود برد مقصد باید شروع به اجرا دستور چشمک زدن بکند.
      در صورتی که درست باشد دوباره بوت لودر را بریزید و باید مسیر rx و tx روی میکرو خود را باید بررسی کنید.
      در غیر این صورت جایی از مسیر را اشتباه رفته اید.

      ژانویه 27, 2024 at 8:29 ق.ظ
      • احسان Reply

        سلام خیلی ممنون از راه نمایی شما مشکل حل شد
        من در نرم افزار آردواینو برد حدف را آردواینو مگا قرار داده بودم و به همین دلیل عملیات پروگرام کردن درست انجام نمی شد و الان برد حدف را روی atmega2560 قرار دادم و عملیات به درستی انجام شد

        ژانویه 27, 2024 at 1:23 ب.ظ
  • حامد Reply

    درود . وقت بخیر . در یک اردوینو اونو ch340 , که مشکل برقراری ارتباط در زمان اپلود اسکچ دارد و ارورهای stk500 یا avrdude یا … با هیچ کدام از روش های نرم افزاری برطرف نشده , آیا ممکن است با تعویض ای سی ch340g این مشکل مرتفع شود یا ارتباطی به این قطعه ندارد؟ سپاس

    ژانویه 30, 2024 at 12:58 ب.ظ
  • سپهراتحاد Reply

    سلام خسته نباشید
    با فایل هگز کد اردوینو با استفاده از پروگرمر هاتل میتوان ایسی اتمگا8 را اپلود کرد؟

    فوریه 4, 2024 at 6:54 ب.ظ
    • محمد دمیرچی Reply

      با سلام
      برد آردوینو بسته به مدل ( برای مثال uno از atmega328 استفاده می شود)
      در نتیجه نمی توان این hex را بر روی Atmega8 ریخت.

      فوریه 5, 2024 at 9:35 ق.ظ

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد.