2016-09-18
クロック周波数を1/1000にして出力する回路を作る。分周するときはタイマー2を使う。PICのタイマーは水晶の1/4の周波数でカウントする。タイマーの出力で信号を変化させるのでここで1/2になる1/1000にするためにはタイマーで1/125分周すればよい。プリスケーラ、ポストスケーラ共に1:1(分周なし)でPR2に124を設定すれば1/125分周される
同じ回路をブレッドボードで何度も組むのは面倒なので基板を作った
16MHz水晶を1/1000した周波数を計測。16MHz水晶なら16kHzが出力される
Mercury製の16MHz水晶(秋月電子で売っているもの)
1/1000分周した出力
中国製の水晶の精度を計測してみた。両グラフ共に縦軸目盛の間隔は合わせてある。グラフ中央が絶対誤差ゼロ。絶対制度は秋月のほうが3割程度良い。秋月の物は5個しか在庫がなかったのでサンプル不足でばらつき誤差は不明。この5個だけで判断するとばらつきは秋月のほうが1桁小さいが中国製も5個だけ抜き出せば同程度のばらつきになる可能性が高いので何とも言えない
中国製16MHz 30個程度を抜き出してテスト
中国製16MHz
秋月電子で売っているもの
回路図。今後のためにLEDと抵抗を入れてある。現時点の1/1000分周器では使用されていない
プログラム
0001 '-------------------------------------------------------------- 2016-09-18 -----
0002 ' XTAL test program
0003 '-------------------------------------------------------------------------------
0004 program XTAL_TEST
0005
0006 symbol PORT_OUTPUT = 0
0007 symbol PORT_INPUT = 1
0008
0009 '---- TMR2 ---------------------------------------
0010 symbol Timer2_overflowed = TMR2IF_bit
0011 symbol Timer2_interrupt_enable = TMR2IE_bit
0012 symbol Timer2_period_register = PR2
0013 symbol Timer2_enable = TMR2ON_bit
0014 symbol Timer2_postscale_bit0 = T2OUTPS0_bit
0015 symbol Timer2_postscale_bit1 = T2OUTPS1_bit
0016 symbol Timer2_postscale_bit2 = T2OUTPS2_bit
0017 symbol Timer2_postscale_bit3 = T2OUTPS3_bit
0018 symbol Timer2_prescale_bit0 = T2CKPS0_bit
0019 symbol Timer2_prescale_bit1 = T2CKPS1_bit
0020
0021 '---- interrupt -------------------------------------
0022 symbol interrupt_enable = GIE_bit
0023 symbol peripheral_interrupt_enable = PEIE_bit
0024
0025 symbol LED1_TRIS = TRISB4_bit
0026 symbol LED1_PORT = LATB4_bit
0027
0028
0029 dim val1 as byte
0030
0031 '===============================================================================
0032 ' Interrupt routine
0033 '===============================================================================
0034 sub procedure interrupt
0035 if Timer2_overflowed then
0036 Timer2_overflowed = false
0037 val1 = not val1
0038 LED1_PORT = val1
0039 end if
0040 end sub
0041
0042 '*******************************************************************************
0043 ' Program main
0044 '*******************************************************************************
0045 main:
0046 '---- TMR2 --------- output 1/1000 --------------------------
0047 Timer2_interrupt_enable = FALSE
0048 Timer2_enable = TRUE
0049 Timer2_period_register = 124
0050 Timer2_prescale_bit0 = 0 ' prescale is 1:4
0051 Timer2_prescale_bit1 = 0
0052 Timer2_postscale_bit0 = 0 ' postscaler 1:1
0053 Timer2_postscale_bit1 = 0
0054 Timer2_postscale_bit2 = 0
0055 Timer2_postscale_bit3 = 0
0056
0057 ANSELA = 0x0 ' PORT A Digital I/O
0058 ANSELC = 0x0 ' PORT C Digital I/O
0059
0060 LED1_TRIS = PORT_OUTPUT
0061 LED1_PORT = 0
0062 Timer2_interrupt_enable = true
0063 peripheral_interrupt_enable = true
0064 interrupt_enable = true
0065
0066 while( true)
0067 wend
0068 end.
0069 '---------------- E N D --------------------------------------------------------
行番号
解説
46-55行目
タイマー2でタイマーの入力クロックを1/125にする
37-38行目
LED1のポートをトグル動作。分岐命令を使うとクロックのデューティーが50%でなくなるのでNOT命令で反転出力する