AT90S2313のLEDの点滅を試したいと思います。

まずは回路図は下記のようになっています。
USBaspのSCKは書き込みが不安定になったので、10Kでプルダウンしました。

LEDを点滅する方法として、ウェイトループで時間稼ぎする方法とタイマー0による割り込みの方法の2点で試みてみました。

まずは、 ウェイトループで時間稼ぎする方法 ですが、8MHzクロックで、約100uSのwaitloopを作成します。

wait100us:	push	r17
		ldi	r17,0d159
wait_loop:
		nop
		nop
		dec	r17
		brne	wait_loop
		pop	r17
		ret

このループをもとに、約100msのループを作成します。

wait100ms:
		push	r17
		ldi	r17,0d100
wait100msloop:
		rcall	wait1ms
		dec	r17
		brne	wait100msloop
		pop	r17
		ret	


wait1ms:
		rcall	wait500us
		rcall	wait500us
		ret

wait500us:	push	r17
		ldi	r17,0d5
wait500loop:
		rcall	wait100us
		dec	r17
		brne	wait500loop
		pop	r17
		ret

PB2に接続したLEDは、XOR(eXcluslve OR:排他的論理和)を使用したトグル動作としました。
入力A 入力B 出力X
 0   0  0
 0   1  1
 1   0  1
 1   1  0

入力Aを1に固定すると、入力B0→出力1、入力B1→出力0のトグル動作となります。
XORのAVR命令は、eor命令となります。

loop:

		rcall	wait1s
		in	r16,	PINB
		eor	r16,	0b00000100	;PB2 xor output
		out	PORTB,	r16
		rjmp	loop

次にタイマー0を使用した割り込み方法のLED点滅は下記のように試しました。

TCCR0を システムクロック/1024に設定します。これにより128uSの周期になります。
TCNT0は、10mSを作り出すのに、78(0x4e)に設定します。(128uS*78=約10mS)
R17には、500mSを作成するために、10mSごとの割り込みで50までカウントします
これで、10mS*50=500mSを作成します。

TIMSKでタイマー0の割り込みを許可します。
TIFRでタイマー0の割り込みフラグを立てます。

		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,	0d50		;100mS counter at 10ms*
		
		ldi	r16,	0x03		;Timer/Counter0 Overflow Interrupt Enable
		out	TIMSK,	r16
		
		ldi	r16,	0x02		;Timer/Counter0 Overflow Interrupt Flag
		out TIFR,	r16
loop:
		rjmp	loop

タイマー0の割り込みでは、r17が50→0になるまでカウントダウンします。
r17が0になったら、R17に50の初期値を設定し、PB2をトグル動作します。
TIFRでタイマー0の割り込みフラグを立てたのち割り込みを終了します。

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

プログラムソースは下記のとおりです。

ウェイトループで時間稼ぎする方法

;AT90S2313 LED tennmetu 1 
;
       	;; AT90S2313 cpu
        ;; rom 0000h -- 03ffh
		;; ram 0000h -- 00dfh
		;; eeprom 0000h -- 007fh
        ;; External clock 8MHz
        ;;
        ;;
        ;; assemblers  ASxxxx and ASlink V5.40
        ;; file name 2313_led_pulse_xor.asm
        ;; $ asavr -l -s -o 2313_led_pulse_xor.asm
        ;; $ aslink -i 2313_led_pulse_xor
        ;; $ (sudo) avrdude -v  -p 2313 -c usbasp -P usb -F -e -U flash:w:2313_led_pulse_xor.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
		reti				;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,	0b00000100	;PB2 output setting
		out	DDRB,	r16
		
		ldi	r16,	0b00000100	;PB2 high level outpit
		out	PORTB,	r16
loop:

		rcall	wait1s
		in	r16,	PINB
		eor	r16,	0b00000100	;PB2 xor outpit
		out	PORTB,	r16
		rjmp	loop

wait1s:
		push	r17
		ldi	r17,0d10
wait1sloop:
		rcall	wait100ms
		dec	r17
		brne	wait1sloop
		pop	r17
		ret	

wait100ms:
		push	r17
		ldi	r17,0d100
wait100msloop:
		rcall	wait1ms
		dec	r17
		brne	wait100msloop
		pop	r17
		ret	


wait1ms:
		rcall	wait500us
		rcall	wait500us
		ret

wait500us:	push	r17
		ldi	r17,0d5
wait500loop:
		rcall	wait100us
		dec	r17
		brne	wait500loop
		pop	r17
		ret

wait100us:	push	r17
		ldi	r17,0d159
wait_loop:
		nop
		nop
		dec	r17
		brne	wait_loop
		pop	r17
		ret
		
		.end			

タイマー0を使用した割り込み

;AT90S2313 LED tennmetu 2 
;
       	;; AT90S2313 cpu
        ;; rom 0000h -- 03ffh
		;; ram 0000h -- 00dfh
		;; eeprom 0000h -- 007fh
        ;; External clock 8MHz
        ;;
        ;;
        ;; assemblers  ASxxxx and ASlink V5.40
        ;; file name 2313_led_pulse_int.asm
        ;; $ asavr -l -s -o 2313_led_pulse_int.asm
        ;; $ aslink -i 2313_led_pulse_int
        ;; $ (sudo) avrdude -v  -p 2313 -c usbasp -P usb -F -e -U flash:w:2313_led_pulse_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,	0d50		;100mS counter at 10ms*
		
		ldi	r16,	0x03		;Timer/Counter0 Overflow Interrupt Enable
		out	TIMSK,	r16
		
		ldi	r16,	0x02		;Timer/Counter0 Overflow Interrupt Flag
		out TIFR,	r16
loop:
		rjmp	loop

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

		
		.end			


おすすめの記事