2017年10月25日 星期三

Arduino DUE上的ATmega16u2韌體燒錄

由於工作上碰到需要將Arduino DUE整合在PCB板上,所以預先學習及實際燒錄實驗,特此將資料做紀錄,但目前PCB板還在設計中,未來如果在實際操作中還遇到什麼問題,將會繼續補充。

此篇不會講到:
1. 燒錄方法 -> 請自行爬文。
2. DUE在Arduino IDE的環境安裝 -> 請自行爬文。

實作環境:
Arduino IDE 1.5.8

首先須說明的是雖然DUE跟UNO、MEGA2560一樣是使用ATmega16u2,用途也是類似FT232(USB裝置IC)之功能,但是其中燒錄的韌體是完全不同的,所以不可以直接用FT232來代替。

我們先從官方的電路圖來看:




16U2的pin23(PC6)是有做SAM3X8E的ERASE功能,此功能在UNO、MEGA2560都是沒有的。

燒錄方式

請參考 => https://petervanhoyweghen.wordpress.com/2013/02/25/modifying-the-atmega16u2-firmware-on-the-due/

這邊SPI的5V我沒有接到DUE的VCC,DUE是獨立供電(因為工作電壓為3.3V怕有疑慮)

都準備好了就可以開啟CMD下指令燒錄囉(請依照自己的路徑做修改)

主要要修改下列路徑:
avrdude.exe
avrdude.conf
Arduino-DUE-usbserial-prod-firmware-2013-02-05.hex -> 似乎只有1.5.X的IDE才會有,我另外一個1.8.X版本的IDE沒有此檔案

 "C:\Users\Desktop\arduino-1.5.8-windows\arduino-1.5.8\hardware\tools\avr\bin\avrdude.exe" -C "C:\Users\Desktop\arduino-1.5.8-windows\arduino-1.5.8\hardware\tools\avr\etc\avrdude.conf" -v -v -v -v -p m16u2 -c avrisp -P COM9 -b 19200 -U flash:w:C:\Users\arduino-1.5.8-windows\arduino-1.5.8\hardware\arduino\sam\firmwares\atmega16u2\Arduino-DUE-usbserial-prod-firmware-2013-02-05.hex:i

燒錄完成後就可以透過USB燒錄囉


2017年10月24日 星期二

Arduino語法介紹-PROGMEM

使用時機
1. 存放指令
    當你需要宣告存放指令名稱的空間。
2. 大量重覆性資料
    當你有大量的重複性資料需要透過Serial、Client…等,Steam類型的物件print。
3. 查表法表格
    當你需要設置一個資料量大的查表法表格。

為何使用
要解決硬體SRAM空間不足之問題,使用PROGMEM就是將這些大量資料從SRAM搬到Flash,當要使用的時候再從Flash中搬回來。 因為AVR系列的晶片SRAM大小不一,當資料大的情況,使用超過硬體的SRAM大小,此時編譯器編譯可能不會報錯,但是在使用上不代表程式運作不會發生異常。

如何使用
PROGMEM 變數修飾符是被定義在 pgmspace.h 之中,它是 AVR 架構中 pgmspace.h 函式庫眾多函式的其中之一。所以您要使用 PROGRAM 之前,必須在程式的開頭包含入這個函式庫,如下: #include 然後,使用下列句法給值

const dataType variableName [ ] PROGMEM = {data0, data1, data2...};

dataType - 表資料型態。
variableName - 表變數名稱。

PROGMEM 只是一個變數修飾符,它沒有被規定應該放在哪個位置,所以下列三種宣告方式都可以通過編譯器的編譯:

const dataType variableName [ ] PROGMEM = {data0, data1, data2...};
const PROGMEM dataType variableName [ ] = {data0, data1, data2...};
const dataType PROGMEM variableName [ ] = {data0, data1, data2...};

注意事項

請注意,為了要使用 PROGMEM,您必須將變數指定為全域變數(Global)或靜態變數(Static)。 下列程式碼若是被放在函式裡面,它將不會運作

const char long_str[] PROGMEM = "Hello world.";

下列程式碼若是被放在函式裡面,它會運作

const static char long_str[] PROGMEM = “Hello world." 

官方範例 =>  https://www.arduino.cc/en/Reference/PROGMEM

小小的Demo Exported from Notepad++
#include <avr/pgmspace.h> const char Command_0[] PROGMEM = "*IDN?"; const char Command_1[] PROGMEM = "Start"; const char Command_2[] PROGMEM = "END"; const char* const CommandTable[] PROGMEM = { Command_0, Command_1, Command_2 }; void setup() { Serial.begin(19200); while (!Serial); //PGM_ReadChar demo char yy[10]; PGM_ReadChar(yy, CommandTable[0]); //print yy for (int r = 0; r < strlen(yy); r++) Serial.println(yy[r]); //PGM_ReadChar_PT demo PGM_ReadChar_PT(CommandTable[1]); } void loop() { } void PGM_ReadChar(char input[], const char PGM_Arr[]) //Read PROGMEM to char[] { int len = strlen_P(PGM_Arr); int Cnt; for (Cnt = 0; Cnt < len; Cnt++) { input[Cnt] = pgm_read_byte_near(PGM_Arr + Cnt); } input[Cnt] = "\0"; } void PGM_ReadChar_PT(const char PGM_Arr[]) //Read PROGMEM to print { int len = strlen_P(PGM_Arr); char MyChar; for (int k = 0; k < len; k++) { MyChar = pgm_read_byte_near(PGM_Arr + k); Serial.print(MyChar); } }