ちょっとわけあってATTiny13でavr-asを使ってみました。ネットで見つかったコードを参考にしました。
.equ DDRB, 0x17
.equ PORTB, 0x18
.equ WDTCR, 0x21
.equ LED, 2
.org 0x0000
rjmp reset
reset:
ldi R16, 0x00
out WDTCR, R16
sbi DDRB, LED
loop:
sbi PORTB, LED
rcall delay
cbi PORTB, LED
rcall delay
rjmp loop
delay:
ldi R17, 8
delay1s:
ldi R18, 250
delay250ms:
ldi R19, 250
delay1ms:
nop
dec R19
brne delay1ms
dec R18
brne delay250ms
dec R17
brne delay1s
ret
スタックポインターはリセット時に初期化されているようなので、設定していません。
必要なequはAVR Studioのcpu毎のincファイルからコピペします。
Makefileはこんな感じです。
AVRBIN=/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin
test:
$(AVRBIN)/avr-as -mmcu=attiny13 -o test.o test.s
$(AVRBIN)/avr-ld test.o -o test.elf
$(AVRBIN)/avr-objcopy -j .text -j .data -O ihex test.elf test.hex
Timer0の割り込みを使うとこんな感じになります。
.equ DDRB, 0x17
.equ PORTB, 0x18
.equ WDTCR, 0x21
.equ TCCR0B, 0x33
.equ TIMSK0, 0x39
.equ LED, 2
.org 0x0000
rjmp reset ; RESET
.org 0x0006
rjmp timer ; TIM0_OVF
timer:
inc R17
cpi R17, 0x00
brne next
cbi PORTB, LED
reti
next:
cpi R17, 0x80
brne end
sbi PORTB, LED
end:
reti
reset:
ldi R16, 0x02
out TCCR0B, R16
ldi R16, 0x02
out TIMSK0, R16
sbi DDRB, LED
sbi PORTB, LED
ldi R17, 0x00
sei
loop:
rjmp loop
ちなみに割り込みをCで書くとこんな感じです。
#include <avr/io.h>
#include <avr/interrupt.h>
int count;
ISR(TIM0_OVF_vect)
{
++count;
if(count == 0x80) {
PORTB ^= (1<<PB2);
count = 0;
}
}
void init_timer()
{
TCCR0A = 0; // normal mode
TCCR0B = (1<<CS01); // prescaler = 2
TIMSK0 |= (1<<TOIE0);
//TCNT0 = 0;
}
int main()
{
DDRB =(1<<PB2);
init_timer();
count = 0;
sei(); // enable global interrupts
while(1) {
}
}
オブジェクトのサイズはこのようになりました。
text data bss dec hex filename
44 0 0 44 2c timer_asm.elf
186 0 2 188 bc timer_c.elf
なにか理由がなければ、デバッグが骨なので、ATTiny25とかでCで開発するのが良い気もします。