プログラム

 下のプログラムをPIC12F675に書き込んでください。

 

 なお、PIC12F675は出荷時に、プログラムメモリの最終番地に、発信周波数の補正値が記録されています。最初のプログラミングの前に、PIC12F675のプログラムを読み込み、表示させます。(MPLABでは、メニューのProgrammer→ Read、次にView → ProgramMemory)。 最終番地(3FF)34XXXXをメモしておき、プログラム中の該当部分をこの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