2011年3月1日 星期二

把 Arduino 當成一個 AVR ISP(In-System Programmer) 使用(2)

這是這系列的第二篇。

前一篇中提到,用 Arduino 做 AVR ISP Programming,我們用了兩張 Arduino 板子,一個是燒錄用的板子,叫作 ArduinoISP,另一個是要被燒錄 bootloader 的板子,稱為 Target board。其實 Target board 不一定非得使用 Arduino 板子不可,你也可以用麵包板當作 Target Board。

用麵包板當作 Target Board 標準版

用麵包板做 Target Board,要準備的材料除了麵包板和 ATmega 晶片外,你還需要 4 個元件:

  • 一個 16 MHz 的石英震盪器(Crystal)
  • 一個 10k 歐姆電阻,以及
  • 兩個 18 到 22 pF(picofarad) 的陶瓷電容

線路接法如下圖:
image
▲ 麵包板當作 Target Board 用,標準版本

用麵包板當作 Target Board 最低需求版

如果你沒有 16 MHz 的石英震盪器也沒有 18-22 pF 的陶瓷電容,那麼你可以設置 ATMega 晶片使用它內部的 8 MHz RC 震盪器當作時脈源。其實 Reset pin 上不放 10K pull up 電阻也沒有關係,所以也可以把它拿掉,這樣你就可以做個最低需求的麵包板 Target Board 了。

線路接法如下圖: image
▲ 麵包板當作 Target Board 用,最低需求版本

要用這個最低需求麵包板的 Target Board,你得做一件事。首先打開 C:\arduino-00xx\hardware\arduino\board.txt (00xx 是你 Arduino IDE 的版本號碼),並將底下這段設定附加到 board.txt 檔案中:

接著重新啟動 Arduino IDE,在 Tools > Board  選單中應該就會看到多了一個 "ATmega328 on a breadboard (8 MHz internal clock)" 的選項:

image

當你設定完成之後,就可以照前一篇的「Bootloader 燒錄步驟」把 bootloader 燒錄到 ATmega 晶片。在燒錄 bootloader 的時候,記得一定要選 "ATmega328 on a breadboard (8 MHz internal clock)" 這個選項,不然的話就沒效。

ATmega328 Pinout

下圖是 ATmega328 晶片的腳位排列圖(Pinout),在連接線路的時候可作為參考:

image
▲ 取自 ATmega328 datasheet

後記

這篇取材自 "From Arduino to a Microcontroller on a Breadboard" 一文,我做過實驗,標準版可以動(加了 16 MHz 石英震盪器的版本),但最低需求版的實驗沒有成功(使用內部 RC 震盪器),在點 Tools > Burn Bootloader > w/ Arduino as ISP 開始燒錄 bootloader 的時候,Arduino IDE 會丟出一個錯誤訊息: "avrdue: Yikes! Invalid device signature.":

image

不曉得我哪邊的設定不正確? 我大膽猜測可能是 Fuses 的設定不對,不過 AVR Fues 要怎麼設我不懂,如果有網友試驗成功,還請不吝分享。

延伸閱讀

46 意見:

letoh 提到...

可先用 avrdude 把 signature 和 fuse 設定讀出來看看對不對,再寫入正確設定

coopermaa 提到...

avrdude? Thanks, 我找個時間來試看看。

letoh 提到...

fuse 設定會決定要使用外部石英震盪器還是內部 rc,先在連得上 chip 的情況下,透過 avrdude 讀出設定確認,要改用內部 rc 的話,找線上計算 fuse 設定的網頁算一下新設定值,再用 avrdude 寫入新設定應該就可以測試最低需求版

p.s. avrdude 好像有 gui 界面,覺得參數很多很煩可以找找看

coopermaa 提到...

AVR 的 Fuse 設定跟 Microchip PIC 的 Configuration bits 應該是一樣的東西。我很納悶為什麼 ATmel 把石英震盪器的設定稱作 fuse?這跟保險絲有關嗎?

看來還是有必要把 AVR 晶片弄通,所以我正計畫要學 AVR 單晶片。

coopermaa 提到...

letoh 是 forth 玩家? forth 這語言我只耳聞沒學過,剛看了一下網路上的資料,哇塞!我發現它的語法跟大眾語言差很多,第一次接觸,還真是不太習慣咧,寫 forth 程式好像是都用 postfix 在思考的樣子。看符式協會 google group 的討論,感覺玩 forth 好像都是 hacker 等級的怪物...喔,我沒有惡意,我是說都是高手中的高高手。:)

