今回はタイマー割り込み(タイマ0)を使用して、LEDの点滅を行ってみたいと思います。

タイマ0関連で使用するレジスターは次のとおりです。

・ステータスレジスター (SREG)
・タイマ/カウンタ0 制御レジスタ (TCCR0)
・タイマ/カウンタ0 カウンタ (TCNT0)
・タイマ/カウンタ割り込み許可レジスタ (TIMSK)
・タイマ/カウンタ割り込み要求フラグレジスタ (TIFR)

最初にステータスレジスターのbit7(I)の全割り込み許可を行います。

		ldi	r16,	0x80		;Global Interrupt Enable
		out	SREG,	r16

タイマ/カウンタ0 制御レジスタでタイマ/カウンタ0に与えるクロックを選択します。
今回は、CPUクロックを1024分周したクロックを与えました。
CPUクロックは8MHzなので、8MHz/1024で約128uSとなります。

		ldi	r16,	0x05		;Timer CK/1024 set(8MHz/1024=128uS)
		out	TCCR0,	r16

タイマ/カウンタ0 カウンタでは、約10mSの時間稼ぎしたいのでタイマ/カウンタ0 カウンタ値は78(0x4e)となりました。(128uS*78=10mS)

		ldi	r16,	0x4e		;10mS Timer 0 set(128uS*78=10ms)
		out	TCNT0,	r16

タイマ/カウンタ割り込み許可レジスタのbit1(TOIE0)でタイマ/カウンタ0溢れ割り込み許可を設定します。

		ldi	r16,	0x02		;Timer/Counter0 Overflow Interrupt Enable
		out	TIMSK,	r16

タイマ/カウンタ割り込み要求フラグレジスタのbit1(TOV0)でタイマ/カウンタ0溢れ割り込み要求フラグを設定します。タイマ/カウンタ0溢れ割り込み許可及びタイマ/カウンタ0溢れ割り込み要求フラグが設定されると該当の割り込みが発生します。ここではタイマ0を使用しているので、タイマ/カウンタ0の溢れ割り込みが発生ます。

		ldi	r16,	0x02		;Timer/Counter0 Overflow Interrupt Flag
		out 	TIFR,	r16

		rjmp	reset			;reset
		reti				;INT0
		reti				;INT1
		reti				;Timer/Counter1 CAPT1
		reti				;Timer/Counter1 COMP1
		reti				;Timer/Counter1 OVF1
		rjmp	Timer0			;Timer/Counter0 OVF0
		reti				;UART RX
		reti				;UART UDRE
		reti				;UART TX
		reti				;Analog Comparator ANA_COMP

タイマ0の割り込みルーチンでは、10mSをカウントするレジスタr17を減算します。
(初期値10 100mS=10mS*10)

r17が0になったら、再度r17を初期化したのち、PB2に出力します。
再度、タイマ/カウンタ割り込み要求フラグレジスタを設定したのちリターンします。

Timer0:
		dec	r17	
		breq	Timer0_0
		reti
Timer0_0:
		ldi	r17,	0d10
		
		in	r16,	PINB
		eor	r16,	r18
		out	PORTB,	r16
		
		ldi	r16,	0x02		;Timer/Counter0 Overflow Interrupt Flag
		out TIFR,	r16
		reti	

全体のプログラムは下記の通りです。

;AT90S2313 LED Flashing (Exclusive OR and interrupt mode)
;
        ;; AT90S2313 cpu
        ;; rom 0000h -- 03ffh
        ;; ram 0000h -- 00dfh
        ;; eeprom 0000h -- 007fh
        ;; External clock 8MHz
        ;;
        ;;
        ;; assemblers  ASxxxx and ASlink V5.40
        ;; file name 2313_led_flashing_eor_int.asm
        ;; $ asavr -l -s -o 2313_led_flashing_eor_int.asm
        ;; $ aslink -i 2313_led_flashing_eor_int
        ;; $ (sudo) avrdude -v  -p 2313 -c usbasp -P usb -F -e -U flash:w:2313_led_flashing_eor_int.ihx


;I/O regster
SREG    .equ    0x3f    ;Status Register
SPL     .equ    0x3d    ;Stack Pointer Low
GIMSK   .equ    0x3b    ;General Interrupt MaSK register
GIFR    .equ    0x3a    ;General Interrupt Flag register
TIMSK   .equ    0x39    ;Timer/Counter Interrupt MaSK register
TIFR    .equ    0x38    ;Timer/Counter Interrupt Flag register
MCUCR   .equ    0x35    ;MCU general Control Register
TCCR0   .equ    0x33    ;Timer/Counter 0 Control Register
TCNT0   .equ    0x32    ;Timer/CouNTer 0
TCCR1A  .equ    0x2f    ;Timer/Counter 1 Control Register A
TCCR1B  .equ    0x2e    ;Timer/Counter 1 Control Register B
TCNT1H  .equ    0x2d    ;Timer/CouNTer 1 High byte
TCNT1L  .equ    0x2c    ;Timer/CouNTer 1 Low byte
OCR1AH  .equ    0x2b    ;Output Compare Register 1 High byte
OCR1AL  .equ    0x2a    ;Output Compare Register 1 Low byte
ICR1H   .equ    0x25    ;T/C Input Capture Register High byte
ICR1L   .equ    0x24    ;T/C Input Capture Register Low byte
WDTCR   .equ    0x21    ;WatchDog Timer Control Register
EEAR    .equ    0x1e    ;EEPROM Address Register
EEDR    .equ    0x1d    ;EEPROM Data Register
EECR    .equ    0x1c    ;EEPROM Control Register
PORTB   .equ    0x18    ;Data Register, Port B
DDRB    .equ    0x17    ;Data Direction Register, Port B
PINB    .equ    0x16    ;Input Pins, Port B
PORTD   .equ    0x12    ;Data Register, Port D
DDRD    .equ    0x11    ;Data Direction Register, Port D
PIND    .equ    0x10    ;Input Pins, Port D
UDR     .equ    0x0c    ;UART Data Register
USR     .equ    0x0b    ;UART Status Register
UCR     .equ    0x0a    ;UART Control Register
UBRR    .equ    0x09    ;UART Baud Rate Register
ACSR    .equ    0x08    ;Analog Comparator Control and Status Register


