# 用arduinoasisp玩at89s51 ###### tags: `專題` `8051` 小裝置c語言編譯器(SDCC) https://petervanhoyweghen.wordpress.com/tag/sdcc/ ```shell= brew install sdcc brew install avrdude ``` avrdude需要89s52的conf 這裡有 https://www.instructables.com/Program-8051-With-Arduino/ 本來用gedit作為ide 但是在mac上一下子找不到等寬字 一下子在m1無法執行 後來改用sublime文字編輯器 他可以執行外部工具 他稱作build package 是以shell script方式呼叫外部工具 ``` { "shell_cmd": "sdcc --verbose \"$file\" && avrdude -C./avrdude.conf -v -p89s52 -cstk500v1 -P/dev/cu.usbmodem21401 -b19200 -Uflash:w:./\"$file_base_name\".ihx" } ``` 這樣就可以按下cmd-B(ctrl-B)進行編譯與上傳 但是對於usb port的設定還沒有找到選單選擇方法 目前要靠手動進去檔案填寫 改用find指令找出usbmodem(mac os看到的arduino com port)這樣可以暫時自動找到com port 利用以下指令作到自動尋找目前連線的USB ISP裝置(ISP是以虛擬串列埠形式存在) ``` find /dev -name \"cu.usbmodem*\"` ``` ``` { "shell_cmd": "sdcc --verbose \"$file\" && avrdude -C./avrdude.conf -v -p89s52 -cstk500v1 -P`find /dev -name \"cu.usbmodem*\"` -b19200 -Uflash:w:./\"$file_base_name\".ihx" } ``` 如何讓arduinoasisp與serial port共存? https://forum.arduino.cc/t/arduinoisp-sketch-serial-passthrough/541128 後來改用外置開關切換兩種功能: 燒錄 與 傳遞串列埠 並使用softwareSerial另用2,3腳做rx,tx 外部開關同時會開關SoftwareSerial避免燒錄51時的異常 發現用32u4做arduinoISP的上傳速度,比用328P的來得快 原來原來 藉由觀察arduino ide的log發現 arduino leonardo(32u4)的做法: 他會在上傳之前先強制用1200bps開關comport一次 之樣會令leonardo重置 也就可以實現不用手動切換狀態的方式 網上有個方法可以執行上述動作 ``` stty -f `find /dev -name "cu.usbmodem*"` ispeed 1200 ospeed 1200 ``` 自動切換「上傳程式」與「串列埠中繼」功能,完成!! 果然還是觀察arduino目前的功能而來。arduino leonardo(32u4)有一個特殊功能,在上傳前會用1200bps開啟與關閉arduino的串列埠用來重置arduino,因此,我就利用這個重置行為來執行「8051程式上傳」與「串列埠中繼功能」的切換❤️ 這部分的原理是 32u4系列的arduino因為mcu本身自帶usb介面,所以32u4是把bootloader放在自己身上,但是這樣會有usb介面究竟是用來上傳程式還是作為串列埠中繼這樣的問題,因此32u4內的bootloader設計為,當收到usb virtual com port開啟為1200 bps並且馬上關掉,此時bootloader就會切換成ISP接收模式,準備接收來自電腦的程式資料,並且燒錄進去目標mcu中,也就是32u4自身的arduino程式區域,最後跳往arudino程式區域執行。這個時候對於內部的arduino程式來說,就會重新執行。而我們51的ISP就可以藉此重置狀態,也會先切換成51 ISP下載模式,然後在下載模式出現錯誤時,切換成串列中繼模式。 ![arduino as 51 ISP原理圖](https://i.imgur.com/0Ndfzpl.png) 文字編輯器的外部工具再修改如下: ``` { "shell_cmd": "echo \"\nsdcc $file\n\" && sdcc --verbose \"$file\" && echo \"\nwaiting for arudinoISP\n\" && stty -f `find /dev -name \"cu.usbmodem*\"` ispeed 1200 ospeed 1200 && sleep 9 && avrdude -C./avrdude.conf -v -p89s52 -cstk500v1 -P`find /dev -name \"cu.usbmodem*\"` -b19200 -Uflash:w:./\"$file_base_name\".ihx" } ``` ArduinoISP的修改差異 ``` 43,47d42 < < #define mySerial1 Serial1 // for 32u4 < < < 79,84c74,76 < // #define LED_HB 9 < // #define LED_ERR 8 < // #define LED_PMODE 7 < #define LED_HB 13 < #define LED_ERR 13 < #define LED_PMODE 13 --- > #define LED_HB 9 > #define LED_ERR 8 > #define LED_PMODE 7 232,233d223 < long waiting_timer = 0; < 237,244c227,233 < // pinMode(LED_PMODE, OUTPUT); < // pulse(LED_PMODE, 2); < // pinMode(LED_ERR, OUTPUT); < // pulse(LED_ERR, 2); < // pinMode(LED_HB, OUTPUT); < // pulse(LED_HB, 2); < < waiting_timer = millis(); --- > pinMode(LED_PMODE, OUTPUT); > pulse(LED_PMODE, 2); > pinMode(LED_ERR, OUTPUT); > pulse(LED_ERR, 2); > pinMode(LED_HB, OUTPUT); > pulse(LED_HB, 2); > 299,300d287 < int now_state = HIGH; < 302,310d288 < < if(now_state == HIGH) { < if(millis() - waiting_timer > 3000) { < now_state = LOW; < mySerial1.begin(4800); < } < } < < if(now_state == HIGH) { 327d304 < waiting_timer = millis(); 330,335d306 < }else{ < if (mySerial1.available()) < SERIAL.write(mySerial1.read()); < if (SERIAL.available()) < mySerial1.write(SERIAL.read()); < } ``` 它或許可以與arduino整合在一起,設計個「開發板管理員」,但我不想這麼做。由於硬體能力,它或許永遠不能執行arduino現有的函式庫。 於是,我想另外開發它的IDE。架構大概是這樣:一個帶有文法著色的文字編輯器,一個負責呼叫外部工具的按鈕,一個串列埠文字視窗,一個串列埠繪圖視窗。 某個串列埠繪圖家 https://github.com/swharden/SeriPlot 20210913 完成初步IDE 目標: 使用對象為初學者 讓第一次寫程式與上傳的過程降到最低 因此沒有選項功能,一切都是預設設定 功能: 以文字編輯器為主軸 視窗分上下兩區 上面是程式碼帶著色功能與列號 下面是執行外部工具的輸出 外部工具有 sdcc: c編譯器 stty: 負責開關通訊埠於1200bps avrdude: 負責與ISP溝通上傳程式 一個串列埠監視視窗(目前找現成python) ![](https://i.imgur.com/0KfoVje.png) 20210924 在windows10上,avrdude無法透過32u4上傳,會報programmer is not responding 以及 stk500_getsync() attempt 1 of 10: not in sync: resp=0x03 的錯誤。 經過觀察arduinoIDE呼叫32u4 arduinoasisp的時候會另外指定programmer 原本是stk500v1 32u4會改成arduino 目前還不知道差異點 但是這方法在mac上面是可以動的 https://github.com/per1234/ATmega32U4asISP 這裡似乎是arduino IDE中arduinoasisp(32u4)的由來 當年相關的issue: https://github.com/arduino/Arduino/issues/1182 https://forum.arduino.cc/t/programming-with-arduinoisp-from-arduino-ide/593879/2 這裡在討論stk500v1 protocol與arduino protocol https://www.avrfreaks.net/forum/writing-at89s52-through-usbasp 這裡在討論89s52燒不進去 整理上面所述 windows的uart驅動,跟leonardo的usb CDC連接時 ,leonardo會因為windows沒有觸動DTR,導致leonardo不會送出封包,但是leonardo確認會收。 https://forum.arduino.cc/t/program-89s52-with-an-arduino/72247 這篇敘述了如何用arduinoasisp燒錄89s52 https://forum.arduino.cc/t/programming-the-at89lp-series-with-an-arduino/405684 這篇提到at89lp 20210927 目前將stk500v1協定寫進去程式裡面 但暫時只能用於89s52 ## 51BASIC 設計一款類似APPLE II 的BASIC ```BASIC 10 PRINT "HELLO" 20 A=A+1 30 B = B + 1 40 PRINT A 50 FOR I=0 TO 10 60 PRINT A+I 70 NEXT I ``` 用這個例子作為測試 ## 參考資料 mcs51 http://web.mit.edu/6.115/www/document/8051.pdf sdcc http://sdcc.sourceforge.net/doc/sdccman.pdf atmel 8051 hardware manual https://ww1.microchip.com/downloads/en/DeviceDoc/doc4316.pdf atmel 8051 instrution set https://www.keil.com/dd/docs/datashts/atmel/at_c51ism.pdf atmel 89s52 https://www.microchip.com/en-us/product/AT89S52