极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1340|回复: 5

8F328U 作基礎的 AVR 燒寫器

[复制链接]
发表于 2019-7-24 13:08:27 | 显示全部楼层 |阅读模式
本帖最后由 eddiewwm 于 2019-7-24 15:20 编辑

用 8F328U 小紅板 按外國大神的指導,完成了以下的 AVR ATmega328P 燒寫器。
AVRprogrammer_9_24_18.JPG

參考視頻:
https://www.youtube.com/watch?v=7H8aQ1mWUy4

AVRprogrammer_9_24_18.ino
  1. #include "data.h"
  2. void setup ()
  3. {
  4.   Serial.begin(115200);
  5.   Serial.println("AVR Programmer Ready...");
  6.   pinMode (startSwitch, INPUT);
  7.   digitalWrite (startSwitch, HIGH);
  8.   pinMode (errorLED, OUTPUT);
  9.   pinMode (readyLED, OUTPUT);
  10.   pinMode (workingLED, OUTPUT);
  11.   pinMode (buzzerPin, OUTPUT);
  12.   digitalWrite(buzzerPin, HIGH);
  13.   delay(20);
  14.   digitalWrite(buzzerPin, LOW);
  15.   // initialize the SD card at SPI_HALF_SPEED to avoid bus errors with
  16.   // breadboards.  use SPI_FULL_SPEED for better performance.
  17.   while (!sd.begin (chipSelect, SPI_HALF_SPEED))
  18.   {
  19.     ShowMessage (MSG_NO_SD_CARD);
  20.     delay (1000);
  21.   }

  22. }  // end of setup



  23. //------------------------------------------------------------------------------
  24. //      LOOP
  25. //------------------------------------------------------------------------------
  26. void loop ()
  27. {

  28.   digitalWrite (readyLED, HIGH);

  29.   // wait till they press the start switch
  30.   while (!getUserSerial()) {}
  31. //  Serial.println("Press Button to Start!!");
  32. //  while (digitalRead (startSwitch) == HIGH)
  33. //  {
  34. //    //just loop in here till start button is pressed
  35. //
  36. //  }  // end of waiting for switch press

  37. }  // end of loop
复制代码


