AVRマイコンのFUSEビットを書き換えてクロックアップ


『仮面ライダーカブト』(2006)(水嶋ヒロ 佐藤祐基 山本裕典)
仮面ライダーの中で一番好きです。佐藤祐基の方がメインかと思いきや、水嶋ヒロがいろいろかっさらっていきます。カブトのクロックアップ時の戦闘シーンが面白かったですね。ジェットコースターがゆっくり進む中、高所のレールの上で戦ったり、電車が直前まで迫ってきてるのに余裕かましていたり。

AVRマイコンでキャラクタLCDに時間を表示する(その1)」で作ったなんちゃって時計ですが、内部クロックをクロックアップすると、時間は早く進むのでしょうか。
確認してみます。

クロックアップの仕方ですが、ATtiny2313は、初期状態で1MHzのクロックとなっており、FUSE書き換えで8MHzにクロックアップすることができます。FUSEはavrdudeを使えば簡単に書き換えできます。

# avrdude -p t2313 -c linuxgpio -U lfuse:w:0xE4:m

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x1e910a
avrdude: reading input file "0xE4"
avrdude: writing lfuse (1 bytes):

Writing | ################################################## | 100% 0.01s

avrdude: 1 bytes of lfuse written
avrdude: verifying lfuse memory against 0xE4:
avrdude: load data lfuse data from input file 0xE4:
avrdude: input file 0xE4 contains 1 bytes
avrdude: reading on-chip lfuse data:

Reading | ################################################## | 100% 0.00s

avrdude: verifying ...
avrdude: 1 bytes of lfuse verified

avrdude: safemode: Fuses OK (E:FF, H:DF, L:E4)

avrdude done.  Thank you.

# 

これで8MHzで動作するようになりましたので、時計を動かしてみましょう。
clock-up-001
おっと、キャラクタLCDが文字化けしています。おそらくクロックアップは上手くいったのでしょう。クロックアップしたため、初期化等の待ち時間が足りなくなったということだと思います。

これは、もちろん、ビルドするときの、-DF_CPU=1000000ULオプションを2000000ULに変更すれば、上手くいくようになりますが、やりたいことは、クロックアップして、時計が早く進むことの確認なので、このオプションは変更せずに動作確認しようと思います。代わりにLCDの初期化の待ちに使用している_delay_us()や_delay_ms()の数値をことごとく8倍にしてみます。

まずは、delayを使用している箇所をgrepしてみます。

root@raspberrypi:~/bread/mcu/avr/attiny2313/device/clock# grep delay hello.c
#include <util/delay.h>
				_delay_us(1);		\
				_delay_us(1);		\
				_delay_us(1);		\
				_delay_us(1);		\
				_delay_us(40);		\
				_delay_us(1);		\
				_delay_us(1);		\
				_delay_us(40);		\
				_delay_us(1);			\
				_delay_us(1);			\
				_delay_us(40);			\
			_delay_us(1);				\
			_delay_us(1);				\
			_delay_us(1);				\
			_delay_us(1);				\
			_delay_us(40);				\
	_delay_us(40);		//more than 40us
	_delay_ms(2);		//more than 1.52ms
	_delay_us(40);		//more than 38us
	_delay_us(40);		//more than 38us
	_delay_ms(100);
	_delay_ms(41);
	_delay_ms(5);
	_delay_us(100);
	_delay_ms(2);			//more than 1.52ms
		_delay_ms(2);
		_delay_ms(998);
root@raspberrypi:~/bread/mcu/avr/attiny2313/device/clock# 

たくさんありますが、8倍の数値への置換は、一行perlで一発ですね。ただし、最後の998だけは、LCDに対する待ち時間ではないので、そのまま残します。

置換します。

# perl -pe 's/(delay.*)\((\d+)\)/sprintf("%s(%d)",$1,$2 * 8)/e unless/998/' -i hello.c
# 

置換できたか再度grepしてみましょう。

# grep delay hello.c#include <util/delay.h>
				_delay_us(8);		\
				_delay_us(8);		\
				_delay_us(8);		\
				_delay_us(8);		\
				_delay_us(320);		\
				_delay_us(8);		\
				_delay_us(8);		\
				_delay_us(320);		\
				_delay_us(8);			\
				_delay_us(8);			\
				_delay_us(320);			\
			_delay_us(8);				\
			_delay_us(8);				\
			_delay_us(8);				\
			_delay_us(8);				\
			_delay_us(320);				\
	_delay_us(320);		//more than 40us
	_delay_ms(16);		//more than 1.52ms
	_delay_us(320);		//more than 38us
	_delay_us(320);		//more than 38us
	_delay_ms(800);
	_delay_ms(328);
	_delay_ms(40);
	_delay_us(800);
	_delay_ms(16);			//more than 1.52ms
		_delay_ms(16);
		_delay_ms(998);
# 

最後の998以外は8倍になっているようです。これで時計も動くと思います。

確認しましょう。
clock-up-002
ストップウォッチの時間が1:58の時に、15:48なので、ほぼ8倍進んでますね。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA