# 用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下載模式,然後在下載模式出現錯誤時,切換成串列中繼模式。

文字編輯器的外部工具再修改如下:
```
{
"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)

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