GCY 提到...

forth給我的感覺就跟Lisp一樣XD我指的不是語法等等,就單純很Geek的感覺XD

coopermaa 提到...

有時候真佩服那些發明程式語言的人,不曉得他們腦袋是怎麼做的。

letoh 提到...

pic 我不熟,對於 avr 其實也是剛接觸的新手。avr 的 fuse bit 包含很多 chip 相關組態,例如 clock,i/o pin 用途,以及是否啟用 watchdog 等功能。把它想成各種功能的開關就是囉,不是只有 clock 設定。

Forth 是我最愛的語言(心法),也是我最不熟的語言 :(
會寫 C 的人,只要學到會用 function pointer 的程度,應該都能理解 Forth 的運作方式 :p

要玩 Forth 其實不用拘泥於型式,之前我就用 c 寫了一個給 arduino 用的 simple forth shell,雖然不是正統 forth,但用來測試簡單的 i/o 動作還蠻好用的 :p 處理和硬體的互動性是 Forth 被發明出來的初衷,我建議可以試著從這個角度出發,而不是完全當作新的程式語言來學 :)

@GCY:
Forth 會設計成這種型式是有原因的,在某些情況很好用,也因此看起來跟一般主流的通用性程式語言不太一樣 :) 在我的認知,Geek 多半會對問題有深入瞭解,並找出有效率的解決方法。Forth 不過是個工具,當然也會是選項之一囉

符式學會裡的前輩們都是經驗豐富的高手,有興趣的話歡迎來參與討論 :)

GCY 提到...

@letoh:挺棒的!希望有機會可以請教前輩:)

coopermaa 提到...

@letoh, PIC 的 Configuration bits 的用途也是在設這些晶片組態。說到 simple forth shell, 有個東西也許你會有興趣,我前天用 arduino + forth 搜尋,找到 finf(FINF Is Not Forth),FINF 是個給 Arduino 用的 FORTH-like language.

coopermaa 提到...

@letoh + @GCY, 你們兩位來訪,真是蓬蓽生輝啊! :)

letoh 提到...

感謝介紹 finf。我看了一下程式碼,似乎連 compiler 都完成了,算是個具體而微的 Forth 系統了,而且從中也學到一些 avr-c 的寫法,真是很棒的範例

coopermaa 提到...

You're welcome.

這幾天在 K Arduino 的 code,過程中需要翻閱 AVR datasheet,我發現 AVR 的暫存器命名都很直覺好記,還蠻容易學習的。

CYC 提到...

想請教一下
我用您介紹的各種方法去燒錄bootloader
但是都會遇到
avrdude: stk500_getsync(): not in sync: resp=0x15這個錯誤
我看官網說加個電阻進去,但是對我來說還是無效
不知道您有沒有這個問題的解決方案呢?

PS:連麵包版都會出現這樣的問題...

coopermaa 提到...

@CYC
Arduino IDE 打開 Serial Port 的時候,會觸發 ArduinoISP
的 Auto reset,可能就會產生 not in sync 這個問題。在燒錄的時候可以暫時把這個功能關掉,方法是在 +5V 和 Reset pin 之間接一顆 110 歐姆的電阻。請參考 Mega ISP 這篇

提到...
作者已經移除這則留言。
coopermaa 提到...

hi, pin11 接到晶片右邊數過來第三支腳沒錯,
你可以看這篇,裏面有一張 Atmega328 晶片與 Arduino 的腳位對照表:
http://coopermaa2nd.blogspot.com/2011/07/2-io-ports.html

那個 pcint3 是 Pin Change Interrupt Request 3 的縮寫,不是 Arduino 的對應腳位喔。是的,Atmega8 接法也是一樣。

不客氣喲!歡迎來這交流。

提到...

抱歉!因為後來找的了答案,在沒有重新整理網頁下就把留言刪掉了。(實在抱歉。)
再問您一個問題,請問我從電器行買回來的Atmega8A-PU 第一個步驟是什麼?
燒韌體?(韌體是啥?)還是直接使用 ArduinoISP 來燒錄 Arduino 程式(Arduino Sketch)了?
請問,我只用單顆的Atmega8A-PU在電路中一需要石英嗎?(沒有石英就沒有等待時間?)
謝謝您! (還有抱歉。)

coopermaa 提到...

