どもどもー
![](./IMG_1127.JPG)ここ3日、ずっとAVRマイコンをAssemblyでプログラミングしていました。(きっと)
何となくわかってきたのでとりあえずメモ。
使用しているマイコンと回路図
調べてみたところ、Arduinoに任意のHEXが書き込めるようだったので、書き込み器付きマイコンボードとしてArduino Unoを使いました。
プログラマを持っていなかったので助かりました・・・
ちなみに載っているマイコンはATmega328Pです。
図のようにパーツを接続しました。
追加するパッケージ
avra
AVRマイコン(等)のアセンブラです。これを使って書いたコードをビルドします。
avrdude
AVRマイコンのプログラマソフトです。これでビルドしたプログラムの書き込みを行います。
2013/10/6 (Sun) 21:42:56追記
また、各マイコンのIncludeFileをこのサイトからダウンロードし、使うマイコンのファイルをソースと同じフォルダに配置します。
プログラム
この3日で書いていたプログラムを2つ上げておきます。
1.PB0に接続されたスイッチを押す(内部プルアップなので入力はLOW)とLEDが消える、離すと(入力はHIGH)再び点灯
.include "m328pdef.inc"
; Interrupt Vectors
.ORG 0x0000
RJMP RESET
; Reset Pin and Timer
RESET:
CLI ; Disable All Interruputs
; Port Config
LDI R25, 0b11111110 ; PB0 is Input, Others are Output
OUT DDRB, R25
LDI R25, 0b00000001 ; Output HIGH to PORTB
OUT PORTB, R25
RJMP MAIN
; Main Loop
MAIN:
SBIS PINB, 0 ; If PB0 is Low,
RJMP RESET ; LED Turn Off
LDI R25, 0xFF ; Else, Led Turn On
OUT PORTB, R25
RJMP MAIN
2.LED点滅(タイマ1使用)
.include "m328pdef.inc"
; Named General Purpose Register
.DEF TMP1 = R25
.DEF TMP2 = R24
.DEF STACK = R23
; Interrupt Vectors
.ORG 0x0000 ; RESET
RJMP RESET
.ORG 0x001A ; TIMER1 OVF
RJMP INT
; Interrupt Routine
INT:
IN STACK, SREG ; Backup Status Register
LDI TMP1, 0x00 ; Stop Timer1
STS TCCR1B, TMP1
IN TMP1, PORTB ; Invert the Value of PORTB
LDI TMP2, 0b11111110
EOR TMP1, TMP2
OUT PORTB, TMP1
LDI TMP1, 0x0000 ; Set Timer1 Counter and Restart
STS TCCR1A, TMP1
LDI TMP1, 0x05
STS TCCR1B, TMP1
LDI TMP1, 0xC2
STS TCNT1H, TMP1
LDI TMP1, 0xF7
STS TCNT1L, TMP1
OUT SREG, STACK ; Restore Status Register
RETI ; Interrupt End
; Reset Pin and Timer
RESET:
CLI ; Disable All Interruputs
; Port Config
LDI TMP1, 0b11111110 ; PB0 is Input, Others are Output
OUT DDRB, TMP1
LDI TMP2, 0xFF ; Output HIGH to PORTB
OUT PORTB, TMP2
; Timer1 Config
LDI TMP1, 0x00 ; Nomal Mode
STS TCCR1A, TMP1
LDI TMP1, 0x05 ; Prescaler:1024
STS TCCR1B, TMP1
LDI TMP1, 0xC2 ; Interrupt Time:1sec
STS TCNT1H, TMP1
LDI TMP1, 0xF7
STS TCNT1L, TMP1
LDS TMP1, TIMSK1 ; Enable Timer1 Overflow Interrupt
SBR TMP1, (1<<TOIE1)
STS TIMSK1, TMP1
SEI ; Enable All Interruputs
RJMP MAIN
; Main Loop
MAIN:
RJMP MAIN
ビルド及び書き込み
// ビルド
$ avra FileName.asm
// ArduinoにHEXを書き込み(Arduinoの接続先が/dev/ttyACM0とする)
$ avrdude -c arduino -P /dev/ttyACM0 -p m328p -b 115200 -u -e -U flash:w:"FileName.hex":a
これで書き込めます。
実際にLED点滅プログラムを動かしてみたところです。(何気にFullHD)
Arch LinuxでArduinoが認識されない時
僕の環境でもそうでしたが、一般ユーザーで/dev/ttyACM0にアクセスができませんでした。
しかし、次の方法で解決出来ました。
$ sudo gpasswd -a YourUserName uucp
$ sudo stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts
$ sudo chown root:wheel /run/lock
$ sudo chmod 775 /run/lock
参考
Greyed Serial Port Menu in Arduino IDE on Arch Linux | Stray Bytes
いやぁ〜、AVR-Assemblyヤバイです。
わかりやすいし美しい。PICとかいうクソマイコンとは大違いです。
これから書く予定のステッピングモータ制御プログラム、全部Assemblyで書こうかな・・・
ではでは〜