下のプログラムをPIC12F675に書き込んでください。
なお、PIC12F675は出荷時に、プログラムメモリの最終番地に、発信周波数の補正値が記録されています。最初のプログラミングの前に、PIC12F675のプログラムを読み込み、表示させます。(MPLABでは、メニューのProgrammer→ Read、次にView → ProgramMemory)。 最終番地(3FF)の34XXのXXをメモしておき、プログラム中の該当部分をこのXXに書き直してください。下のプログラムでは44になっています。
注:出荷時の補正値は一度プログラミングすると消えてしまうので、必ず最初のプログラミングの前に、行ってください。
自分は、秋月電子のAKI-PIC2プログラマボード(PICkit2互換)を使っています。
http://akizukidenshi.com/catalog/g/gM-02495/
フラットマイコンの足をDIP型の足に変換する器具は自作しました。
液晶表示部の加工が終わった段階で、ブレッドボード上で作動確認することをお勧めします。この時は、扱いやすいDIPタイプのマイコン(PIC12F675)を使います。
回路を組んで、電池をつなぐと直ちに圧電スピーカから、音が鳴り始めます。音が鳴れば正しくプログラミングされています。
音は出るが、ストップウォッチが作動しない場合、代表的な確認事項は次の通りです。
①模様のような表示
液晶の取り付けが向きが逆。導電ゴムの接触不良。
②表示が出ない
電池をつないで約1秒後に電源電圧(V+)が1.5Vに立ち上がるかどうかを確認します。
1.5Vが立ち上がれば、赤、黒コードのストップウォッチ上のはんだ付け部を確認します。
③表示が出たが初期化されていない(「1:0000」にならない)
ぴっぴっぴっの音のタイミングで、ストップウォッチのSTART/STOP入力部でパルス信号が出るかを確認します。パルスが出なければ抵抗、コンデンサの接続状態、パルスが出ていれば黄色のコードのストップウォッチ基板の接続状態を確認します。
④ストップウォッチモードにならない
1.5V立ち上がってから約3秒後にストップウォッチのMode入力部にパルス信号が出るかを確認します。パルスが出なければ抵抗の接続状態、パルスが出ていれば緑色のコードのストップウォッチ基板の接続状態を確認します。
⑤スタート、ストップが作動しない(ストップウォッチが計測開始、計測終了しない)
スタート音と同時にSTART/STOP入力部にパルス信号が出ているかどうかを確認します。出ていなければ、10kΩ抵抗と0.1μFの接続状態、出ていれば黄色のコードのストップウォッチ基板の接続状態を確認します。 ③と同じ確認方法ですので、③で問題なければスタート、ストップも作動します。
注:100円ショップのストップウォッチの特性による作動不良の場合もあるかもしれません。ストップウォッチ単体で、以下を確認してください。
①V+=0Vとし、START/STOPへ1.5Vのパルス信号を入力する。
②V+=1.5V供給してストップウォッチを起動したら、時計モードの「1:0000」表示になり、時が刻まれるか。
③Mode信号に1回1.5Vのパルス信号を入力したら「0:0000」表示となるか。
②,③のとおり作動しなければ、作動する方法を試行錯誤して特性を見極め、特性に応じた回路やプログラムを工夫してください。
;指ストップウォッチコントロールプログラム 2016年6月 小出 芳夫
;file name:stopwatch_3V.asm
;*****ピン配置***************************************************
; MODE
START/STOP 圧電スピーカ
;
/初期化
; Vss GP0
GP1 GP2
; 8
7 6
5
;
; 1
2 3
4
; Vdd GP5
GP4(input) GP3(input)
; stopwatch電源 SWITCH(抵抗でプルアップ)
;**************************************************************
LIST P=12f675
#INCLUDE <p12f675.inc>
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
CBLOCK 020h
T10ms_count ;10mSループカウンタ
T1_count ;汎用タイムループカウンタ
T2_count ;汎用タイムループカウンタ
LP_count1 ;汎用ループカウンタ1
LPG_count2 ;電源用ループカウンタ2
LPG_count1 ;電源用ループカウンタ1
LP_count2 ;汎用ループカウンタ2
LP_count4 ;汎用ループカウンタ4
MP_count ;全体時間用カウンタ メインと割り込み共通
M_count ;STOP時チャタリング防止カウンタ メインと割り込み共通
E_data ;EPROMデータ
s_stts ; statusレジスタの退避
s_wreg ; workingレジスタの退避
f_int ; 割り込みフラグ(bit1:mode切替命令時に1; bit0:on_offの切替のマーク)
ENDC
ORG 0
; =====PIC初期化======================================
movlw B'00000111'
movwf CMCON ;コンパレータOFF
bsf STATUS,RP0 ;■バンク1に切替え
;-------------------------PIC12F675毎の固有の値を設定する----------------------
movlw 44h ;プログラム最終アドレス3FFの34XXのXX値(出荷時の調整値)
;をOSCCALに書き込む(プログラムを一度書き込むと消えるので注意)
;本サンプルではアドレス3FFの値が、3444であった。
;------------------------------------------------------------------------
movwf OSCCAL ;発振周波数調整
CLRF ANSEL ;AN機能使用しない
movlw B'00011000' ;GP3,GP4を入力、GP0,GP1,GP2,GP5は出力 '--543210'
movwf TRISIO
movlw B'00010000' ; GP番号(GP4)を指定
movwf WPU ; 指定番号をWPUに記入し
bcf OPTION_REG,7 ; プルアップ有効にする
movlw B'00010000' ; GP4ピン変化割込有効に
movwf IOC
bcf STATUS,RP0 ;■バンク0に切替え
movlw 08h ; ピン変化割込有効GPIE(00001000)
movwf INTCON ;
CLRF f_int ;メモリクリア
CLRF GPIO
;******** メイン処理*********************************************************
MAIN
bsf STATUS,RP0 ;■バンク1に切替え
bcf TRISIO,5 ;出力に
bcf STATUS,RP0 ;■バンク0に切替え
bcf GPIO,5 ;出力0(V)にする(電源切る)。
call T04sWAIT ;電源切ったあとの電圧下がるまで待つ
call T40mBEEP_WITH_GP1_ONOF ;電源切り状態のときにstart電圧掛ける。音も出す。
call T04sWAIT
call T40mBEEP_WITH_GP1_ONOF ;電源切り状態のときにstart電圧掛ける。音も出す。
call T04sWAIT
call T40mBEEP_WITH_GP1_ONOF ;電源切り状態のときにstart電圧掛ける。音も出す。
btfss GPIO,4 ;長押しの場合(0の場合)、E_dataの一桁めの0,1を変更する
incf E_data,f ;(一桁目1はランダムモード)
btfss E_data,0 ;1の場合(ランダムモード場合)1行ジャンプして音を鳴らす
goto next00
call T10mWAIT ;40ms後にぴ音 ランダムモード場合、音の並びが 「ぴっぴっぴぴ」 となる
call T10mWAIT
call T10mWAIT
call T10mWAIT
call T10mBEEP
call T10mBEEP
call T10mBEEP
call T10mBEEP
next00
;ストップウォッチの電源をいれながら、STOPWATCHが立ち上がるまで待つ
call Vinp01 ;電源供給
call Vinp01 ;電源供給
call T1sWAIT
call Vinp01 ;電源供給
call T1sWAIT
call Vinp01 ;電源供給
call T1sWAIT
;MODE切り替え(ストップウォッチモードへ)
bsf GPIO,0 ;MODE信号はON
call T10mWAIT
call T10mWAIT
call T10mWAIT
call T10mWAIT
call T10mWAIT
bcf GPIO,0 ;MODE信号はON
call Vinp01 ;電源供給
;3秒ぴー音
movlw D'50'
movwf LP_count1
bee1
call T10mBEEP
call T10mWAIT
call T10mWAIT
call Vinp1ms ;電源供給
call Vinp1ms ;電源供給
call Vinp1ms ;電源供給
decfsz LP_count1,f
goto bee1
call Vinp01 ;電源供給
;3秒まち
call T1sWAIT
call Vinp01 ;電源供給
call T1sWAIT
call Vinp01 ;電源供給
call T1sWAIT
call Vinp01 ;電源供給
;3秒まち
call T1sWAIT
call Vinp01 ;電源供給
call T1sWAIT
call Vinp01 ;電源供給
call T1sWAIT
call Vinp01 ;電源供給
;.5秒ブー音
movlw D'25'
movwf LP_count1
bee3
call T10mBEEP
call T10mWAIT
decfsz LP_count1,f
goto bee3
;.5秒ブー音
movlw D'22'
movwf LP_count1
bee4
call T10mBEEP
call T10mWAIT
call T3mWAIT
decfsz LP_count1,f
goto bee4
call Vinp01 ;電源供給
;1秒まち(スタート直前処理1)
call T1sWAIT
call Vinp01 ;電源供給
;追加時間待ち(スタート直前処理2)
movlw D'125' ;固定時間をLP_count1にセット
movwf LP_count1
btfss E_data,0 ;ランダムモードの場合(最下位ビットが1の場合)ジャンプ
goto wait2
movfw E_data ;ランダムの場合ランダム時間(E_data)をワークレジスタに移す。
movwf LP_count1 ;ランダム時間をLP_count1にセット
wait2
call T3mWAIT
decfsz LP_count1,f
goto wait2
;start信号出力---------------------
call T40mBEEP_WITH_GP1_ONOF ;40msの間start信号と音を同時に出す
call T10mBEEP ;その後は音だけ60ms出す。
call T10mBEEP
call T10mBEEP
call T10mBEEP
call T10mBEEP
call T10mBEEP
bcf f_int,1 ;STOP音未発生状態とする=0
bcf f_int,2 ;BEEP信号後の待ち時間未完了とする=0
;2分待つ++++++++++++++++++++++++++++++++
movlw D'240'
movwf MP_count
wait2min ;
movfw E_data ;E_dataに値を加算(疑似ランダム値を入力する)
addlw D'162'
movwf E_data
;誤ボタン操作防止のためのカウントダウン(2秒待つ)
btfss f_int,1 ;音発生済だったらスキップ
goto next1
btfsc f_int,2 ;待ち時間未完了だったらスキップ
goto next1
decfsz M_count ;カウントが0になればジャンプ(チャタリング防止)
goto next1
bsf f_int,2 ;待ち時間完了とする(チャタリング防止時間経過済)
next1
;.5秒まち--------------------
movlw D'250'
movwf LP_count4
wait1s
call Vinp1ms
call T2mWAIT
btfsc GPIO,4 ;0の場合スキップ(ストップウォッチ作動させる)
goto end1
btfsc f_int,2 ;経過時間過ぎてない場合はスキップ。 経過した場合はメインに
goto MAIN
btfsc f_int,1 ;ストップ音発生未の場合スキップして音発生へ
goto end1
;STOP信号出力
call T40mBEEP_WITH_GP1_ONOF
call T10mBEEP
call T10mBEEP
call T10mBEEP
call T10mBEEP
call T10mBEEP
call T10mBEEP
bsf f_int,1 ;ストップ音発生済
bcf f_int,2 ;待ち時間クリア(未完了とする)
movlw D'240' ;表示を2分延長
movwf MP_count
movlw D'4' ;チャタリング防止カウンタ
movwf M_count
end1
decfsz LP_count4,f
goto wait1s
;----------------------------
decfsz MP_count,f
goto wait2min
;++++++++++++++++++++++++++++++++++
;SLEEP前処理*************************
movlw D'05'
movwf LP_count2
wait5
call T10mBEEP
call T1sWAIT
decfsz LP_count2,f
goto wait5
bsf STATUS,RP0 ;■バンク1に切替え
bcf TRISIO,5 ;出力に
nop
bcf STATUS,RP0 ;■バンク0に切替え
bcf GPIO,5
nop
nop
;EEDATAの保存++++++++++++
movfw E_data
movwf EEDATA
movlw 00h ;アドレス指定
movwf EEADR
bsf STATUS,RP0 ;Bank 1
bsf EECON1,WREN ;Enable write
movlw 55h ;Unlock write
movwf EECON2
movlw 0AAh
movwf EECON2
bsf EECON1,WR ;Start the write
wait999
btfsc EECON1,WR
goto wait999
bcf STATUS,RP0 ;Bank 0
;++++++++++++++++++++++
bcf INTCON,GPIF ;ピン変化割込みフラグをクリアする(0 bit目)
sleep
nop
;EEDATAの読み込み++++++++
movlw 00h ;アドレス指定
movwf EEADR
bsf STATUS,RP0 ;Bank 1
bsf EECON1,RD
bcf STATUS,RP0 ;Bank 0
;+++++++++++++++++++++++
goto MAIN
;***********************以下サブルーチン*******************************
;*************電源供給関連*******************************************
Vinp01
bsf STATUS,RP0 ;■バンク1に切替え
bcf TRISIO,5 ;出力に
bcf STATUS,RP0 ;■バンク0に切替え
call T01sGP5 ;ストップウォッチに0.1秒電源供給
bsf STATUS,RP0 ;■バンク1に切替え
bsf TRISIO,5 ;入力に
bcf STATUS,RP0 ;■バンク0に切替え
return
Vinp1ms
bsf STATUS,RP0 ;■バンク1に切替え
bcf TRISIO,5 ;出力に
bcf STATUS,RP0 ;■バンク0に切替え
call T1msGP5 ;ストップウォッチに1ms秒電源供給
bsf STATUS,RP0 ;■バンク1に切替え
bsf TRISIO,5 ;入力に
bcf STATUS,RP0 ;■バンク0に切替え
return
;GP5を0.1秒ONOFF繰り返す。ストップウォッチへの電源供給-----------
T01sGP5
movlw D'50' ;1
movwf LPG_count1 ;1
loop2
bcf GPIO,5 ; 1
nop ; 1
movlw D'200' ; 1
movwf LPG_count2 ; 1
loop1
bsf GPIO,5 ;1
nop ;1
nop ;1
nop ;1
nop ;1
bcf GPIO,5 ; 1
decfsz LPG_count2,f; 1(2)
goto loop1 ; 2 .001*9*200=18ms
nop ; 1
bsf GPIO,5 ;1
decfsz LPG_count1 ;1(2)
goto loop2 ;2
return
;GP5を.58ms ONOFF繰り返す。ストップウォッチへの電源供給------------
T1msGP5
movlw D'5' ; 1
movwf LPG_count2 ; 1
loop3
bsf GPIO,5 ;1
nop ;1
nop ;1
nop ;1
nop ;1
nop ;1
nop ;1
bcf GPIO,5 ;1
decfsz LPG_count2,f;1(2)
goto loop3 ;2 .001*(44+12+2)=.58ms
return ; 2
;***************音関連**************************************
;--;4kHzのビープ音を10ms継続-----------------------------------
; 4kHz=.25ms 4Mhz=.00025ms 1STEP=.00025*4=.001ms 250STEPで.25mSとなる
T10mBEEP
movlw D'40' ;1
movwf T1_count ;1
LOOP71
bsf GPIO,2 ;1 送信ポートGP2をhighに
call TIME100STEP ;100
call TIME10STEP ;10
call TIME10STEP ;10
nop ;1
nop ;1
nop ;1
nop ;1
bcf GPIO,2 ; 1 送信ポートGP2をLOWに
call TIME100STEP ; 100
call TIME10STEP ; 10
call TIME10STEP ; 10
nop ; 1
decfsz T1_count,f ; 1(2)
goto LOOP71 ; 2
return ;2
;--;4kHzのビープ音を40ms継続 かつ GP1(START,STOPスイッチ)のON、OFFを繰り返す
; 4kHz=.25ms 4Mhz=.00025ms 1STEP=.00025*4=.001ms 250STEPで.25mSとなる
T40mBEEP_WITH_GP1_ONOF
movlw D'160' ;40ms/.25ms=160
movwf T1_count
LOOP72 ;1
*************
bsf GPIO,2 ;1 GP2(音)をhighに
nop ;1
nop ;1
nop ;1
bcf GPIO,1 ; 1 GP1(START,STOPスイッチ)のOFF
movlw D'13' ; 1
movwf T2_count ; 1
loop721 ;
+++++
bsf GPIO,1 ;1 GP1(START,STOPスイッチ)のON
nop ;1
nop ;1
nop ;1
nop ;1
bcf GPIO,1 ; 1 GP1(START,STOPスイッチ)のOFF
decfsz T2_count ; 1(2)
goto loop721 ; 2 9*13=117 step +++++
bsf GPIO,1 ;1 GP1(START,STOPスイッチ)のON
nop ;1
nop ;1 3 step
bcf GPIO,2 ;1 GP2(音)をLOWに
movlw D'13' ;1
movwf T2_count ;1
bcf GPIO,1 ; 1 GP1(START,STOPスイッチ)のOFF
nop ; 1 5step
loop722 ;
-----
bsf GPIO,1 ;1 GP1(START,STOPスイッチ)のON
nop ;1
nop ;1
nop ;1
nop ;1
bcf GPIO,1 ; 1 GP1(START,STOPスイッチ)のOFF
decfsz T2_count ; 1(2)
goto loop722 ; 2 9*13=117sep -----
bsf GPIO,1 ;1
decfsz T1_count ;1(2)
goto LOOP72 ;2 4 step **************
bcf GPIO,1 ; 1
nop
nop
nop
return
;*****タイマ関連***************************************************
;---------- 10.000mS待つ 1STEP=.00025*4=.001ms
T10mWAIT ;2 (call分)
movlw D'97' ;1
movwf T10ms_count ;1
T10mloop
call TIME100STEP ;100
decfsz T10ms_count,F;1(2)
goto T10mloop ;2 4+103*96+108=10000
nop ; 1
nop ; 1
nop ; 1
nop ; 1
return ; 2
;----------- 3.095mS待つ 1STEP=.00025*4=.001ms
T3mWAIT ; 2 (call分)
movlw D'30' ; 1
movwf T1_count ; 1
T3mloop
call TIME100STEP ;100
decfsz T1_count,F ;1(2)
goto T3mloop ;2 4+103*29+104=3095
return ; 2
;----------- 1.931mS待つ 1STEP=.00025*4=.001ms
T2mWAIT ;2 (call分)
movlw D'18' ;1
movwf T1_count ;1
T2mloop
call TIME100STEP ;100
nop ;1
nop ;1
nop ;1
nop ;1
decfsz T1_count,F ;1(2)
goto T2mloop ;2 4+107*17*108=1931
return ; 2
;-----------0.1s待つ
T01sWAIT ;2 (call分)
movlw D'10' ;1
movwf T1_count ;1
T01sloop
call T10mWAIT ;10000
decfsz T1_count,F ;1(2)
goto T01sloop ;2 4+10003*9+10004=100035
return ; 2
;-----------0.4s待つ
T04sWAIT ;2 (call分)
movlw D'40' ;1
movwf T1_count ;1
T04sloop
call T10mWAIT ;10000
decfsz T1_count,F ;1(2)
goto T04sloop ;2 4+10003*39+10004=400121
return ; 2
;-----------1s待つ
T1sWAIT ;2 (call分)
movlw D'100' ;1
movwf T1_count ;1
T1sloop
call T10mWAIT ;10000
decfsz T1_count,F ;1(2)
goto T1sloop ;2
return ; 2
;-----------10STEP待つ
;10STEP(10μs=0.01ms)
TIME10STEP ;2 (call分)
nop ;1
nop ;1
nop ;1
nop ;1
nop ;1
nop ;1
return ;2
;-----------100STEP待つ
;100STEP(0.1ms)
TIME100STEP ;2 (call分)
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
call TIME10STEP ;10
nop ;1
nop ;1
nop ;1
nop ;1
nop ;1
nop ;1
return ;2
end