韌體 (firmware) 是寫到晶片裏的程式,其實就是程式啦。
這要看你想怎麼使用,如果買回晶片後用 ArduinoISP 或 AVR Dragon 之類的 Programmger 直接燒 Arduino Sketch,也是可以的,只不過因為沒有 bootlaoder,所以下次還是要用 ArduinoISP 或 AVR Dragon 更新程式,不能用 Arduino IDE 上傳程式,好處是少了 bootloader 可以有很多程式空間可用。或者你也可以先燒 bootloader,然後再用 Arduino IDE 上傳程式,不過你可能要調整一下 Arduino IDE,因為標準 Arduino IDE 只支援一個 Atmega8 (Arduino NG),而且 clock 用的是 16 MHz。

如果你要進一步了解,可以參考我這篇:http://coopermaa2nd.blogspot.com/2011/06/avrdude-arduino-sketch.html

不用石英也行,只是你要調整 Arduino IDE 的 boards.txt。這部份可參考這篇:http://todbot.com/blog/2009/05/26/minimal-arduino-with-atmega8/

提到...

請問您"不能用 Arduino IDE 上傳程式"的意思是晶片不能直接接上USB上傳程式,而是要透過ArduinoISP上傳嗎?
(請問我的Programmger用ArduinoISP,然後用Arduino IDE寫程式上傳嗎?還是我要用DOS視窗?)
謝謝您!

coopermaa 提到...

是的,如果沒有燒 bootloader 就不能走 USB 上傳程式,要透過 ISP 介面上傳,所以會需要 Programmer。

你選 Arduino IDE 那邊的 Programmer 要注意一件事,Arduino IDE 這個功能是燒錄 bootloader 用的,不能用來上傳 sketch 喔!

You're welcome.

提到...

http://coopermaa2nd.blogspot.com/2011/05/arduino-avr-ispin-system-programmer-3.html

那我按照您這篇文章的指示
"編輯 Arduino 的 preferences.txt"
應該就可以燒了吧?
謝謝!

coopermaa 提到...

是的。

你把我寫的每一篇都讀過了。:-)

coopermaa 提到...

對了,我沒有試過 Atmega8 @8 Mhz
Atmega8 跟 Atmega168/328 的 fuses 設定可能不太一樣,建議你在用 atmega8 的時候順便參考這篇的設定:http://todbot.com/blog/2009/05/26/minimal-arduino-with-atmega8/

提到...

我要用 Atmega8 和 16 MHz 石英震盪器
(按照您上面"麵包板當作 Target Board 用,標準版本"的接法),
這樣"編輯 Arduino 的 preferences.txt",在燒錄應該就沒有問題吧!

是的,相關的文章我都看過了,因為我之前有買這個
http://www.eslite.com/product.aspx?pgid=10099145301929592
所以有稍微接觸了Arduino,所以我有一塊Atmega168的開發板,所以我想要用這塊開發板當作ArduinoISP,不想再做USBasp了。
本來想要用8051製作萬年曆(因為我把桌上的時鐘搞壞了,現在都是睡到自然醒,每次早上的台詞:X!遲到了!。所以才想會製作這個)
但是上網找資料的時候發現,都是一些販賣專題報告的賣家,
像什麼『【歐趴專賣店】-8051單晶片專題製作』等等。根本找不到相關的資料(也許是我不會找)
所以才把腦筋動到曾接觸過的Arduino,發現製作Arduino的成本便宜,程式好寫,而且網路上一大堆文章。
所以才選擇它。既然選擇了它,那當然要做一些功課囉。(禮拜六家裡有事,沒買到材料喇~ OAO)
謝謝您!

coopermaa 提到...