RAM     .equ    0x60
RAMEND  .equ    0xdf

        .AT90S2313

                
start   :
        rjmp    reset           ;reset
        reti                ;INT0
        reti                ;INT1
        reti                ;Timer/Counter1 CAPT1
        reti                ;Timer/Counter1 COMP1
        reti                ;Timer/Counter1 OVF1
        rjmp    Timer0          ;Timer/Counter0 OVF0
        reti                ;UART RX
        reti                ;UART UDRE
        reti                ;UART TX
        reti                ;Analog Comparator ANA_COMP
        
reset:
        ldi r16,    RAMEND      ;Stack pointer setting
        out SPL,    r16
        
        ldi r16,    0x80        ;Global Interrupt Enable
        out SREG,   r16
        
        ldi r16,    0b00000100  ;PB2 output setting
        out DDRB,   r16
        
        
        ldi r16,    0x05        ;Timer CK/1024 set(8MHz/1024=128uS)
        out TCCR0,  r16
        
        ldi r16,    0x4e        ;10mS Timer 0 set(128uS*78=10ms)
        out TCNT0,  r16
        
        ldi r17,    0d10        ;100mS counter at 10ms*
        
        ldi r16,    0x02        ;Timer/Counter0 Overflow Interrupt Enable
        out TIMSK,  r16
        
        ldi r16,    0x02        ;Timer/Counter0 Overflow Interrupt Flag
        out     TIFR,   r16
        ldi r18,    0b00000100  ;eor reg
loop:
        rjmp    loop

Timer0:
        dec r17 
        breq    Timer0_0
        reti
Timer0_0:
        ldi r17,    0d10
        
        in  r16,    PINB
        eor r16,    r18
        out PORTB,  r16
        
        ldi r16,    0x02        ;Timer/Counter0 Overflow Interrupt Flag
        out TIFR,   r16
        reti    

        
        .end            

アセンブリします。

$ asavr -l -s -o 2313_led_flashing_eor_int.asm
$ aslink -i 2313_led_flashing_eor_int

ASlink >> -i
ASlink >> 2313_led_flashing_eor_int

AT90S2313に焼き付けます。

$ sudo avrdude -v  -p 2313 -c usbasp -P usb -F -e -U flash:w:2313_led_flashing_eor_int.ihx
[sudo] hogehoge のパスワード:

avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "/etc/avrdude.conf"
         User configuration file is "/root/.avrduderc"
         User configuration file does not exist or is not a regular file, skipping

         Using Port                    : usb
         Using Programmer              : usbasp
         AVR Part                      : AT90S2313
         Chip Erase delay              : 20000 us
         PAGEL                         : P00
         BS2                           : P00
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom         4    12    64    0 no        128    0      0  4000  9000 0x80 0x7f
           flash          4    12   128    0 no       2048    0      0  4000  9000 0x7f 0x7f
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           fuse           0     0     0    0 no          1    0      0     0     0 0x00 0x00
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00

         Programmer Type : usbasp
         Description     : USBasp, http://www.fischl.de/usbasp/

avrdude: auto set sck period (because given equals null)
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x1e9101 (probably 2313)
avrdude: safemode: Fuse reading not support by programmer.
              Safemode disabled.
avrdude: erasing chip
avrdude: auto set sck period (because given equals null)
avrdude: reading input file "2313_led_flashing_eor_int.ihx"
avrdude: input file 2313_led_flashing_eor_int.ihx auto detected as Intel Hex
avrdude: writing flash (76 bytes):

Writing | ################################################## | 100% 1.27s

avrdude: 76 bytes of flash written
avrdude: verifying flash memory against 2313_led_flashing_eor_int.ihx:
avrdude: load data flash data from input file 2313_led_flashing_eor_int.ihx:
avrdude: input file 2313_led_flashing_eor_int.ihx auto detected as Intel Hex
avrdude: input file 2313_led_flashing_eor_int.ihx contains 76 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.44s

avrdude: verifying ...
avrdude: 76 bytes of flash verified

avrdude: safemode: Sorry, reading back fuses was unreliable. I have given up and exited programming mode

avrdude done.  Thank you.

書き込みが終了すると、約100mS周期で点滅します。

おすすめの記事