PIC16F84電子遊戯(31)
最終更新日:2001年7月12日
乾電池チェッカー(1ページ)へ (2ページ)

乾電池チェッカーのA/D変換値の表示データへの変換
さて読み込んだA/D変換値は基準電圧が5Vのため下記のようになります。
5V 4V 3V 2V 1V 0V

255

204

153

102

51

0

ここでこのデータをどう料理するか考えましょう。
乾電池の電圧を測定することを考えると、0.1V刻み程度の分解能があれば充分です。
そこでこのA/D変換値を5で割ることにしましょう。
5V 4V 3V 2V 1V 0V

51

40

30

20

10

0

(整数しか扱えませんので小数点以下は切り捨てています。)
さてこれでどうなったでしょうか。丁度0.1Vが1カウントに対応出来るようになりました。
このデータを用いてLEDを表示することにしましょう。
ところでPICでは「5で割る」という計算は簡単には出来ません。
私は変換値から5が何回引けるかで算出しています。(詳しくはソースを見て下さい。)
簡単に表示データへの変換の概要を示します。
A/D変換値を演算エリアにコピーする
計算エリアをクリアする
演算エリア値を5で割った商を求める計算エリアに入れる
計算エリアを基に赤色LED表示用データを読み出しコピーする
計算エリアを基に緑色LED表示用データを読み出しコピーする
データ計算用のRAMを用意しています。
sub2_data
計算エリア
割り算(減算の繰り返し)に使用する値もデータとして定義しておきます。
data1
5H
乾電池チェッカーのLED表示
では計算したデータをどのように表示するか考えましょう。
せっかく2色LEDを使用しているのですから、3色(緑、橙、赤)を最大限駆使して表示を考えます。
どうでしょうか、上図のようにデザインしてみました。
ポイントは乾電池が正常に使える電圧を1.4Vとした点です。
これ以上の電圧は緑色のLED表示にしましょう。
乾電池がへたり出す電圧を1.2〜1.3Vとしてここを橙色のLED表示にします。
それ以下は赤色LEDで表示しますが、何Vかわかるように電圧に応じてLEDの点灯の数を変えています。
0.8Vで赤色LEDがひとつ点灯します。赤色が全灯したときは0Vの時とします。
さて1.5V以上も測りたいと思ったので(実際にそのようなことがあるかわかりませんが)1.6V以上のときは表示をフローティング状態にして全体表示が下へ移動するようにしてみました。
そうすることによって上図のように2.1Vまで測定することが出来ます。
どうせ5Vまで測れるのですから、この辺は皆さんで考えてみてください。
(2.1V以上のときは全て緑色LEDの点灯となります。)
乾電池チェッカーの全ソースリスト公開
乾電池チェッカーのソースリストです。皆さんで自由に改造して下さい。
;**********************************************************************
;    Filename:	    denchi.asm                                       *
;    Date:          2001/7/1                                        *
;    File Version:                                                    *
;**********************************************************************

	list      p=16F84             ; list directive to define processor
	#include <p16F84.inc>         ; processor specific variable definitions

	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

;***** VARIABLE DEFINITIONS
w_temp        EQU     0x0C        ; variable used for context saving 
status_temp   EQU     0x0D        ; variable used for context saving

wait_data		EQU	0x10		;wait data
adsub_data	EQU	0x11		;ad keisanyou ram

taihi		EQU	0x13		;taihi data
adin_data		EQU	0x14		;ad input data ram
count_data	EQU	0x15		;0.1sec keisoku count ram

sub2_data		EQU	0x17		;keisan data ram

led_red_data	EQU	0x20		;LED RED hyouji
led_green_data	EQU	0x21		;LED GREEN hyouji

tm0_setdata	EQU	63h		;255-156=99=63H  156*128=19.968msec
cnt_setdata	EQU	5h		;19.968*5=99.84msec
data1		EQU	5h		;henkanyou data

;**********************************************************************
		ORG     0x000             ; processor reset vector
  		goto    main              ; go to beginning of program

;----------------------------------------------------------------------------------
		ORG     0x004             ; interrupt vector location
		movwf   w_temp            ; save off current W register contents
		movf	STATUS,w          ; move status register into W register
		movwf	status_temp       ; save off contents of STATUS register

		;---------------------------------	
		bcf	INTCON,T0IF
		movlw	tm0_setdata
		movwf	TMR0

		decfsz	count_data,1
		goto	next_int
