但在下嘗試上載 Sketch 到發現卻出現錯誤,究竟是甚麼原因?
在下為了測試這塊 ATmega328P-U ,網上建議最簡單的方法,就是將 ATmega328P* 安裝到 Arduino UNO Rev3
在下便將原來 Arduino UNO Rev3 上的 ATmega328P-PU 卸除,並安裝 ATmega328P-U 到 Arduino UNO Rev3
但在下發現當上載測試用的 Sketch 到 Arduino 卻出現錯誤
翻查資料估計是這塊 ATmega328P-U 是沒有載入 Bootloader ,需要先將 Bootloader 燒錄到 ATmega328P-U 才能上載 Sketch
外觀
ATmel 的 ATmega328P-U 晶片 的 正面
ATmel 的 ATmega328P-U 晶片 的 背面
引腳
使用 雙列直插封裝 (Dual In-line Package (DIP)) 的 ATmega328P* 共有 28支引腳後 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
用途 | A5 | A4 | A3 | A2 | A1 | A0 | GND | AREF | AVCC | D13 | D12 | D11 | D10 | D9 |
RST | D0/RX | D1/TX | D2 | D3 | D4 | VCC | GND | C0 | C1 | D5 | D6 | D7 | D8 | |
前 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
編號 | 引腳 | 方向 | 用途 |
---|---|---|---|
1 | RST | 輸入 | 重新啟動 當訊號 為 低電壓 時會 重新啟動 |
2 | D0/RX | 輸入/輸出 | 第0 數碼訊號 接收數據 (序列通訊用途) PORTD0 |
3 | D1/TX | 輸入/輸出 | 第1 數碼訊號 送出數據 (序列通訊用途) PORTD1 |
4 | D2 | 輸入/輸出 | 第2 數碼訊號 PORTD2 |
5 | D3 | 輸入/輸出 | 第3 數碼訊號 支援 脈衝寬度調變 輸出 10位元訊號 PORTD3 |
6 | D4 | 輸入/輸出 | 第4 數碼訊號 PORTD4 |
7 | VCC | 電源 (接受 1.8V 至 5.5V) | |
8 | GND | 接地 | |
9 | C0 | 第0 16KHz晶體振盪器 連接 | |
10 | C1 | 第1 16KHz晶體振盪器 連接 | |
11 | D5 | 輸入/輸出 | 第5 數碼訊號 支援 脈衝寬度調變 輸出 10位元訊號 PORTD5 |
12 | D6 | 輸入/輸出 | 第6 數碼訊號 支援 脈衝寬度調變 輸出 10位元訊號 PORTD6 |
13 | D7 | 輸入/輸出 | 第7 數碼訊號 PORTD7 |
14 | D8 | 輸入/輸出 | 第8 數碼訊號 PORTB0 |
15 | D9 | 輸入/輸出 | 第9 數碼訊號 支援 脈衝寬度調變 輸出 10位元訊號 PORTB1 |
16 | D10 | 輸入/輸出 | 第10 數碼訊號 支援 脈衝寬度調變 輸出 10位元訊號 Arduino UNO Rev3 預設 SPI SS引腳 PORTB2 |
17 | D11 | 輸入/輸出 | 第11 數碼訊號 支援 脈衝寬度調變 輸出 10位元訊號 Arduino UNO Rev3 預設 SPI MOSI引腳 PORTB3 |
18 | D12 | 輸入/輸出 | 第12 數碼訊號 Arduino UNO Rev3 預設 SPI MISO引腳 PORTB4 |
19 | D13 | 輸入/輸出 | 第13 數碼訊號 Arduino UNO Rev3 預設 SPI SCK引腳 PORTB5 |
20 | AVCC | 類比電源 | |
21 | AREF | 輸入 | 類比參考 (接受 0V 至 5V) 改變 類比訊號最大值 的 電壓參考值 類比參考 給予 4V 時,類比訊號最大值 為 1023 = 4V 此引腳沒有接駁時 為 5V |
22 | GND | 接地 | |
23 | A0 | 輸入/輸出 | 第0 類比訊號 類比訊號 時只可以作為 輸入10位元訊號 數碼訊號 時可以作為 輸入訊號 或 輸出訊號 PORTC0 |
24 | A1 | 輸入/輸出 | 第1 類比訊號 類比訊號 時只可以作為 輸入10位元訊號 數碼訊號 時可以作為 輸入訊號 或 輸出訊號 PORTC1 |
25 | A2 | 輸入/輸出 | 第2 類比訊號 類比訊號 時只可以作為 輸入10位元訊號 數碼訊號 時可以作為 輸入訊號 或 輸出訊號 PORTC2 |
26 | A3 | 輸入/輸出 | 第3 類比訊號 類比訊號 時只可以作為 輸入10位元訊號 數碼訊號 時可以作為 輸入訊號 或 輸出訊號 PORTC3 |
27 | A4 | 輸入/輸出 | 第4 類比訊號 類比訊號 時只可以作為 輸入10位元訊號 數碼訊號 時可以作為 輸入訊號 或 輸出訊號 Arduino UNO Rev3 預設 I2C SDA引腳 PORTC4 |
28 | A5 | 輸入/輸出 | 第5 類比訊號 類比訊號 時只可以作為 輸入10位元訊號 數碼訊號 時可以作為 輸入訊號 或 輸出訊號 Arduino UNO Rev3 預設 I2C SCL引腳 PORTC5 |
線路接駁
使用 ATmega328P* Host
以 ATmega328P* Host 方式最簡單如果閣下有 2塊 Arduino底板 而其中 1塊是 THT版本 便可以使用
將 非 ATmega328P* Host 的 Arduino 寫入 Arduino ISP (Arduino In-System Programming)
再將 Bootloader 經 Arduino 燒錄到 ATmega328P* Host 的 ATmega328P*
Arduino ISP 引腳 | Arduino Host 引腳 |
---|---|
5V | 5V |
GND | GND |
D13 | D13 |
D12 | D12 |
D11 | D11 |
D10 | RST |
Arduino UNO Rev3 THT版本 上的 28 DIP 引腳座,可以簡單安裝及卸除 ATmega328P*
安裝時, ATmega328P* 的缺口為電源插孔的反方向
使用 ATmega328P* Host 線路接駁 原型
使用 ATmega328P* Host 實際線路接駁
Arduino ISP 的 5V引腳 連接到 ATmega328P* Host 的 5V引腳
Arduino ISP 的 GND引腳 連接到 ATmega328P* Host 的 GND引腳
Arduino ISP 的 D10引腳 連接到 ATmega328P* Host 的 RST引腳
Arduino ISP 的 D13引腳 連接到 ATmega328P* Host 的 D13引腳
Arduino ISP 的 D12引腳 連接到 ATmega328P* Host 的 D12引腳
Arduino ISP 的 D11引腳 連接到 ATmega328P* Host 的 D11引腳
直接連接 ATmega328P*
如果閣下只有 1塊 Arduino底板 便需要接駁電子零件要直接連接 ATmega328P* 寫入 Bootloader 還需要 1粒16MHz晶體振盪器 及 2粒22pF電容
Arduino ISP 引腳 | ATmega328P* 引腳 | 接駁電子零件 | |
---|---|---|---|
C0 | C1 | 16MHz晶體振盪器 | |
GND | C0 | 22pF電容 | |
GND | C1 | 22pF電容 | |
5V | VCC | ||
GND | GND | ||
D13 | D13 | ||
D12 | D12 | ||
D11 | D11 | ||
D10 | RST |
直接連接 ATmega328P* 線路接駁 原型
將 ATmega328P* 安裝到 麵包板 方便接駁
16MHz晶體振盪器 連接到 ATmega328P* C0引腳 及 C1引腳
22pF電容 連接到 ATmega328P* GND引腳 及 C1引腳
另1粒 22pF電容 連接到 ATmega328P* GND引腳 及 C0引腳
接駁方式大致與原型相似
ArduinoISP VCC引腳 連接到 ATmega328P* VCC引腳
ArduinoISP GND引腳 連接到 ATmega328P* GND引腳
ArduinoISP D10引腳 連接到 ATmega328P* RST引腳
ArduinoISP D11引腳 連接到 ATmega328P* D11引腳
ArduinoISP D12引腳 連接到 ATmega328P* D12引腳
ArduinoISP D13引腳 連接到 ATmega328P* D13引腳
寫入 Arduino ISP
開啟 Arduino IDE
選擇 檔案(File) > 例子(Examples) > ArduinoISP 的範本
到 工具(Tools) > Programmer 選擇 AVRISP mk II
將程式上載到 Arduino
到 工具(Tools) > Programmer 選擇 Arduino as ISP
到 工具(Tools) > Burn Bootloader
燒錄 Bootloader
將 Bootloader 燒錄到空白 ATmega328P*
選擇 檔案(File) > 例子(Examples)
選擇測試範本,例如 Basics > Blink
將範本上載到已燒錄 Bootloader 的 ATmega328P* 中
將 Bootloader 燒錄至 ATmega328P* 並上載 Blink 範本測試
如果將這塊 ATmega328P* 安裝到 Arduino , Arduino 上標記著 L 的 LED 會閃動
補充資料
數碼引腳 及 類比引腳 寫著 PORTB 、 PORTC 、 PORTD在下學習 Arduino 時,網上翻查資料經常出現 PORTD = 0x00; 或 byte value = PORTD; 程式碼,最初在下完全不知甚麼意思
翻查 ATmega328P 的說明書都提及 PORT* 時,因此仔細翻找相關資料
PORT* 是 讀取 或 寫入 對應引腳的訊號
例如 寫入
PORTD = 0xB4;由於 0xB4(hex) = 10110100(bin) ,位元資料為 0 = LOW , 為 1 = HIGH
等價於
digitalWrite(7, HIGH); digitalWrite(6, LOW); digitalWrite(5, HIGH); digitalWrite(4, HIGH); digitalWrite(3, LOW); digitalWrite(2, HIGH); digitalWrite(1, LOW); digitalWrite(0, LOW);
例如 讀取
byte value = PORTD;等價於
byte value = 0; value |= ((digitalRead(7) == LOW) ? 0 : 1) << 7; value |= ((digitalRead(6) == LOW) ? 0 : 1) << 6; value |= ((digitalRead(5) == LOW) ? 0 : 1) << 5; value |= ((digitalRead(4) == LOW) ? 0 : 1) << 4; value |= ((digitalRead(3) == LOW) ? 0 : 1) << 3; value |= ((digitalRead(2) == LOW) ? 0 : 1) << 2; value |= ((digitalRead(1) == LOW) ? 0 : 1) << 1; value |= ((digitalRead(0) == LOW) ? 0 : 1) << 0;
除了 PORT* 還有 DDR* 及 PIN* (* 同樣是 B, C, D)
DDR* 為設定對應引腳的 輸入 或 輸出 方向
例如
DDRD = 0x4B;由於 0x4B(hex) = 01001011(bin) ,位元資料為 0 = INPUT , 為 1 = OUTPUT
等價於
pinMode(7, INPUT); pinMode(6, OUTPUT); pinMode(5, INPUT); pinMode(4, INPUT); pinMode(3, OUTPUT); pinMode(2, INPUT); pinMode(1, OUTPUT); pinMode(0, OUTPUT);
PIN* 只是 讀取 對應引腳的訊號
例如
byte value = PIND;等價於
byte value = 0; value |= ((digitalRead(7) == LOW) ? 0 : 1) << 7; value |= ((digitalRead(6) == LOW) ? 0 : 1) << 6; value |= ((digitalRead(5) == LOW) ? 0 : 1) << 5; value |= ((digitalRead(4) == LOW) ? 0 : 1) << 4; value |= ((digitalRead(3) == LOW) ? 0 : 1) << 3; value |= ((digitalRead(2) == LOW) ? 0 : 1) << 2; value |= ((digitalRead(1) == LOW) ? 0 : 1) << 1; value |= ((digitalRead(0) == LOW) ? 0 : 1) << 0;
簡單來說 PORT*, ADD*, PIN* 是一種簡化程式碼或語法的寫法
PORTD 存取 D7 至 D0 共 8位元 資料
但 PORTC 存取 D13 至 D8 及 PORTB 存取 A5 至 A0 ,分別只有 6位元 資料
都是 讀取 第5位元 至 第0位元 的 資料,而非 第7位元 至 第2位元 的 資料
PORT* | 第n引腳 | 第n位元 |
---|---|---|
PORTC | A5 | 5 |
A4 | 4 | |
A3 | 3 | |
A2 | 2 | |
A1 | 1 | |
A0 | 0 | |
PORTB | D13 | 5 |
D12 | 4 | |
D11 | 3 | |
D10 | 2 | |
D9 | 1 | |
D8 | 0 | |
PORTD | D7 | 7 |
D6 | 6 | |
D5 | 5 | |
D4 | 4 | |
D3 | 3 | |
D2 | 2 | |
D1 | 1 | |
D0 | 0 |
補充資料
使用較舊版 Bootloader 的 Arduino Nano亦可以使用這方法,將新版本的 Bootloader 燒綠到 Arduino Nano 的 QFP ATmega328P
總結
淺綠色的 Arduino UNO Rev3 是 Arduino 的官方版本藍色是與 Arduino UNO Rev3 相容的 UNO ,形狀大小與官方版本是完全相同,不過 UNO 比官方版本提供更多引腳
Arduino UNO Rev3 數碼引腳 及 類比引腳 等 常用引腳 都是 插孔,但 UNO 還提供 插頭 方便讓 其他電子零件 連接
設計線路、接駁電子零件、編寫程式、提供電源便可以運作
例如要在 LCD顯示器上 顯示溫度、濕度資料,可以編寫好運作程式,測試正確後,設計編路甚至製作印刷電路板
當安裝所有需要使用的零件都印刷電路板後,接通電源便可以立即使用
比起購買 Arduino ,只購買 ATmega328P* 的成本更低
而且獨立運作的話, Arduino底板 的體積反而會佔據使用空間,可能不太適合小型專案
雖然 Arduino Nano 等版本的體積會細小及便宜,但仍不及單購買 ATmega328P*
如果要更細小,可以使用 SMT 版本的 ATmega328P* 可以更節慳空間及成本
沒有預載 Bootloader 的 ATmega328P* 會再稍微便宜一點
如果需要大量購買,可以選擇沒有預裝 Bootloader 的版本
另外如果上載 Sketch 到 ATmega328P* 時,突然終斷連接,排除晶片的內部受損,有機會導致寫入資料出錯而不能再上載 Sketch
這時同樣需要重新寫入 Bootloader 到 ATmega328P* 讓 ATmega328P* 能正常運作
沒有留言 :
張貼留言