LoginSignup
3
1

More than 5 years have passed since last update.

ATTiny13でアセンブラ

Last updated at Posted at 2017-09-08

ちょっとわけあって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で開発するのが良い気もします。

3
1
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1