time_up		movlw	cnt_setdata		
		movwf	count_data
		;-------------------------------- data henkan
		movf	adin_data,0
		movwf	adsub_data
		movlw	00h
		movwf	sub2_data
next21
		movlw	data1
		subwf	adsub_data,0
		btfsc	STATUS,0
		goto	next30
		goto	next31
next30
		movwf	adsub_data
		incf	sub2_data,1
		goto	next21
next31
		movf	sub2_data,0
		call	set_led_red
		movwf	led_red_data
		movf	sub2_data,0
		call	set_led_green
		movwf	led_green_data

		;---------------------------------

next_int
		;----------------------------------
		movf    status_temp,w     ; retrieve copy of STATUS register
		movwf	STATUS            ; restore pre-isr STATUS register contents
		swapf   w_temp,f
		swapf   w_temp,w          ; restore pre-isr W register contents
		retfie                    ; return from interrupt
;---------------------------------------------------------------------------------------
main
		call	porta_set_out
		call	portb_set_out
		movlw	0ffh		;port initial set
		movwf	PORTA
		movlw	0ffh
		movwf	PORTB

		movlw	0ffh
		movwf	led_red_data
		movwf	led_green_data
		movlw	00h
		movwf	adin_data

		call	timer0_set
		movlw	cnt_setdata
		movwf	count_data

main_loop
;--------------------------------------- disp
		bcf	INTCON,GIE
		call	portb_set_out
		bsf	INTCON,GIE

		movf	led_red_data,0
		movwf	PORTB
		bcf	PORTA,0
		call	wait_1
		bsf	PORTA,0

		movf	led_green_data,0
		movwf	PORTB
		bcf	PORTA,1
		call	wait_1
		bsf	PORTA,1		

;--------------------------------------- ad input
		bcf	INTCON,GIE
		call	portb_set_in
		bcf	PORTA,3
		nop
		nop
		nop
		bcf	PORTA,4
		nop
		nop
		nop
		bsf	PORTA,4
		nop
		nop
		nop
		movf	PORTB,0
		movwf	adin_data
		nop
		nop
		bsf	PORTA,3
		bsf	INTCON,GIE
;---------------------------------------
main_next
		goto	main_loop
;-------------------------------------------------------------------------------
set_led_red	movwf	taihi
		btfsc	taihi,5
		goto	led_red_end
		btfsc	taihi,6
		goto	led_red_end
		btfsc	taihi,7
		goto	led_red_end
		movlw	low(table0)
		addwf	taihi,1
		movlw	high(table0)
		movwf	PCLATH
		addcf	PCLATH,1
		movf	taihi,0
		movwf	PCL
table0		retlw	00h		;00
		retlw	0ffh		;01
		retlw	0ffh		;02
		retlw	0ffh		;03
		retlw	0ffh		;04
		retlw	0ffh		;05
		retlw	0ffh		;06
		retlw	0ffh		;07
		retlw	0feh		;08
		retlw	0fch		;09
		retlw	0f8h		;0a
		retlw	0f0h		;0b
		retlw	0e0h		;0c
		retlw	0c0h		;0d
		retlw	0c0h		;0e
		retlw	0c0h		;0f
		retlw	0e0h		;10
		retlw	0f0h		;11
		retlw	0f8h		;12
		retlw	0fch		;13
		retlw	0feh		;14
		retlw	0ffh		;15
		retlw	0ffh		;16
		retlw	0ffh		;17
		retlw	0ffh		;18
		retlw	0ffh		;19
		retlw	0ffh		;1a
		retlw	0ffh		;1b
		retlw	0ffh		;1c
		retlw	0ffh		;1d
		retlw	0ffh		;1e
		retlw	0ffh		;1f
led_red_end	retlw	0ffh		;20-4f
;-------------------------------------------------------------------------------
set_led_green	movwf	taihi
		btfsc	taihi,5
		goto	led_green_end
		btfsc	taihi,6
		goto	led_green_end
		btfsc	taihi,7
		goto	led_green_end
		movlw	low(table1)
		addwf	taihi,1
		movlw	high(table1)
		movwf	PCLATH
		addcf	PCLATH,1
		movf	taihi,0
		movwf	PCL
