PIC16F84電子遊戯(14)
最終更新日:2001年3月11日
湿度計(1ページ)へ (2ページ)へ (3ページ)

湿度計の温度センサーの出力電圧の調整
A/D変換されたデータを表示データに変換する処理を説明する前に、湿度センサーの出力電圧を調整しておきましょう。
湿度センサーの出力電圧は1%につき10mVです。これをオペアンプで4倍に増幅します。
まず、LM35DZの出力電圧をデジタルテスタで計測します。uPC358Cの3ピンの電圧でOKです。次にその電圧の4倍値になるように1ピンにテスタを当てて10kVRを調整しましょう。
湿度計のA/D変換値の表示データへの変換
さて、読み込んだA/D変換値はどのようにして表示データに変換するのでしょうか。
まず、オペアンプを含めた湿度センサーからの電圧は、例えば40%のとき、1.6Vとなります。A/D変換の基準電圧が5Vなので、1.6VのときのA/D変換値は81(256/5*1.6=81.92)となります。この値を2で割れば40(81/2=40.5)となりほぼ測定値に合った表示となります。
(正確には1ビットを0.5%として表示します。理論的には100%のときに200になります。)
湿度表示は10%、1%の位を順に表示しますので、位ごとに表示データを算出します。まず10%の表示データはA/D変換値を20で割った値です。20で割るというのは難しいので、A/D変換値から20が何回引けるかで算出します。
同様にその残りのデータから2が何回引けるか算出して1%の表示データとします。
以上より、湿度表示は1%きざみとなります。最終的には湿度センサーの出力電圧をテスターで計測しながら、表示データを合うように10kVRを微調整しましょう。
A/D変換値を演算エリアにコピーする
10%、1%計算エリアをクリアする
演算エリア値を20で割った商を10%のデータとする
残りの値を2で割った商を1%のデータとする
それぞれの計算結果を表示データへコピーする
表示データの計算にはそれぞれの計算用RAMを用意しました。
adsub_data sub2_data sub3_data
A/D変換値を演算エリア 1%計算エリア 10%計算エリア
割り算(減算の繰り返し)に使用する値もデータとして定義しておきましょう。
data10 data1
14H 2H
表示データへの変換は0.5秒ごとに行います。
メインルーチンで毎回行ってもいいのですが、そうすると表示が常に変化してしまうので、見栄えが悪くなります。
7セグの表示は常に行われますが、変換は0.5秒ごとに行うため、見かけ上は0.5秒ごとにセンスしているように見えます。
湿度計の全ソースリスト公開
湿度計の全ソースリストです。
まだ未熟な点もありますので、皆さんでお好みに改造して下さい。
;**********************************************************************
;    Filename:	    shitudo.asm                                       *
;    Date:          2001/2/4                                        *
;    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
shitu1_data	EQU	0x11		;shitudo(1) LED data ram
shitu2_data	EQU	0x12		;shitudo(10) LED data ram
adin_data	EQU	0x14		;ad input data ram
count_data	EQU	0x15		;0.5sec keisoku count ram
adsub_data	EQU	0x16		;ad keisanyou ram
sub2_data	EQU	0x17		;sub(1) data ram
sub3_data	EQU	0x18		;sub(10) data ram
tm0_setdata	EQU	63h		;255-156=99=63H  156*128=19.968msec
cnt_setdata	EQU	19h		;19.968*25=0.4992sec
data10		EQU	14h		;henkanyou data 1
data1		EQU	2h		;henkanyou data 2
;**********************************************************************
		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
		movwf	sub3_data
next10
		movlw	data10
		subwf	adsub_data,0
		btfsc	STATUS,0
		goto	next20
		goto	next21
next20
		movwf	adsub_data
		incf	sub3_data,1
		goto	next10
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
		movwf	shitu1_data
		movf	sub3_data,0
		movwf	shitu2_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	00h
		movwf	PORTB
		movlw	00h
		movwf	shitu1_data
		movwf	shitu2_data
		movwf	adin_data
		call	timer0_set
		movlw	cnt_setdata
		movwf	count_data
main_loop
;--------------------------------------- led7_disp
		bcf	INTCON,GIE
		call	portb_set_out
		bsf	INTCON,GIE
		movf	shitu1_data,0
		movwf	PORTB
		bcf	PORTA,0
		call	wait_1
		bsf	PORTA,0
		movf	shitu2_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
;-------------------------------------------------------------------------------
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に書き込めるデータに出来ます。
:020000002C28AA
:080008008C0003088D000B11B0
:1000100063308100950B272819309500140896004D
:1000200000309700980014301602031818281B2877
:100030009600980A13280230160203182028232855
:100040009600970A1B2817089100180892000D08BF
:1000500083008C0E0C0E090060206420FF308500A8
:100060000030860000309100920094006D2019301D
:1000700095008B1364208B171108860005105B20F8
:1000800005141208860085105B2085148B136820E8
:1000900085110000000000000512000000000000B3
:1000A0000516000000000000060894000000000093
:1000B00085158B173928FF309000900B5D280800BC
:1000C00083168501831208008316860183120800B7
:1000D0008316860186098312080083168630810004
:0C00E0008312633081008B168B17080020
:02400E00F13F80
:00000001FF
(shitudo.hex)
湿度計の各処理概要
ソースリストの赤い部分が割り込み処理、青の部分がメイン処理です。
後半の黒の部分が各種サブルーチンです。
割り込み処理
STATUSレジスタ退避
0.5秒カウンタ処理
A/D変換値の表示データへの変換
STATUSレジスタ復帰
メイン処理
初期設定
7セグメント表示処理
A/D変換入力
湿度計の完成
以上で湿度計は大完成です。なんか温度計とほとんど同じでしたね。
しかし、色々実測してみましたがなぜかこれが本当の湿度かな?と疑うこともあります。
まああまり深く追求しないことにしておきましょう。センサー部分の問題かもしれませんので。
これからもどんどん面白くなる「PIC16F84電子遊戯」をよろしくお願いします。

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

Copyright(c)2000-2001 nonchansoft