クロックはEPSONの4MクリスタルモジュールSG-11 8501B を使いました 有効桁数5桁 足は左から G ,OUT, 5V
ジャンク箱の中にあった手持ち部品
セ ラロックでも有効桁数4桁位ありますので良いと思いますが!
7セグLEDは4桁 アノードコモン ダイナミック点灯用 SL-1063-50 ジャンク 1個32円か53円
JWCADで基板パターン作成 大きさ 31*33o 超小型です。
でもこんな事が簡単に出来る CNC はすばらしい。皆でCNCを作りましょう!!
基板は上記と違いますが、写真撮り忘れてしまいました。
完成した基板上部
基板パターン部
表示はレンジ自動切換えです。常に4桁表示します。DPは表示しません。7セグに無いので
クロックの1/4をカウントします。したがって今回は1MHzになります。
割込みを使って見ました。
PICのCCPモジュール キャプチャーモード を使用して計測します。
ポートB3はCCP1のシュミット入力ポートです。
入力信号をトリガにしてタイマ1の内容を保持します。
TMR1H,TMR1Lの内容がトリガ信号によりCCPR1H.CCPR1Lにコピーし同時に割込みが発生します。
;周期カウンター アノードコモン JA0BAS 08/07/24
LIST P=PIC16F716
INCLUDE "P16F716.INC"
__CONFIG _PWRTE_ON & _WDT_OFF & _CP_OFF & _HS_OSC
& _BOREN_OFF
errorlevel -302 ; suppress message 302 from list
file
; Define Constant or Work
#define K1 PORTA,0 ;1Hz
#define K2 PORTA,1 ;10Hz
#define K3 PORTA,2 ;100Hz
#define K4 PORTA,3 ;1000Hz
x0 equ 20h
x1 equ 21h
x2 equ 22h
x3 equ 23h
vfo0 equ 28h ;Lo(VFO)。
vfo1 equ 29h
vfo2 equ 2ah
cfo3 equ 2bh
y0 equ 2ch
y1 equ 2dh
y2 equ 2eh
y3 equ 2fh
dec0 equ 30h ; 10進格納場所(10バイト)
dec1 equ 31h
dec2 equ 32h
dec3 equ 33h
dec4 equ 34h
dec5 equ 35h
dec6 equ 36h
dec7 equ 37h
dec8 equ 38h
dec9 equ 39h ;dec_top
val0 equ 3ah ; 変換したい値(32ビット)
val1 equ 3bh
val2 equ 3ch
val3 equ 3dh
val_m equ 3eh ; 一時余り格納場所(サブルーチンで使用)
overf equ 44h
dsp0 equ 45h ;LED表示データ 5桁
dsp1 equ 46h
dsp2 equ 47h
dsp3 equ 48h
dsp4 equ 49h
tempa EQU 4bh
wait_cn equ 4ch
wait_cn2 equ 4dh
cn equ 4eh
cs equ 4fh ;sub-counter
COUNTF EQU 60H
W_TEMP EQU 61H
W_TEM EQU 62H
ST_TEMP EQU 63H
INT_C EQU 64H
MOVFF MACRO SRC,DST ;←MOVFF というマクロを登録、引数は SRC DST
MOVF SRC,W ;命令を書く
MOVWF DST
ENDM ;マクロ終了
CPLFN MACRO L,FILE,PTR ;IF(L <> FILE) GOTO PTR
F<>Lの場合PTRへとぶ
MOVF FILE,W ;WREG破壊 例:CPLFN H'10',FILE,PTR
XORLW L ;IF FILE = L THEN Z = 1
BTFSS STATUS,Z ;Z = 1 なら1行とばす
GOTO PTR
ENDM
org 0
goto start
org 4
goto INTR
tabl ANDLW B'00001111' ;下位4ビット有効
addwf pcl,F ;cycle3
; ADBE-FGC 7segment のA〜F
retlw b'11110101' ;letter 0 RB0(6)-C
retlw b'00100001' ;letter 1 RB1(7)-G
retlw b'11110010' ;letter 2 RB2(8)-F
retlw b'11100011' ;letter 3 RB3(9)-
retlw b'00100111' ;letter 4 RB4(10)-E
retlw b'11000111' ;letter 5 RB5(11)-B
retlw b'11010111' ;letter 6 RB6(12)-D
retlw b'10100001' ;letter 7 RB7(13)-A
retlw b'11110111' ;letter 8
retlw b'11100111' ;letter 9 A
retlw b'01110101' ;letter U ____
retlw b'01010100' ;letter L F | | B
retlw b'11010100' ;letter C |_G__|
retlw b'10110111' ;letter A E | | C
retlw b'10010110' ;letter F |____|
retlw b'00000010' ;letter - D
;--------------------------------------------------------------------------
start
INI
bsf STATUS,RP0 ;BANK1
MOVLW b'11111111' ;初期設定 アナログOFF
MOVWF ADCON1 ;16F716 独自
MOVLW b'00001000' ;初期設定 RB3 CCP入力
MOVWF TRISB
MOVLW B'11010111' ;OPTION set
MOVWF OPTION_REG ;for TMR0
BCF PIE1,TMR1IE ;TMR1 OVERフロー割込禁止
BCF PIE1,CCP1IE ;チャプチャー割込禁止
BCF PIE1,TMR2IE ;TMR2 OVERフロー割込禁止
MOVLW b'11110000' ;初期設定入力 RA0-3 桁出力 RA4 TOCKI
MOVWF TRISA
BCF STATUS,RP0 ;BANK0
MOVLW b'11111111'
MOVWF T2CON ;1:16,1:16 SET=256
CLRF TMR2
MOVLW b'11111111' ;LED OFF
MOVWF PORTA ;MOVWF PORTA
MOVLW b'00000101' ;初期設定入力
MOVWF CCP1CON ;チャプチャー立上エッジごと
MOVLW b'00000000' ;初期設定入力
MOVWF T1CON ;T1CONレジスタ プリスケーラ1:1
BCF T1CON,T1OSCEN ;OSC停止
BCF T1CON,T1SYNC ;同期
BCF T1CON,TMR1CS ;int osc
BSF T1CON,TMR1ON ;TMRのTMR ONビットをセット カウント開始
CLRF COUNTF
CLRF PIR1
BSF INTCON,PEIE ;周辺割込の許可
BSF INTCON,GIE ;全体割込の許可
CLRF TMR1H
CLRF TMR1L
CLRF DSP0
CLRF DSP1
CLRF DSP2
CLRF DSP3
CLRF INT_C
MAIN
display ;RETURN
BTFSS INT_C,2 ;4回まで待つ
GOTO DIS1
bsf STATUS,RP0 ;BANK1
BTFSC PIE1,CCP1IE ;チャプチャー割込中?
GOTO DIS2
BCF STATUS,RP0 ;BANK0
CLRF TMR1L
CLRF TMR1H
CLRF A2
BCF PIR1,CCP1IF ;CCP FLG CLR
bsf STATUS,RP0 ;BANK1
BSF PIE1,CCP1IE ;チャプチャー割込許可
BCF STATUS,RP0 ;BANK0
GOTO DIS1
DIS2
BCF STATUS,RP0 ;BANK0
BTFSS INT_C,3 ;8回過ぎたらErr
GOTO DIS1
CLRF DSP0
CLRF DSP1
CLRF DSP2
CLRF DSP3
CLRF DSP4
CALL DEND
DIS1 movf dsp3,w ;100KHz桁
call TABL
MOVWF W_TEM
COMF W_TEM,W ;反転
movwf portb
BCF K4
call TIME
bSf K4
movf dsp2,W ;10KHz桁
call TABL
MOVWF W_TEM
COMF W_TEM,W ;反転
movwf portb
BCF K3
call TIME
bSf K3
movf dsp1,W ;1KHz桁
call TABL
MOVWF W_TEM
COMF W_TEM,W ;反転
movwf portb
BCF K2
call TIME
bSf K2
movf dsp0,W ;0.1KHz桁
call TABL
MOVWF W_TEM
COMF W_TEM,W ;反転
movwf portb
BCF K1
call TIME
bSf K1
GOTO MAIN
TIME DECFSZ wait_cn,f
GOTO $-1
DECFSZ wait_cn,f
GOTO $-1
btfsS PIR1,TMR1IF ;1M/64k=15 100Ms以内にCHKする
GOTO CHK ;TMR1 OVER FRO
BCF PIR1,TMR1IF ;クリヤー
INCF A2,F ;
CHK BTFSS PIR1,TMR2IF ;TMR2 OVER FRO CHK
RETURN
BCF PIR1,TMR2IF
INCF INT_C,F
RETURN
;
INTR ;割込処理
PUSH BCF INTCON,GIE ;全体割込の禁止
MOVWF W_TEMP ;Wレジスタ待避
SWAPF STATUS,W ;STATUS取出
MOVWF ST_TEMP ;STATUS待避
CALL INTMAIN
pop SWAPF ST_TEMP,W ;STATUSを戻す
MOVWF STATUS
SWAPF W_TEMP,F ;Wレジスタを戻す
SWAPF W_TEMP,W
BSF INTCON,GIE ;全体割込の許可
RETFIE ;割込を許可してリターン
INTMAIN BCF PIR1,CCP1IF ;CCP FLG CLR
CPLFN 01H,COUNTF,NEXT
MOVFF CCPR1L,A4 ;NEW->A
MOVFF CCPR1H,A3
CALL SUB32 ;NEW-OLD(A-B)=A
MOVFF A4,B4
MOVFF A3,B3
MOVFF A2,B2
MOVLW B'00000000' ;A=D'4000M'を2進数でSET
MOVWF A4
MOVLW B'00101000' ;1Hzで1000表示
MOVWF A3
MOVLW B'01101011' ;誤差を無くすためなるべく大きな数
MOVWF A2
MOVLW B'11101110'
MOVWF A1
CALL DIV32 ;4 000 000 000/xx(A/B)=A
BCF STATUS,C ;/2
RRF A1,F
RRF A2,F
RRF A3,F
RRF A4,F
BCF STATUS,C ;/2
RRF A1,F
RRF A2,F
RRF A3,F
RRF A4,F
MOVFF A4,VAL0 ;A->VAL
MOVFF A3,VAL1
MOVFF A2,VAL2
MOVFF A1,VAL3
CALL DCMAIN ;B->D 変換 答えはDEC0-9
MOVLW 2Fh ; DEC0-9 10進格納場所(10バイト)開示番地
MOVWF FSR
A INCF FSR,F
MOVF INDF,W
BTFSS STATUS,Z ;値が0(Z=1)でスキップ
GOTO CEND
MOVF FSR,W
SUBLW 36h ;36Hまでで終了
BTFSS STATUS,Z ;36hの場合(Z=1)でSKIP
GOTO A ;次を確認
CEND MOVFF INDF,DSP3 ;DEC->DSP へ複写 4桁
INCF FSR,F
MOVFF INDF,DSP2
INCF FSR,F
MOVFF INDF,DSP1
INCF FSR,F
MOVFF INDF,DSP0
DEND CLRF COUNTF ;以後CCPR終了処理
CLRF TMR1L
CLRF TMR1H
CLRF A2 ;TMR1 OVER CLR
CLRF A1
bsf STATUS,RP0 ;BANK1
BCF PIE1,CCP1IE ;チャプチャー割込禁止
BCF STATUS,RP0 ;BANK0
CLRF INT_C
RETURN
NEXT MOVFF CCPR1L,B4 ;OLD->B
MOVFF CCPR1H,B3
MOVFF A2,B2
CLRF B1
INCF COUNTF,F
RETURN
;---------------------------------------------------------------------
;32ビットバイナリ→10進変換
;valに32ビットデータを置く。(val3:val2:val1:val0)
;dcmainをコールする。 decに答えが格納される。
; (dec0:dec1:...:dec8:dec9)
;dec0が最上位桁でdec[9]が最下位桁です。 変換後valは破壊される。
dcmain
movLW 39H ; 格納場所初期値 DEC9
MOVWF FSR
call devide ; 最下位変換
call devide ;10回繰り返し
call devide
call devide
call devide
call devide
call devide
call devide
call devide
call devide ; 最上位変換
RETURN
; ÷10サブルーチン 10で除算します
devide MOVLW D'32'
MOVWF cn ; 32ビットくり返し
clrf val_m
devide0 BCF STATUS,C
RLF val0,F
RLF val1,F
RLF val2,F
RLF val3,F
RLF val_m,F
movlw b'11110110' ;F6H
addwf val_m,0
btfsc STATUS,c
movWF val_m
btfsc STATUS,c
incF val0,F
DECFSZ CN,F
GOTO devide0
decF fsr,F
MOVFF val_m,INDF ; 余り
RETURN
;*********************************************************************
; 32bit四則演算ルーチン PM=216/DM=15
;*********************************************************************
; 32bit除算ルーチン A÷B=A・・・B (call DIV32)
; 0エラーのときは、A,B ともに 0 クリア
; A1〜A4 割られる数 / 答え
; B1〜B4 割る数 / 余り 137〜3609命令
;---------------------------------------------------------------------
; 32bit乗算ルーチン AXB=AB (call MUL32)
; A1〜A4,B1〜B4 答えは 64bit 1639命令
;---------------------------------------------------------------------
; 32bit加算ルーチン A+B=A; (call ADD32)
; STATUS,C は正確/B は壊れない 38命令
;---------------------------------------------------------------------
; 32bit減算ルーチン A−B=A; (call SUB32)
; STATUS,C は正確/B は壊れない 77命令
A1 equ 50h ;割られる数上位
A2 equ 51h ; ↓
A3 equ 52h ; ↓
A4 equ 53h ;割られる数下位
B1 equ 54h ;割る数上位
B2 equ 55h ; ↓
B3 equ 56h ; ↓
B4 equ 57h ;割る数下位
W1 equ 58h ;ワーク1
W2 equ 59h ;ワーク2
W3 equ 5Ah ;ワーク3
W4 equ 5Bh ;ワーク4
Na equ 5Ch ;Aのシフト値
Nba equ 5Dh ;BとAのシフト値の差
Ctemp equ 5Eh
;---------------------------------------------------------------------
SET32:
movlw 0ffh ;割られる数上位 (ffffffffh=4294967295)
movwf A1 ; 〜
movlw 0ffh ; 〜
movwf A2 ; 〜
movlw 0ffh ; 〜
movwf A3 ; 〜
movlw 0ffh ; 〜
movwf A4 ;割られる数下位
movlw 0ffh ;割る数上位 (989680h=10000000)
movwf B1 ; 〜
movlw 0ffh ; 〜
movwf B2 ; 〜
movlw 0ffh ; 〜
movwf B3 ; 〜
movlw 0ffh ; 〜
movwf B4 ;割る数下位
return
DIV32:
clrf Na ;初期値をセット
clrf Nba
clrf W1
clrf W2
clrf W3
clrf W4
LOOPA:
btfsc A1,7 ;最上位bitまでループ
goto LOOPB ;最上位まできたら、次へ
bcf STATUS,C
rlf A4,f ;左シフトする
rlf A3,f
rlf A2,f
rlf A1,f
incf Na,f ;カウント加算
btfss Na,5 ;カウントが 32 か?
goto LOOPA ;ループ
goto ANSERR ;カウント値が 32 ならばエラー処理
LOOPB:
btfsc B1,7 ;最上位bitまでループ
goto NCHK ;最上位まできたら、次へ
bcf STATUS,C
rlf B4,f ;左シフトする
rlf B3,f
rlf B2,f
rlf B1,f
incf Nba,f ;カウント加算
btfss Nba,5 ;カウントが 32 か?
goto LOOPB ;ループ
goto ANSERR ;カウント値が 32 ならばエラー処理
NCHK:
movf Na,w ;Nbaを計算
subwf Nba,f
incf Nba,f
btfss STATUS,C ;Nbaが負なら
goto ANS1 ;ANSZへジャンプ
movf Nba,w
addwf Na,f
HOS32:
call SUB32
btfss STATUS,C
goto ADDH
LOOPH:
rlf W4,1 ;左シフトする(結果もシフトされる)
rlf W3,1
rlf W2,1
rlf W1,1
rlf A4,1 ;左シフトする
rlf A3,1
rlf A2,1
rlf A1,1
decf Nba,f
btfsc STATUS,Z
goto ANS1
btfsc A1,7 ;最上位までループ
goto HOS32 ;最上位まできたらHOS32へ
goto LOOPH
ADDH:
call ADD32
bcf STATUS,C
ADDHLOOP:
rlf W4,1 ;左シフトする(結果もシフトされる)
rlf W3,1
rlf W2,1
rlf W1,1
rlf A4,1 ;左シフトする
rlf A3,1
rlf A2,1
rlf A1,1
decf Nba,f
btfsc STATUS,Z
goto ANS1
call SUB32
bsf STATUS,C
btfsc A1,7
goto ADDHLOOP
goto LOOPH
ANS1:
bcf STATUS,C
rrf A1,f ;右シフトする
rrf A2,f
rrf A3,f
rrf A4,f
decfsz Na,f
goto ANS1
ANSS: ;解答をセットし終了
movf A1,w
movwf B1 ;余りをBにコピー
movf A2,w
movwf B2
movf A3,w
movwf B3
movf A4,w
movwf B4
movf W1,w
movwf A1 ;答えをAにコピー
movf W2,w
movwf A2
movf W3,w
movwf A3
movf W4,w
movwf A4
return
ANSERR: ;エラー処理
clrf A1 ;数値クリア
clrf A2
clrf A3
clrf A4
goto ANSS
SUB32:
call COM32 ;補数計算後、加算することにより減算する
call ADD32
call COM32
bcf STATUS,C
btfsc Ctemp,0
bsf STATUS,C
retlw 0
ADD32: ;32bit加算
bcf Ctemp,0
movf B4,w
addwf A4,f
movlw 1
btfsc STATUS,C
addwf A3,f
btfsc STATUS,C
addwf A2,f
btfsc STATUS,C
addwf A1,f
btfsc STATUS,C
bsf Ctemp,0
movf B3,w
addwf A3,f
movlw 1
btfsc STATUS,C
addwf A2,f
btfsc STATUS,C
addwf A1,f
btfsc STATUS,C
bsf Ctemp,0
movf B2,w
addwf A2,f
movlw 1
btfsc STATUS,C
addwf A1,f
btfsc STATUS,C
bsf Ctemp,0
movf B1,w
addwf A1,f
btfsc STATUS,C
bsf Ctemp,0
btfsc Ctemp,0
bsf STATUS,C
retlw 0
COM32:
comf B4,f
comf B3,f
comf B2,f
comf B1,f
movlw 1
addwf B4,f
btfsc STATUS,C
addwf B3,f
btfsc STATUS,C
addwf B2,f
btfsc STATUS,C
addwf B1,f
retlw 0
MUL32:
movlw 21h
movwf Na
movf A1,w ;Aをワークへ
movwf W1
clrf A1
movf A2,w
movwf W2
clrf A2
movf A3,w
movwf W3
clrf A3
movf A4,w
movwf W4
clrf A4
bcf STATUS,C
LOOPM:
rrf A1,f ;右シフトする
rrf A2,f
rrf A3,f
rrf A4,f
rrf W1,f
rrf W2,f
rrf W3,f
rrf W4,f
btfsc STATUS,C
call ADD32
decfsz Na,f
goto LOOPM
movf W1,w ;ワークからBへ
movwf B1
movf W2,w
movwf B2
movf W3,w
movwf B3
movf W4,w
movwf B4
return
END
プログラムです。バグがあったら訂正しますので連絡してください。
反省
クロックは20MHZを使用して精度を上げる。
1サイクルでカウントしているが、4サイクル位カウントして精度を上げたほうが良い。
他のプログラムを参考にして作成したので無駄な部分や意味の無い部分がたくさんあります。
普通のカウンターも組込み入力周波数により自動的に切り替えて表示する。
何方か改良してください。
5.347Hzを計測中です。