嗯,理論上應該是可以.
atmega8 有分 Atmega8 跟 Atmega8L 兩種版本。Atmega8 可以跑到 16MHz,Atmega8L 只能到 8MHz。之前我想把 Atmega8L 超頻到 16MHz,結果沒試成功。:(

呵~這是正常的,將來 Arduino 如果成本降低,然後市場也打開之後,我可以想像應該會出現 『Arduino 專題製作...」之類商品。

提到...

請問,我昨天購買了一顆ATMEGA8-16PU,
我按照您的麵包版的標準版本接線(零件都有齊全)
也把ArduinoISP程式燒到Atmega168的開發板上
也有編輯 Arduino 的 preferences.txt
也設定了Tools>Board>Arduino NG or older w/ ATmega8
但是在燒錄的時候發生錯誤,如下:
Wrong microcontroller found. Did you select the right board from the Tools > Board menu?
avrdude: Expected signature for ATMEGA8 is 1E 93 07
Double check chip, or use -F to override this check.

(錯誤圖片:https://plus.google.com/u/0/photos/104122324856232209042/albums/5713719272211534945/5713719269045012050)
請問該如何解決呢?
謝謝您!

coopermaa 提到...

你有接 16 Mhz 的 crystal 嗎?

提到...

有的。

提到...

是因為我沒有設定Fuses,所以他才抓不到晶片嗎?
全新的晶片一定要燒Fuses嗎?
要怎麼用 avrdude 去設定 fuse 呢?
(可以請您說明一下什麼是Fuses嗎?)
謝謝您!

coopermaa 提到...

你抓不到晶片的訊息是 signature 不對
好像不是 Fuses 的關係
你是用 Arduino 1.0 嗎?
建議你把 Preferences > Show verbose output during > compilation 打開,然後看完整的錯誤訊息寫什麼

Fuses 簡單說就是晶片的設定
比如最重要的 Clock Source ( clock source 是內部或外部振盪器、頻率是多少,要不要除頻等)、還有 Brown-detection, watchdog 等設定

全新的晶片建議先設定 Fuses,或是先燒一次 bootlaoder (這個步驟就會設定 fuses)

可以參考一下這篇 fuses 的介紹:
http://www.ladyada.net/learn/avr/fuses.html

如果你用其它廠牌的晶片,也會有類似的設定
比如 Microchip PIC,不過在 PIC 裏不叫 Fuses,它叫 Configuration Bits

提到...

您好,我是用Arduino-0018
您說先燒一次bootlaoder,那晶片不是剩7KB而已嗎?
要怎麼把它刪除押?
還是用ArduinoISP在燒一次程式它就不見惹?(那就是8KB?)
謝謝您!

coopermaa 提到...

是的,先燒一次 bootloader,然後再用 ArduinoISP 再燒 Sketch 就行,這樣會蓋掉 bootloader。

Arduino-0018 的話,可以按 Shift + Verify 編譯程式,這樣會有很多編譯的訊息。

提到...

我試燒bootloader,一樣的錯誤
avrdude: Expected signature for ATMEGA8 is 1E 93 07
Double check chip, or use -F to override this check.
為什麼捏?(線路都正確。)
我發現我的168開發版是8Mhz的crystal這樣燒16 Mhz的atmega8會有問題?
謝謝

coopermaa 提到...

你開發板 168 是 8MHz 的?
那在燒 ArduinoISP 的時候你選的是?

提到...

我的開發板是8MHz的
燒的時候是選 arduino NG or older w /Atmega8

coopermaa 提到...

現在看起來,一個可能原因是 ArduinoISP 沒有正常動作,另一個可能原因是全新的晶片必須先設定 Fuses

你 168 是 8 MHz,可是 "arduino NG or older w /Atmega8" 這個選項是 16 MHz的耶,這樣 ArduinoISP 燒到 168 後,也許程式不能正常動作。建議你給 168 也加個 16 MHz 的 crystal,然後重燒 ArduinoISP 試試。

提到...

如影片
http://www.youtube.com/watch?v=GMt4hLaKjAc&feature=related
已經可以燒錄囉。
但是,最近課業壓力比較重,我要把此事移到第一次段考後囉~
謝謝您近來提供資訊和幫我找到答案,非常感謝您唷~

coopermaa 提到...

你試成功了啊!
恭禧!恭禧!
後來有找到原因嗎?

哇塞!你還把操作過程拍成影片啊!?

不客氣,有空常來啊!

kevin 提到...

請問在燒錄過程中
出現以下
avrdude: stk500_getsync(): not in sync: resp=0x15

這該怎麼解決?!

上面說的增加電阻已經試過了還是沒辦法解決

coopermaa 提到...

請問你用的板子型號是多少?
你電阻是加在 reset pin 和 5v 之間對嗎?

kevin 提到...

我們是用Arduino Duemilanove ATMega328這塊版子 接ATMega8 然後reset pin 接110歐姆的電阻到 5V

coopermaa 提到...

這樣應該是對
不曉得是不是 ATmega8 的問題
BTW, 你是燒 ATmega8 的 bootloader 嗎?
因為 Arduino 內建沒有支援 ATmega8
所以你是上網下載 ATmega8 的 bootloader?

kevin 提到...

版主你好
我們是燒 ATmega8 的 bootloader
我有試過這個方法 但好像還是一樣耶
http://www.geek-workshop.com/thread-174-1-1.html

coopermaa 提到...

你是說你有試過 USBTinyISP 也是不行嗎?
那有沒有試過 AVR-Dragon?

kevin 提到...

謝謝版主 可是我沒有AVR-Dragon
我在試試別的方法好了