table1		retlw	0ffh		;00
		retlw	0ffh		;01
		retlw	0ffh		;02
		retlw	0ffh		;03
		retlw	0ffh		;04
		retlw	0ffh		;05
		retlw	0ffh		;06
		retlw	0ffh		;07
		retlw	0ffh		;08
		retlw	0ffh		;09
		retlw	0ffh		;0a
		retlw	0ffh		;0b
		retlw	0efh		;0c
		retlw	0cfh		;0d
		retlw	8fh		;0e
		retlw	0fh		;0f
		retlw	07h		;10
		retlw	03h		;11
		retlw	01h		;12
		retlw	00h		;13
		retlw	00h		;14
		retlw	00h		;15
		retlw	00h		;16
		retlw	00h		;17
		retlw	00h		;18
		retlw	00h		;19
		retlw	00h		;1a
		retlw	00h		;1b
		retlw	00h		;1c
		retlw	00h		;1d
		retlw	00h		;1e
		retlw	00h		;1f
led_green_end	retlw	00h		;20-4f
;-------------------------------------------------------------------------------
wait_1		
		movlw	0ffh
		movwf	wait_data
wait_2
		decfsz	wait_data,1
		goto	wait_2
		return
;-------------------------------------------------------------------------------
porta_set_out				;RA0,RA1,RA2,RA3,RA4(OUT)
		bsf	STATUS,RP0
		clrf	TRISA
		bcf	STATUS,RP0
		return
;-------------------------------------------------------------------------------
portb_set_out				;RB0,RB1,RB2,RB3,RB4,RB5,RB6,RB7(OUT)
		bsf	STATUS,RP0
		clrf	TRISB
		bcf	STATUS,RP0
		return
;-------------------------------------------------------------------------------
portb_set_in				;RB0,RB1,RB2,RB3,RB4,RB5,RB6,RB7(IN)
		bsf	STATUS,RP0
		clrf	TRISB
		comf	TRISB,1
		bcf	STATUS,RP0
		return
;-------------------------------------------------------------------------------
timer0_set
		bsf	STATUS,RP0
		movlw	086h		;(1)PORTB NOT PULLUP
					;(0)INTEDG
					;(0)TOCS
					;(0)TOSE
					;(0)PSA
					;(110)1/128
		movwf	OPTION_REG
		bcf	STATUS,RP0
		
		movlw	tm0_setdata
		movwf	TMR0
		bsf	INTCON,T0IE
		bsf	INTCON,GIE
		return
;-----------------------------------------------------------------------------
		END                     ; directive 'end of program'
乾電池チェッカーの全HEXコード
HEXコードです。メモ帳などのテキストエディタにコピー&ペーストしてファイルすればPICに書き込めるデータに出来ます。
:020000002528B1
:080008008C0003088D000B11B0
:1000100063308100950B202805309500140891006D
:100020000030970005301102031817281A28910094
:10003000970A122817085520A00017088520A1004C
:100040000D0883008C0E0C0E0900BA20BE20FF3074
:100050008500FF308600FF30A000A1000030940032
:10006000C720053095008B13BE208B172008860013
:100070000510B5200514210886008510B5208514CB
:100080008B13C22085110000000000000512000043
:1000900000000000051600000000000006089400A3
:1000A0000000000085158B1733289300931A8428CD
:1000B000131B8428931B84286430930700308A0024
:1000C00003188A0A130882000034FF34FF34FF3417
:1000D000FF34FF34FF34FF34FE34FC34F834F034A2
:1000E000E034C034C034C034E034F034F834FC348C
:1000F000FE34FF34FF34FF34FF34FF34FF34FF3469
:10010000FF34FF34FF34FF34FF349300931AB428D4
:10011000131BB428931BB4289430930700308A0033
:1001200003188A0A13088200FF34FF34FF34FF34B7
:10013000FF34FF34FF34FF34FF34FF34FF34FF3427
:10014000EF34CF348F340F340734033401340034A8
:1001500000340034003400340034003400340034FF
:1001600000340034003400340034FF309000900B31
:10017000B7280800831685018312080083168601BC
:1001800083120800831686018609831208008316ED
:10019000863081008312633081008B168B17080034
:02400E00F13F80
:00000001FF
(denchi.hex)
乾電池チェッカーの完成
(電池を入れないときは緑色、ここでプッシュSWを押すと赤色に)
(単3電池の測定、これはまだまだつかえますねえ)
(単4電池の測定、これは使えなさそう・・・・)
以上で乾電池チェッカーは大完成です。
どうでしょう、本当に実用的な電子工作でしたね。
プッシュSWを押したとき電圧が減らない電池がまだ大丈夫な電池ですね。
ということで、今回はここまでです。
今後も益々面白くなる「PIC16F84電子遊戯」をよろしくお願いいたします。

不明点などあればメールお願いいたします。nonchansoft@nifty.com

Copyright(c)2000-2001 nonchansoft