data.h
  1. //includes
  2. #include <SdFat.h>// for SDFat library see: https://github.com/greiman/SdFat


  3. //functions
  4. boolean getUserSerial();
  5. boolean getDate();
  6. boolean getIntro();

  7. void burnEEPROM(byte EEPROMdata);
  8. void getString();
  9. void readALlFromChip();
  10. void showHex (const byte b, const boolean newline = false, const boolean show0x = true);
  11. void blink (const int whichLED1,
  12.             const int whichLED2,
  13.             const byte times = 1,
  14.             const unsigned long repeat = 1,
  15.             const unsigned long interval = 200);
  16. void ShowMessage (const byte which);
  17. byte BB_SPITransfer (byte c);
  18. byte program (const byte b1, const byte b2 = 0, const byte b3 = 0, const byte b4 = 0);
  19. byte readFlash (unsigned long addr);
  20. void writeFlash (unsigned long addr, const byte data);
  21. bool hexConv (const char * (& pStr), byte & b);
  22. void pollUntilReady ();
  23. void showProgress ();
  24. void clearPage ();
  25. void commitPage (unsigned long addr);
  26. void writeData (const unsigned long addr, const byte * pData, const int length);
  27. void verifyData (const unsigned long addr, const byte * pData, const int length);
  28. bool processLine (const char * pLine, const byte action);
  29. bool readHexFile (const char * fName, const byte action);
  30. bool startProgramming ();
  31. void stopProgramming ();
  32. void getSignature ();
  33. void getFuseBytes ();
  34. void writeFuse (const byte newValue, const byte instruction);
  35. bool updateFuses (const bool writeIt);
  36. bool chooseInputFile ();
  37. bool writeFlashContents ();



  38. //variables and constants
  39. const unsigned int ENTER_PROGRAMMING_ATTEMPTS = 2;
  40. String inputstring = "";
  41. boolean input_string_complete = false;
  42. byte EEPROMindex = 0;
  43. const bool allowTargetToRun = true;  // if true, programming lines are freed when not programming
  44. const char dateMessage[] PROGMEM  = {"Please Enter Date like this: MM/DD/YY \n Example for July 4th, 2018, would be 07/04/18\n"};
  45. const char introMessage[]  PROGMEM  = {"What do you want to do?\n  R = Read Board Information\n  W = Write parameters\n  N = Brand New Board Programming\n"};
  46. const char fuseBurn[]  PROGMEM  = {"Burning Fuse Config:  Should be LFuse=0xFF, HFuse=0xDF, EFuse=0xFD\n"};
  47. const char wrongLength[]  PROGMEM  = {"Sorry wrong length\n"};
  48. // fixed file name to read from SD card (root directory)
  49. const char wantedFile [] = "firmware.hex";

  50. // which switch to close to start programming the target chip
  51. const byte startSwitch = 2;

  52. // the three "status" LEDs
  53. const int errorLED = A0;
  54. const int readyLED = A1;
  55. const int workingLED = A4;
  56. const int buzzerPin = 3;

  57. const int noLED = -1;  // must be int! - can be negative

  58. // status "messages"
  59. typedef enum {
  60.   MSG_NO_SD_CARD,          // cannot open SD card
  61.   MSG_CANNOT_OPEN_FILE,    // canoot open file 'wantedFile' (above)
  62.   MSG_LINE_TOO_LONG,       // line on disk too long to read
  63.   MSG_LINE_TOO_SHORT,      // line too short to be valid
  64.   MSG_LINE_DOES_NOT_START_WITH_COLON,  // line does not start with a colon
  65.   MSG_INVALID_HEX_DIGITS,  // invalid hex where there should be hex
  66.   MSG_BAD_SUMCHECK,        // line fails sumcheck
  67.   MSG_LINE_NOT_EXPECTED_LENGTH,  // record not length expected
  68.   MSG_UNKNOWN_RECORD_TYPE,  // record type not known
  69.   MSG_NO_END_OF_FILE_RECORD,  // no 'end of file' at end of file
  70.   MSG_FILE_TOO_LARGE_FOR_FLASH,  // file will not fit into flash

  71.   MSG_CANNOT_ENTER_PROGRAMMING_MODE,  // cannot program target chip
  72.   MSG_NO_BOOTLOADER_FUSE,             // chip does not have bootloader
  73.   MSG_CANNOT_FIND_SIGNATURE,      // cannot find chip signature
  74.   MSG_UNRECOGNIZED_SIGNATURE,     // signature not known
  75.   MSG_BAD_START_ADDRESS,          // file start address invalid
  76.   MSG_VERIFICATION_ERROR,         // verification error after programming
  77.   MSG_FLASHED_OK,                 // flashed OK
  78. } msgType;

  79. //SPI to target pins
  80. const byte MSPIM_SCK = 4;  // port D bit 4
  81. const byte MSPIM_SS  = 5;  // port D bit 5
  82. const byte BB_MISO   = 6;  // port D bit 6
  83. const byte BB_MOSI   = 7;  // port D bit 7
  84. // 8 MHz clock on this pin
  85. const byte CLOCKOUT = 9;

  86. #define BB_MISO_PORT PIND
  87. #define BB_MOSI_PORT PORTD
  88. #define BB_SCK_PORT PORTD
  89. const byte BB_SCK_BIT = 4;
  90. const byte BB_MISO_BIT = 6;
  91. const byte BB_MOSI_BIT = 7;

  92. // control speed of programming
  93. const byte BB_DELAY_MICROSECONDS = 6;
  94. // target board reset goes to here
  95. const byte RESET = MSPIM_SS;
  96. // SD chip select pin
  97. const uint8_t chipSelect = SS;
  98. const unsigned long NO_PAGE = 0xFFFFFFFF;
  99. const int MAX_FILENAME = 13;

  100. // actions to take
  101. enum {
  102.   checkFile,
  103.   verifyFlash,
  104.   writeToFlash,
  105. };

  106. // file system object
  107. SdFat sd;

  108. // copy of fuses/lock bytes found for this processor
  109. byte fuses [5];

  110. // meaning of bytes in above array
  111. enum {
  112.   lowFuse,
  113.   highFuse,
  114.   extFuse,
  115.   lockByte,
  116.   calibrationByte
  117. };

  118. // structure to hold signature and other relevant data about each chip
  119. typedef struct {
  120.   byte sig [3];
  121.   const char * desc;
  122.   unsigned long flashSize;
  123.   unsigned int baseBootSize;
  124.   unsigned long pageSize;     // bytes
  125.   byte fuseWithBootloaderSize;  // ie. one of: lowFuse, highFuse, extFuse
  126.   byte timedWrites;    // if pollUntilReady won't work by polling the chip
  127. } signatureType;

  128. const unsigned long kb = 1024;
  129. const byte NO_FUSE = 0xFF;

  130. // see Atmega datasheets
  131. const signatureType signatures [] PROGMEM =
  132. {
  133.   //     signature        description   flash size   bootloader  flash  fuse
  134.   //                                                     size    page    to
  135.   //                                                             size   change

  136.   // Attiny84 family
  137.   { { 0x1E, 0x91, 0x0B }, "ATtiny24",   2 * kb,           0,   32,   NO_FUSE },
  138.   { { 0x1E, 0x92, 0x07 }, "ATtiny44",   4 * kb,           0,   64,   NO_FUSE },
  139.   { { 0x1E, 0x93, 0x0C }, "ATtiny84",   8 * kb,           0,   64,   NO_FUSE },

  140.   // Attiny85 family
  141.   { { 0x1E, 0x91, 0x08 }, "ATtiny25",   2 * kb,           0,   32,   NO_FUSE },
  142.   { { 0x1E, 0x92, 0x06 }, "ATtiny45",   4 * kb,           0,   64,   NO_FUSE },
  143.   { { 0x1E, 0x93, 0x0B }, "ATtiny85",   8 * kb,           0,   64,   NO_FUSE },

  144.   // Atmega328 family
  145.   { { 0x1E, 0x92, 0x0A }, "ATmega48PA",   4 * kb,         0,    64,  NO_FUSE },
  146.   { { 0x1E, 0x93, 0x0F }, "ATmega88PA",   8 * kb,       256,   128,  extFuse },
  147.   { { 0x1E, 0x94, 0x0B }, "ATmega168PA", 16 * kb,       256,   128,  extFuse },
  148.   { { 0x1E, 0x95, 0x0F }, "ATmega328P",  32 * kb,       512,   128,  highFuse },

  149.   // Atmega644 family
  150.   { { 0x1E, 0x94, 0x0A }, "ATmega164P",   16 * kb,      256,   128,  highFuse },
  151.   { { 0x1E, 0x95, 0x08 }, "ATmega324P",   32 * kb,      512,   128,  highFuse },
  152.   { { 0x1E, 0x96, 0x0A }, "ATmega644P",   64 * kb,   1 * kb,   256,  highFuse },

  153.   // Atmega2560 family
  154.   { { 0x1E, 0x96, 0x08 }, "ATmega640",    64 * kb,   1 * kb,   256,  highFuse },
  155.   { { 0x1E, 0x97, 0x03 }, "ATmega1280",  128 * kb,   1 * kb,   256,  highFuse },
  156.   { { 0x1E, 0x97, 0x04 }, "ATmega1281",  128 * kb,   1 * kb,   256,  highFuse },
  157.   { { 0x1E, 0x98, 0x01 }, "ATmega2560",  256 * kb,   1 * kb,   256,  highFuse },

  158.   { { 0x1E, 0x98, 0x02 }, "ATmega2561",  256 * kb,   1 * kb,   256,  highFuse },

  159.   // AT90USB family
  160.   { { 0x1E, 0x93, 0x82 }, "At90USB82",    8 * kb,       512,   128,  highFuse },
  161.   { { 0x1E, 0x94, 0x82 }, "At90USB162",  16 * kb,       512,   128,  highFuse },

  162.   // Atmega32U2 family
  163.   { { 0x1E, 0x93, 0x89 }, "ATmega8U2",    8 * kb,       512,   128,  highFuse  },
  164.   { { 0x1E, 0x94, 0x89 }, "ATmega16U2",  16 * kb,       512,   128,  highFuse  },
  165.   { { 0x1E, 0x95, 0x8A }, "ATmega32U2",  32 * kb,       512,   128,  highFuse  },

  166.   // Atmega32U4 family -  (datasheet is wrong about flash page size being 128 words)
  167.   { { 0x1E, 0x94, 0x88 }, "ATmega16U4",  16 * kb,       512,   128,  highFuse },
  168.   { { 0x1E, 0x95, 0x87 }, "ATmega32U4",  32 * kb,       512,   128,  highFuse },

  169.   // ATmega1284P family
  170.   { { 0x1E, 0x97, 0x05 }, "ATmega1284P", 128 * kb,   1 * kb,   256,  highFuse  },

  171.   // ATtiny4313 family
  172.   { { 0x1E, 0x91, 0x0A }, "ATtiny2313A",   2 * kb,        0,    32,  NO_FUSE  },
  173.   { { 0x1E, 0x92, 0x0D }, "ATtiny4313",    4 * kb,        0,    64,  NO_FUSE  },

  174.   // ATtiny13 family
  175.   { { 0x1E, 0x90, 0x07 }, "ATtiny13A",     1 * kb,        0,    32,  NO_FUSE },

  176.   // Atmega8A family
  177.   { { 0x1E, 0x93, 0x07 }, "ATmega8A",      8 * kb,      256,    64,  highFuse, true },

  178.   // ATmega64rfr2 family
  179.   { { 0x1E, 0xA6, 0x02 }, "ATmega64rfr2",  256 * kb, 1 * kb,   256, highFuse },
  180.   { { 0x1E, 0xA7, 0x02 }, "ATmega128rfr2", 256 * kb, 1 * kb,   256, highFuse },
  181.   { { 0x1E, 0xA8, 0x02 }, "ATmega256rfr2", 256 * kb, 1 * kb,   256, highFuse },

  182. };  // end of signatures

  183. char name[MAX_FILENAME] = { 0 };  // current file name

  184. // number of items in an array
  185. #define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))

  186. // programming commands to send via SPI to the chip
  187. enum {
  188.   progamEnable = 0xAC,

  189.   // writes are preceded by progamEnable
  190.   chipErase = 0x80,
  191.   writeLockByte = 0xE0,
  192.   writeLowFuseByte = 0xA0,
  193.   writeHighFuseByte = 0xA8,
  194.   writeExtendedFuseByte = 0xA4,

  195.   pollReady = 0xF0,

  196.   programAcknowledge = 0x53,

  197.   readSignatureByte = 0x30,
  198.   readCalibrationByte = 0x38,

  199.   readLowFuseByte = 0x50,       readLowFuseByteArg2 = 0x00,
  200.   readExtendedFuseByte = 0x50,  readExtendedFuseByteArg2 = 0x08,
  201.   readHighFuseByte = 0x58,      readHighFuseByteArg2 = 0x08,
  202.   readLockByte = 0x58,          readLockByteArg2 = 0x00,

  203.   readProgramMemory = 0x20,
  204.   writeProgramMemory = 0x4C,
  205.   loadExtendedAddressByte = 0x4D,
  206.   loadProgramMemory = 0x40,
  207.   readEEPROMbyte = 0xA0,
  208.   writeEEPROMbyte = 0xC0

  209.                     /*
  210.                        0xC0 WRITE BYTE TO EEPROM
  211.                       0xA0 READ BYTE FROM EEPROM

  212.                     */

  213. };  // end of enum

  214. // which program instruction writes which fuse
  215. const byte fuseCommands [4] = { writeLowFuseByte, writeHighFuseByte, writeExtendedFuseByte, writeLockByte };

  216. // types of record in .hex file
  217. enum {
  218.   hexDataRecord,  // 00
  219.   hexEndOfFile,   // 01
  220.   hexExtendedSegmentAddressRecord, // 02
  221.   hexStartSegmentAddressRecord,  // 03
  222.   hexExtendedLinearAddressRecord, // 04
  223.   hexStartLinearAddressRecord // 05
  224. };
  225. // if signature found in above table, this is its index
  226. int foundSig = -1;
  227. byte lastAddressMSB = 0;
  228. // copy of current signature entry for matching processor
  229. signatureType currentSignature;

  230. unsigned long pagesize;
  231. unsigned long pagemask;
  232. unsigned long oldPage;
  233. unsigned int progressBarCount;
  234. // count errors
  235. unsigned int errors;
  236. bool gotEndOfFile;
  237. unsigned long extendedAddress;

  238. unsigned long lowestAddress;
  239. unsigned long highestAddress;
  240. unsigned long bytesWritten;
  241. unsigned int lineCount;


  242. /*
  243.   LED codes (flash counts) - each sequence repeats 5 times

  244.   If you are using the Crossroads programming board, the statuses are also shown
  245.   as a 2-digit code in the 7-segment display. If you have the board with only one
  246.   7-segment display you will see the first letter only.

  247.   Problems with SD card or programming target chip
  248.   ------------------------------------------------

  249.   Red x 1 = Cannot open SD card (Sd)
  250.   Red x 2 = Cannot read file 'firmware.hex' (FL)
  251.   Red x 3 = Cannot enter programming mode in target chip (Ch)
  252.   Red x 4 = This chip does not have a bootloader fuse (Fu)
  253.   Red x 5 = Cannot read chip signature (Sg)
  254.   Red x 6 = Unrecognized signature (Un)
  255.   Red x 7 = Bad start address in hex file for code (Ad)
  256.   Red x 8 = Verification error (bd)

  257.   Problems with firmware.hex file
  258.   -------------------------------

  259.   Red + yellow x 1 = Line in file is too long (E1)
  260.   Red + yellow x 2 = Line in file is too short (E2)
  261.   Red + yellow x 3 = Line does not start with a colon (:) (E3)
  262.   Red + yellow x 4 = Invalid hex digits (should be 0-9, A-F) (E4)
  263.   Red + yellow x 5 = Bad sumcheck at end of line (E5)
  264.   Red + yellow x 6 = Line not expected length (E6)
  265.   Red + yellow x 7 = Unknown record type (E7)
  266.   Red + yellow x 8 = No 'end of file' record in file (E8)
  267.   Red + yellow x 9 = File will not fit into flash of target (LG)

  268.   Worked OK
  269.   ---------

  270.   Green x 3 = Flashed and verified OK - sequence repeats 10 times (AA)

  271.   Other statuses
  272.   --------------

  273.   Green (steady) = Ready to program (close switch to commence)
  274.   Yellow (flashing) = Programming (Pr)
  275.   Green (steady) + yellow (flashing) = verifying (uF)
  276.   No LEDs on = No power?

  277. */
