続-ガイガカウンタ・簡易モニタリングポスト製作日記(3)

この様な流れでしょうか


ハードの方はめどがたちましたが、さて問題はソフトです。全ての処理を1つのマイクロコントローラに任せるプログラムを書くのは相当高度なテクニックが必要そうですが、今回は豪華に2つ使うことにしました。まるで大名のような贅沢ですね。いや、ひょっとするとそれ以上かもしれません。放射線のカウント、表示の処理は「ちびでぃ~の2」にまかせて、もう一つはパルス発生だけに専念します。これなら初心者の私でも何とかなりそうです。

e-電子工房さんのサイトを見ると400Vの場合、1KHzの周期でパルス幅が大体62n秒であれば良いことがわかります。まったくもって貴重な情報を公開していただき本当にありがとうございます。今回はアッセンブラでプログラムを作り、秋月電子通商から仕入れた新品のATmega168Pへ書き込みます。

当然のことながらAVRのアッセンブラも初めて触る私です。Nの電子講座・AVRマイコン編AVRマイコンで学ぶ コンピュータの仕組みのサイトに詳しく記述されていましたので勉強させていただきました。ありがとうございました。今回は特に小山さんが書かれた「AVRマイコンで学ぶ コンピュータの仕組み」から、ソフトウエアタイマー “blink.asm”の項を参考にプログラムを組ませていただきました。本当にお世話になりました。

フローを考えると次のようになります

スタート–>初期設定–>①–>1を出力する–>62μS待つ–>0を出力する–>938μS待つ–>①へジャンプ

前述のBlink.asmを参考にコードを書いていきます。特に変える必要もなさそうなので、出力ポートも同じPB3にさせていただきました。

GeigerClock.asm

 .include "m168Pdef.inc"
 .cseg
	LDI	R16,0b00001000
	OUT	DDRB,R16		;PB3は出力,他は入力

	LDI	 R16,HIGH(RAMEND)	;RAM最終アドレス上位を取得
    	OUT	 SPH,R16		;スタック ポインタ上位を初期化
	LDI	 R16,LOW(RAMEND)	;RAM最終アドレス下位を取得
    	OUT	 SPL,R16		;スタック ポインタ下位を初期化

LOOP:
	LDI	R16,0b00001000
	OUT	PORTB,R16		;PB3は1, 他は0

	RCALL	T62us			;62μ秒待つ

	LDI	R16,0b00000000
	OUT	PORTB,R16		;PB3は0, 他も0

	RCALL	T938uS			;938μ秒待つ

	RJMP	LOOP			;LOOPの箇所にジャンプ

62μSと938μS待機するサブルーチンを作成します。ATMEGA168Pを8MHzのクロックで動作させて1クロックサイクル=0.125μSで計算します。62μSは50μs+12μSで、938μSは50μSを18回繰り返し、さらに+38μSとすれば大体良さそうです。コメントに書いてある数値、計算は参考にさせて頂いた「AVRマイコンで学ぶ コンピュータの仕組み」サイト中に丁寧な説明があります。


; timer subroutine
T50US:			;((3)+1+5*78-1+4)*0.125=397*0.125=49.625μ秒
	LDI	R20,78	;1 以下を78回繰り返す
_TUS:
	NOP		;1
	NOP		;1
	DEC	R20	;1 R20から1を減じ
	BRNE	_TUS	;1/2 結果が0でなければ_TUSへ
	RET		;4

T62us:			;((3)+397+1+8*12-1+4)*0.125=500*0.125=62.5μ秒
	RCALL	T50US	;397
	LDI	R21,12	;1 以下を12回繰り返す
_T12US:
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	DEC	R21	;1 R21から1を減じ
	BRNE	_T12US	;1/2 結果が0でなければ_T12USへ
	RET		;4

T938us:			;((3)+1+400*18-1+1+8*38-1+4)*0.125=7510*0.125=938.875μ秒
	LDI	R21,18	;1 以下を18回繰り返す
_T900US:
	RCALL	T50US	;397
	DEC R21		;1
	BRNE	_T900US	;1/2 結果が0でなければ_T900USへ

	LDI	R21,38	;1 以下を38回繰り返す
_T38US:
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	NOP		;1
	DEC	R21	;1 R21から1を減じ
	BRNE	_T38US	;1/2 結果が0でなければ_T38USへ
	RET		;4

うまく動くでしょうか????