复制代码



getUserInput.ino

  1. boolean getUserSerial() {
  2.   EEPROMindex = 0;
  3.   inputstring.reserve(15);
  4.   digitalWrite (readyLED, HIGH);
  5.   if (!getIntro())
  6.     return 0;
  7.   digitalWrite(buzzerPin, HIGH);
  8.   delay(20);
  9.   digitalWrite(buzzerPin, LOW);
  10.   if (inputstring == "R") {

  11.     readALlFromChip();

  12.     return 0;
  13.   }
  14.   if (inputstring == "N") {
  15.     strcpy (name, wantedFile);
  16.     Serial.println("Programming Started");

  17.     digitalWrite (readyLED, LOW);
  18.     if (!startProgramming ())
  19.     {
  20.       ShowMessage (MSG_CANNOT_ENTER_PROGRAMMING_MODE);
  21.       return;
  22.     }  // end of could not enter programming mode

  23.     //FUSES ARE BURNED HERE!!!
  24.     // WOULD BE NICE IF WE COULD DETERMINE FUSE SETTINGS BASED ON SIGNATURE
  25.     writeFuse (0xFF, writeLowFuseByte);
  26.     stopProgramming();
  27.     startProgramming ();
  28.     //writeFuse (0xD6, writeHighFuseByte);//retains EEPROM
  29.     writeFuse (0xDE, writeHighFuseByte);
  30.     stopProgramming();
  31.     startProgramming ();
  32.     writeFuse (0x05, writeExtendedFuseByte);//BO at 2.7V
  33.     stopProgramming();
  34.     startProgramming ();
  35.     getSignature ();
  36.     for (int k = 0; k < strlen_P(fuseBurn); k++)
  37.     {
  38.       char myChar =  pgm_read_byte_near(fuseBurn + k);
  39.       Serial.print(myChar);
  40.     }
  41.     getFuseBytes ();
  42.     // don't have signature? don't proceed
  43.     if (foundSig == -1)
  44.     {
  45.       ShowMessage (MSG_CANNOT_FIND_SIGNATURE);
  46.       return;
  47.     }  // end of no signature

  48.     digitalWrite (workingLED, HIGH);
  49.     bool ok = writeFlashContents ();
  50.     digitalWrite (workingLED, LOW);
  51.     digitalWrite (readyLED, LOW);
  52.     stopProgramming ();
  53.     //delay (500);
  54.     if (ok) {
  55.       //ShowMessage (MSG_FLASHED_OK);
  56.       for (int i = 0; i < 10; i++) {
  57.         digitalWrite(buzzerPin, HIGH);
  58.         delay(50);
  59.         digitalWrite(buzzerPin, LOW);
  60.         delay(50);
  61.       }
  62.     }
  63.     Serial.println("Programming Complete!");

  64.   }

  65.   digitalWrite (readyLED, HIGH);
  66.   digitalWrite(buzzerPin, HIGH);
  67.   delay(20);
  68.   digitalWrite(buzzerPin, LOW);

  69.   if (!getDate())
  70.     return 0;
  71.   digitalWrite(buzzerPin, HIGH);
  72.   delay(20);
  73.   digitalWrite(buzzerPin, LOW);

  74.   for (int i = 0; i < 10; i++) {
  75.     digitalWrite(buzzerPin, HIGH);
  76.     delay(20);
  77.     digitalWrite(buzzerPin, LOW);
  78.     delay(20);
  79.   }
  80.   Serial.println("DONE!\n\n");
  81.   readALlFromChip();
  82.   return 0;

  83. }




  84. void burnEEPROM(byte EEPROMdata) {
  85.   startProgramming();
  86.   digitalWrite(workingLED, HIGH);
  87.   program (writeEEPROMbyte, 0, EEPROMindex, EEPROMdata);
  88.   delay(100);
  89.   digitalWrite(workingLED, LOW);
  90.   stopProgramming();
  91. }


  92. boolean getDate() {
  93.   inputstring = "";
  94.   //Serial.println("Please Enter Date like this: MM/DD/YY");
  95.   for (int k = 0; k < strlen_P(dateMessage); k++)
  96.   {
  97.     char myChar =  pgm_read_byte_near(dateMessage + k);
  98.     Serial.print(myChar);
  99.   }
  100.   getString();
  101.   if (inputstring.length() > 8 || inputstring.length() < 8) {
  102.     for (int k = 0; k < strlen_P(wrongLength); k++)
  103.     {
  104.       char myChar =  pgm_read_byte_near(wrongLength + k);
  105.       Serial.print(myChar);
  106.     }
  107.     // Serial.println("Sorry wrong length");
  108.     return 0;
  109.   }
  110.   Serial.print("Thanks, will use ");
  111.   Serial.println(inputstring);
  112.   for (int i = 0; i < 8; i++) {
  113.     burnEEPROM(inputstring[i]);
  114.     EEPROMindex++;
  115.   }
  116.   return 1;
  117. }


  118. boolean getIntro() {
  119.   inputstring = "";
  120.   for (int k = 0; k < strlen_P(introMessage); k++)
  121.   {
  122.     char myChar =  pgm_read_byte_near(introMessage + k);
  123.     Serial.print(myChar);
  124.   }

  125.   getString();
  126.   if (inputstring.length() > 1 || inputstring.length() < 1) {
  127.     for (int k = 0; k < strlen_P(wrongLength); k++)
  128.     {
  129.       char myChar =  pgm_read_byte_near(wrongLength + k);
  130.       Serial.print(myChar);
  131.     }
  132.     return 0;
  133.   }

  134.   return 1;
  135. }

  136. void getString() {
  137.   inputstring = "";
  138.   //digitalWrite (readyLED, LOW);
  139.   unsigned long blinkerStart = millis();
  140.   while (1) {
  141.     if (millis() - blinkerStart > 50) {
  142.       digitalWrite(readyLED, !digitalRead(readyLED));
  143.       blinkerStart = millis();
  144.     }

  145.     if (digitalRead (startSwitch) == LOW) {
  146.       inputstring = "N";
  147.       break;
  148.     }

  149.     if (Serial.available() > 0) {
  150.       delay(10);
  151.       inputstring = Serial.readStringUntil(13);           //read the string until we see a <CR>
  152.       //Serial.println(inputstring);
  153.       digitalWrite (readyLED, HIGH);
  154.       //digitalWrite(workingLED, LOW);
  155.       break;
  156.     }
  157.   }
  158. }

  159. void readALlFromChip() {

  160.   if (!startProgramming ()) {
  161.     Serial.println("NO BOARD DETECTED!!");
  162.     return;
  163.   }
  164.   Serial.println("***** Reading From Board *****");
  165.   Serial.println("Config Fuses Set:");
  166.   getFuseBytes ();
  167.   //startProgramming();
  168.   Serial.println("");
  169.   //    Serial.println("Reading Board Data...");
  170.   Serial.print("Date Prog = ");
  171.   byte indexTracker = 0;
  172.   for (byte i = 0; i < 8; i++) {
  173.     Serial.print(char(program (readEEPROMbyte, 0, i)));
  174.     indexTracker++;
  175.   }
  176.   Serial.println("");

  177.   Serial.print("Firmware Date Code = ");
  178.   for (byte i = indexTracker; i < indexTracker + 8; i++) {
  179.     Serial.print(char(program (readEEPROMbyte, 0, i)));
  180.   }

  181.   stopProgramming();
  182.   Serial.println("");
  183.   Serial.println("*********************");
  184.   Serial.println("\n");
  185. }
复制代码



programmingFunctions.ino
  1. /// changed this line: lowestAddress = 0x7E00;//I HAD TO FORCE THIS FOR THE ATMEGA328P

  2. void showHex (const byte b, const boolean newline, const boolean show0x)
  3. {
  4.   if (show0x)
  5.     Serial.print (F("0x"));
  6.   // try to avoid using sprintf
  7.   char buf [4];
  8.   buf [0] = ((b >> 4) & 0x0F) | '0';
  9.   buf [1] = (b & 0x0F) | '0';
  10.   buf [2] = ' ';
  11.   buf [3] = 0;
  12.   if (buf [0] > '9')
  13.     buf [0] += 7;
  14.   if (buf [1] > '9')
  15.     buf [1] += 7;
  16.   Serial.print (buf);
  17.   if (newline)
  18.     Serial.println ();
  19. }  // end of showHex
  20. // blink one or two LEDs for "times" times, with a delay of "interval". Wait a second and do it again "repeat" times.
  21. void blink (const int whichLED1,
  22.             const int whichLED2,
  23.             const byte times = 1,
  24.             const unsigned long repeat = 1,
  25.             const unsigned long interval = 200)
  26. {
  27.   for (unsigned long i = 0; i < repeat; i++)
  28.   {
  29.     for (byte j = 0; j < times; j++)
  30.     {
  31.       digitalWrite (whichLED1, HIGH);
  32.       if (whichLED2 != noLED)
  33.         digitalWrite (whichLED2, HIGH);
  34.       delay (interval);
  35.       digitalWrite (whichLED1, LOW);
  36.       if (whichLED2 != noLED)
  37.         digitalWrite (whichLED2, LOW);
  38.       delay (interval);
  39.     }  // end of for loop
  40.     if (i < (repeat - 1))
  41.       delay (1000);
  42.   }  // end of repeating the sequence
  43. }  // end of blink

  44. void ShowMessage (const byte which)
  45. {
  46.   // first turn off all LEDs
  47.   digitalWrite (errorLED, LOW);
  48.   digitalWrite (workingLED, LOW);
  49.   digitalWrite (readyLED, LOW);
  50.   Serial.println("SOMETHING IS NOT RIGHT!! Press RED Button to try again...");
  51.   while (1) {
  52.     // now flash an appropriate sequence
  53.     switch (which)
  54.     {
  55.       // problems with SD card or finding the file
  56.       case MSG_NO_SD_CARD:                      blink (errorLED, noLED, 1, 5); break;
  57.       case MSG_CANNOT_OPEN_FILE:                blink (errorLED, noLED, 2, 5); break;

  58.       // problems reading the .hex file
  59.       case MSG_LINE_TOO_LONG:                   blink (errorLED, workingLED, 1, 5); break;
  60.       case MSG_LINE_TOO_SHORT:                  blink (errorLED, workingLED, 2, 5); break;
  61.       case MSG_LINE_DOES_NOT_START_WITH_COLON:  blink (errorLED, workingLED, 3, 5); break;
  62.       case MSG_INVALID_HEX_DIGITS:              blink (errorLED, workingLED, 4, 5); break;
  63.       case MSG_BAD_SUMCHECK:                    blink (errorLED, workingLED, 5, 5); break;
  64.       case MSG_LINE_NOT_EXPECTED_LENGTH:        blink (errorLED, workingLED, 6, 5); break;
  65.       case MSG_UNKNOWN_RECORD_TYPE:             blink (errorLED, workingLED, 7, 5); break;
  66.       case MSG_NO_END_OF_FILE_RECORD:           blink (errorLED, workingLED, 8, 5); break;

  67.       // problems with the file contents
  68.       case MSG_FILE_TOO_LARGE_FOR_FLASH:        blink (errorLED, workingLED, 9, 5); break;

  69.       // problems programming the chip
  70.       case MSG_CANNOT_ENTER_PROGRAMMING_MODE:  blink (errorLED, noLED, 3, 5); break;
  71.       case MSG_NO_BOOTLOADER_FUSE:             blink (errorLED, noLED, 4, 5); break;
  72.       case MSG_CANNOT_FIND_SIGNATURE:          blink (errorLED, noLED, 5, 5); break;
  73.       case MSG_UNRECOGNIZED_SIGNATURE:         blink (errorLED, noLED, 6, 5); break;
  74.       case MSG_BAD_START_ADDRESS:              blink (errorLED, noLED, 7, 5); break;
  75.       case MSG_VERIFICATION_ERROR:             blink (errorLED, noLED, 8, 5); break;
  76.       case MSG_FLASHED_OK:                     blink (readyLED, noLED, 3, 2); break;

  77.       default:                                  blink (errorLED, 10, 10);  break;   // unknown error
  78.     }  // end of switch on which message
  79.   }
  80. }  // end of ShowMessage

  81. // Bit Banged SPI transfer
  82. byte BB_SPITransfer (byte c)
  83. {
  84.   byte bit;

  85.   for (bit = 0; bit < 8; bit++)
  86.   {
  87.     // write MOSI on falling edge of previous clock
  88.     if (c & 0x80)
  89.       BB_MOSI_PORT |= bit (BB_MOSI_BIT);
  90.     else
  91.       BB_MOSI_PORT &= ~bit (BB_MOSI_BIT);
  92.     c <<= 1;

  93.     // read MISO
  94.     c |= (BB_MISO_PORT & bit (BB_MISO_BIT)) != 0;

  95.     // clock high
  96.     BB_SCK_PORT |= bit (BB_SCK_BIT);

  97.     // delay between rise and fall of clock
  98.     delayMicroseconds (BB_DELAY_MICROSECONDS);

  99.     // clock low
  100.     BB_SCK_PORT &= ~bit (BB_SCK_BIT);

  101.     // delay between rise and fall of clock
  102.     delayMicroseconds (BB_DELAY_MICROSECONDS);
  103.   }

  104.   return c;
  105. }  // end of BB_SPITransfer

  106. // execute one programming instruction ... b1 is command, b2, b3, b4 are arguments
  107. //  processor may return a result on the 4th transfer, this is returned.
  108. byte program (const byte b1, const byte b2 = 0, const byte b3 = 0, const byte b4 = 0)
  109. {
  110.   noInterrupts ();
  111.   BB_SPITransfer (b1);
  112.   BB_SPITransfer (b2);
  113.   BB_SPITransfer (b3);
  114.   byte b = BB_SPITransfer (b4);
  115.   interrupts ();
  116.   return b;
  117. } // end of program

  118. // read a byte from flash memory
  119. byte readFlash (unsigned long addr)
  120. {
  121.   byte high = (addr & 1) ? 0x08 : 0;  // set if high byte wanted
  122.   addr >>= 1;  // turn into word address

  123.   // set the extended (most significant) address byte if necessary
  124.   byte MSB = (addr >> 16) & 0xFF;
  125.   if (MSB != lastAddressMSB)
  126.   {
  127.     program (loadExtendedAddressByte, 0, MSB);
  128.     lastAddressMSB = MSB;
  129.   }  // end if different MSB

  130.   return program (readProgramMemory | high, highByte (addr), lowByte (addr));
  131. } // end of readFlash
  132. // write a byte to the flash memory buffer (ready for committing)

  133. void writeFlash (unsigned long addr, const byte data)
  134. {
  135.   byte high = (addr & 1) ? 0x08 : 0;  // set if high byte wanted
  136.   addr >>= 1;  // turn into word address
  137.   program (loadProgramMemory | high, 0, lowByte (addr), data);
  138. } // end of writeFlash

  139. // convert two hex characters into a byte
  140. //    returns true if error, false if OK
  141. bool hexConv (const char * (& pStr), byte & b)
  142. {

  143.   if (!isxdigit (pStr [0]) || !isxdigit (pStr [1]))
  144.   {
  145.     ShowMessage (MSG_INVALID_HEX_DIGITS);
  146.     return true;
  147.   } // end not hex

  148.   b = *pStr++ - '0';
  149.   if (b > 9)
  150.     b -= 7;

  151.   // high-order nybble
  152.   b <<= 4;

  153.   byte b1 = *pStr++ - '0';
  154.   if (b1 > 9)
  155.     b1 -= 7;

  156.   b |= b1;

  157.   return false;  // OK
  158. }  // end of hexConv
  159. // poll the target device until it is ready to be programmed
  160. void pollUntilReady ()
  161. {
  162.   if (currentSignature.timedWrites)
  163.     delay (10);  // at least 2 x WD_FLASH which is 4.5 mS
  164.   else
  165.   {
  166.     while ((program (pollReady) & 1) == 1)
  167.     {}  // wait till ready
  168.   }  // end of if
  169. }  // end of pollUntilReady

  170. // shows progress, toggles working LED
  171. void showProgress ()
  172. {
  173.   digitalWrite (workingLED, ! digitalRead (workingLED));
  174. }  // end of showProgress
  175. // clear entire temporary page to 0xFF in case we don't write to all of it
  176. void clearPage ()
  177. {
  178.   unsigned int len = currentSignature.pageSize;
  179.   for (unsigned int i = 0; i < len; i++)
  180.     writeFlash (i, 0xFF);
  181. }  // end of clearPage
  182. // commit page to flash memory
  183. void commitPage (unsigned long addr)
  184. {
  185.   addr >>= 1;  // turn into word address

  186.   // set the extended (most significant) address byte if necessary
  187.   byte MSB = (addr >> 16) & 0xFF;
  188.   if (MSB != lastAddressMSB)
  189.   {
  190.     program (loadExtendedAddressByte, 0, MSB);
  191.     lastAddressMSB = MSB;
  192.   }  // end if different MSB

  193.   showProgress ();

  194.   program (writeProgramMemory, highByte (addr), lowByte (addr));
  195.   pollUntilReady ();

  196.   clearPage();  // clear ready for next page full
  197. }  // end of commitPage
  198. // write data to temporary buffer, ready for committing
  199. void writeData (const unsigned long addr, const byte * pData, const int length)
  200. {
  201.   // write each byte
  202.   for (int i = 0; i < length; i++)
  203.   {
  204.     unsigned long thisPage = (addr + i) & pagemask;
  205.     // page changed? commit old one
  206.     if (thisPage != oldPage && oldPage != NO_PAGE)
  207.       commitPage (oldPage);
  208.     // now this is the current page
  209.     oldPage = thisPage;
  210.     // put byte into work buffer
  211.     writeFlash (addr + i, pData [i]);
  212.   }  // end of for

  213. }  // end of writeData
  214. void verifyData (const unsigned long addr, const byte * pData, const int length)
  215. {
  216.   // check each byte
  217.   for (int i = 0; i < length; i++)
  218.   {
  219.     unsigned long thisPage = (addr + i) & pagemask;
  220.     // page changed? show progress
  221.     if (thisPage != oldPage && oldPage != NO_PAGE)
  222.       showProgress ();
  223.     // now this is the current page
  224.     oldPage = thisPage;

  225.     byte found = readFlash (addr + i);
  226.     byte expected = pData [i];
  227.     if (found != expected)
  228.       errors++;
  229.   }  // end of for

  230. }  // end of verifyData

  231. /*
  232.   Line format:

  233.   :nnaaaatt(data)ss

  234.   Where:
  235.   :      = a colon

  236.   (All of below in hex format)

  237.   nn     = length of data part
  238.   aaaa   = address (eg. where to write data)
  239.   tt     = transaction type
  240.            00 = data
  241.            01 = end of file
  242.            02 = extended segment address (changes high-order byte of the address)
  243.            03 = start segment address *
  244.            04 = linear address *
  245.            05 = start linear address *
  246.   (data) = variable length data
  247.   ss     = sumcheck

  248.               We don't use these

  249. */

  250. // returns true if error, false if OK
  251. bool processLine (const char * pLine, const byte action)
  252. {
  253.   if (*pLine++ != ':')
  254.   {
  255.     ShowMessage (MSG_LINE_DOES_NOT_START_WITH_COLON);
  256.     return true;  // error
  257.   }

  258.   const int maxHexData = 40;
  259.   byte hexBuffer [maxHexData];
  260.   int bytesInLine = 0;

  261.   if (action == checkFile)
  262.     if (lineCount++ % 40 == 0)
  263.       showProgress ();

  264.   // convert entire line from ASCII into binary
  265.   while (isxdigit (*pLine))
  266.   {
  267.     // can't fit?
  268.     if (bytesInLine >= maxHexData)
  269.     {
  270.       ShowMessage (MSG_LINE_TOO_LONG);
  271.       return true;
  272.     } // end if too long

  273.     if (hexConv (pLine, hexBuffer [bytesInLine++]))
  274.       return true;
  275.   }  // end of while

  276.   if (bytesInLine < 5)
  277.   {
  278.     ShowMessage (MSG_LINE_TOO_SHORT);
  279.     return true;
  280.   }

  281.   // sumcheck it

  282.   byte sumCheck = 0;
  283.   for (int i = 0; i < (bytesInLine - 1); i++)
  284.     sumCheck += hexBuffer [i];

  285.   // 2's complement
  286.   sumCheck = ~sumCheck + 1;

  287.   // check sumcheck
  288.   if (sumCheck != hexBuffer [bytesInLine - 1])
  289.   {
  290.     ShowMessage (MSG_BAD_SUMCHECK);
  291.     return true;
  292.   }

  293.   // length of data (eg. how much to write to memory)
  294.   byte len = hexBuffer [0];

  295.   // the data length should be the number of bytes, less
  296.   //   length / address (2) / transaction type / sumcheck
  297.   if (len != (bytesInLine - 5))
  298.   {
  299.     ShowMessage (MSG_LINE_NOT_EXPECTED_LENGTH);
  300.     return true;
  301.   }

  302.   // two bytes of address
  303.   unsigned long addrH = hexBuffer [1];
  304.   unsigned long addrL = hexBuffer [2];

  305.   unsigned long addr = addrL | (addrH << 8);

  306.   byte recType = hexBuffer [3];

  307.   switch (recType)
  308.   {
  309.     // stuff to be written to memory
  310.     case hexDataRecord:
  311.       //lowestAddress  = min (lowestAddress, addr + extendedAddress);
  312.       lowestAddress = 0x7E00;//I HAD TO FORCE THIS FOR THE ATMEGA328P
  313.       highestAddress = max (lowestAddress, addr + extendedAddress + len - 1);
  314.       bytesWritten += len;

  315.       switch (action)
  316.       {
  317.         case checkFile:  // nothing much to do, we do the checks anyway
  318.           break;

  319.         case verifyFlash:
  320.           verifyData (addr + extendedAddress, &hexBuffer [4], len);
  321.           break;

  322.         case writeToFlash:
  323.           writeData (addr + extendedAddress, &hexBuffer [4], len);
  324.           break;
  325.       } // end of switch on action
  326.       break;

  327.     // end of data
  328.     case hexEndOfFile:
  329.       gotEndOfFile = true;
  330.       break;

  331.     // we are setting the high-order byte of the address
  332.     case hexExtendedSegmentAddressRecord:
  333.       extendedAddress = ((unsigned long) hexBuffer [4]) << 12;
  334.       break;

  335.     // ignore these, who cares?
  336.     case hexStartSegmentAddressRecord:
  337.     case hexExtendedLinearAddressRecord:
  338.     case hexStartLinearAddressRecord:
  339.       break;

  340.     default:
  341.       ShowMessage (MSG_UNKNOWN_RECORD_TYPE);
  342.       return true;
  343.   }  // end of switch on recType

  344.   return false;
  345. } // end of processLine

  346. //------------------------------------------------------------------------------
  347. // returns true if error, false if OK
  348. bool readHexFile (const char * fName, const byte action)
  349. {
  350.   const int maxLine = 80;
  351.   char buffer[maxLine];
  352.   ifstream sdin (fName);
  353.   int lineNumber = 0;
  354.   gotEndOfFile = false;
  355.   extendedAddress = 0;
  356.   errors = 0;
  357.   lowestAddress = 0xFFFFFFFF;
  358.   //lowestAddress
  359.   highestAddress = 0;
  360.   bytesWritten = 0;
  361.   progressBarCount = 0;

  362.   pagesize = currentSignature.pageSize;
  363.   pagemask = ~(pagesize - 1);
  364.   oldPage = NO_PAGE;

  365.   // check for open error
  366.   if (!sdin.is_open())
  367.   {
  368.     ShowMessage (MSG_CANNOT_OPEN_FILE);
  369.     return true;
  370.   }

  371.   switch (action)
  372.   {
  373.     case checkFile:
  374.       break;

  375.     case verifyFlash:
  376.       break;

  377.     case writeToFlash:
  378.       program (progamEnable, chipErase);   // erase it
  379.       delay (20);  // for Atmega8
  380.       pollUntilReady ();
  381.       clearPage();  // clear temporary page
  382.       break;
  383.   } // end of switch

  384.   while (sdin.getline (buffer, maxLine))
  385.   {
  386.     lineNumber++;
  387.     int count = sdin.gcount();
  388.     if (sdin.fail())
  389.     {
  390.       ShowMessage (MSG_LINE_TOO_LONG);
  391.       return true;
  392.     }  // end of fail (line too long?)

  393.     // ignore empty lines
  394.     if (count > 1)
  395.     {
  396.       if (processLine (buffer, action))
  397.       {
  398.         return true;  // error
  399.       }
  400.     }
  401.   }    // end of while each line

  402.   if (!gotEndOfFile)
  403.   {
  404.     ShowMessage (MSG_NO_END_OF_FILE_RECORD);
  405.     return true;
  406.   }

  407.   switch (action)
  408.   {
  409.     case writeToFlash:
  410.       // commit final page
  411.       if (oldPage != NO_PAGE)
  412.         commitPage (oldPage);
  413.       break;

  414.     case verifyFlash:
  415.       if (errors > 0)
  416.       {
  417.         ShowMessage (MSG_VERIFICATION_ERROR);
  418.         return true;
  419.       }  // end if
  420.       break;

  421.     case checkFile:
  422.       break;
  423.   }  // end of switch

  424.   return false;
  425. }  // end of readHexFile

  426. // returns true if managed to enter programming mode
  427. bool startProgramming ()
  428. {

  429.   byte confirm;
  430.   pinMode (RESET, OUTPUT);
  431.   digitalWrite (MSPIM_SCK, LOW);
  432.   pinMode (MSPIM_SCK, OUTPUT);
  433.   pinMode (BB_MOSI, OUTPUT);
  434.   //pinMode (BB_MISO, INPUT);
  435.   unsigned int timeout = 0;

  436.   // we are in sync if we get back programAcknowledge on the third byte
  437.   do
  438.   {
  439.     // regrouping pause
  440.     delay (100);

  441.     // ensure SCK low
  442.     noInterrupts ();
  443.     digitalWrite (MSPIM_SCK, LOW);
  444.     // then pulse reset, see page 309 of datasheet
  445.     digitalWrite (RESET, HIGH);
  446.     delayMicroseconds (10);  // pulse for at least 2 clock cycles
  447.     digitalWrite (RESET, LOW);
  448.     interrupts ();

  449.     delay (25);  // wait at least 20 mS
  450.     //delay (25);
  451.     noInterrupts ();
  452.     BB_SPITransfer (progamEnable);
  453.     BB_SPITransfer (programAcknowledge);
  454.     confirm = BB_SPITransfer (0);
  455.     BB_SPITransfer (0);
  456.     interrupts ();

  457.     if (confirm != programAcknowledge)
  458.     {
  459.       if (timeout++ >= ENTER_PROGRAMMING_ATTEMPTS)
  460.         return false;
  461.     }  // end of not entered programming mode

  462.   } while (confirm != programAcknowledge);
  463.   return true;  // entered programming mode OK
  464. }  // end of startProgramming

  465. void stopProgramming ()
  466. {
  467.   // turn off pull-ups
  468.   digitalWrite (RESET, LOW);
  469.   digitalWrite (MSPIM_SCK, LOW);
  470.   digitalWrite (BB_MOSI, LOW);
  471.   digitalWrite (BB_MISO, LOW);

  472.   // set everything back to inputs
  473.   pinMode (RESET, INPUT);
  474.   pinMode (MSPIM_SCK, INPUT);
  475.   pinMode (BB_MOSI, INPUT);
  476.   pinMode (BB_MISO, INPUT);

  477. } // end of stopProgramming

  478. void getSignature ()
  479. {
  480.   foundSig = -1;
  481.   lastAddressMSB = 0;

  482.   byte sig [3];
  483.   // Serial.print (F("Signature = "));




  484.   for (byte i = 0; i < 3; i++)
  485.   {
  486.     sig [i] = program (readSignatureByte, 0, i);
  487.     //   showHex (sig [i]);
  488.   }  // end for each signature byte
  489.   Serial.println ("");
  490.   for (unsigned int j = 0; j < NUMITEMS (signatures); j++)
  491.   {
  492.     memcpy_P (&currentSignature, &signatures [j], sizeof currentSignature);

  493.     if (memcmp (sig, currentSignature.sig, sizeof sig) == 0)
  494.     {
  495.       foundSig = j;
  496.       // make sure extended address is zero to match lastAddressMSB variable
  497.       program (loadExtendedAddressByte, 0, 0);
  498.       return;
  499.     }  // end of signature found
  500.   }  // end of for each signature

  501.   ShowMessage (MSG_UNRECOGNIZED_SIGNATURE);
  502. }  // end of getSignature

  503. void getFuseBytes ()
  504. {
  505.   fuses [lowFuse]   = program (readLowFuseByte, readLowFuseByteArg2);
  506.   fuses [highFuse]  = program (readHighFuseByte, readHighFuseByteArg2);
  507.   fuses [extFuse]   = program (readExtendedFuseByte, readExtendedFuseByteArg2);
  508.   fuses [lockByte]  = program (readLockByte, readLockByteArg2);
  509.   fuses [calibrationByte]  = program (readCalibrationByte);

  510.   Serial.print (F("LFuse = "));
  511.   showHex (fuses [lowFuse], true);
  512.   Serial.print (F("HFuse = "));
  513.   showHex (fuses [highFuse], true);
  514.   Serial.print (F("EFuse = "));
  515.   showHex (fuses [extFuse], true);
  516.   Serial.print (F("Lock byte = "));
  517.   showHex (fuses [lockByte], true);
  518.   Serial.print (F("Clock calibration = "));
  519.   showHex (fuses [calibrationByte], true);

  520. }  // end of getFuseBytes


  521. // write specified value to specified fuse/lock byte
  522. void writeFuse (const byte newValue, const byte instruction)
  523. {
  524.   //  if (newValue == 0)
  525.   //    return;  // ignore

  526.   program (progamEnable, instruction, 0, newValue);
  527.   pollUntilReady ();
  528. }  // end of writeFuse

  529. // returns true if error, false if OK
  530. bool updateFuses (const bool writeIt)
  531. {
  532.   unsigned long addr;
  533.   unsigned int  len;

  534.   byte fusenumber = currentSignature.fuseWithBootloaderSize;

  535.   // if no fuse, can't change it
  536.   if (fusenumber == NO_FUSE)
  537.   {
  538.     //    ShowMessage (MSG_NO_BOOTLOADER_FUSE);   // maybe this doesn't matter?
  539.     return false;  // ok return
  540.   }

  541.   addr = currentSignature.flashSize;
  542.   len = currentSignature.baseBootSize;

  543.   if (lowestAddress == 0)
  544.   {
  545.     // don't use bootloader
  546.     fuses [fusenumber] |= 1;
  547.   }
  548.   else
  549.   {
  550.     byte newval = 0xFF;

  551.     if (lowestAddress == (addr - len))
  552.       newval = 3;
  553.     else if (lowestAddress == (addr - len * 2))
  554.       newval = 2;
  555.     else if (lowestAddress == (addr - len * 4))
  556.       newval = 1;
  557.     else if (lowestAddress == (addr - len * 8))
  558.       newval = 0;
  559.     else
  560.     {
  561.       ShowMessage (MSG_BAD_START_ADDRESS);
  562.       return true;
  563.     }

  564.     if (newval != 0xFF)
  565.     {
  566.       newval <<= 1;
  567.       fuses [fusenumber] &= ~0x07;   // also program (clear) "boot into bootloader" bit
  568.       fuses [fusenumber] |= newval;
  569.     }  // if valid

  570.   }  // if not address 0

  571.   if (writeIt)
  572.   {
  573.     writeFuse (fuses [fusenumber], fuseCommands [fusenumber]);

  574.   }

  575.   return false;
  576. }  // end of updateFuses

  577. // returns true if error, false if OK
  578. bool chooseInputFile ()
  579. {

  580.   if (readHexFile(name, checkFile))
  581.   {
  582.     return true;  // error, don't attempt to write
  583.   }

  584.   // check file would fit into device memory
  585.   if (highestAddress > currentSignature.flashSize)
  586.   {
  587.     ShowMessage (MSG_FILE_TOO_LARGE_FOR_FLASH);
  588.     return true;
  589.   }

  590.   // check start address makes sense
  591.   if (updateFuses (false))
  592.   {
  593.     return true;
  594.   }

  595.   return false;
  596. }  // end of chooseInputFile

  597. // returns true if OK, false on error
  598. bool writeFlashContents ()
  599. {

  600.   errors = 0;

  601.   if (chooseInputFile ())
  602.     return false;


  603.   // ensure back in programming mode
  604.   if (!startProgramming ())
  605.     return false;

  606.   // now commit to flash
  607.   if (readHexFile(name, writeToFlash))
  608.     return false;

  609.   // turn ready LED on during verification
  610.   digitalWrite (readyLED, HIGH);

  611.   // verify
  612.   if (readHexFile(name, verifyFlash))
  613.     return false;

  614.   // now fix up fuses so we can boot
  615.   if (errors == 0)
  616.     updateFuses (true);

  617.   return errors == 0;
  618. }  // end of writeFlashContents
复制代码

回复

使用道具 举报

发表于 2019-7-31 11:30:01 | 显示全部楼层
看上去代码有点长...
另外,这块和耗电有什么关系么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-7-31 21:54:16 | 显示全部楼层
這是 AVR ATmega328P 的燒寫器,跟耗電沒關係!
回复 支持 反对

使用道具 举报

发表于 2019-10-17 10:24:03 来自手机 | 显示全部楼层
这个可以作为 LGT328P的编程器使用吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-10-17 11:27:10 | 显示全部楼层
活得精彩 发表于 2019-10-17 10:24
这个可以作为 LGT328P的编程器使用吗?

不可以,LGT8F328P 的燒寫方法跟 ATmega328P 不同。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2019-11-18 12:59 , Processed in 0.053213 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表