ストップウォッチ(16ビット版)(PIC24FJ64GA002)

概要

回路的にはシンプルですが、高性能(分解能1msec)なストップウォッチを製作しました。

動作原理

クロックには、32.00000MHzの高精度なクロックモジュールを使用しました。

正確な1msecを得る方法
TIMER1(16ビット)をフリーランで使用して、1msecを得ます。
TMR1とPR1がコンペアされTMR1がPR1に達すると割り込みが発生します。プリスケール値は、1/1とします。
PR1には、16000を設定します。
16000=1msec÷(1÷(32MHz÷2))

ストップウォッチの開始
単純にポートを監視し、立下りで、即開始します。

カウント
開始されると、先程の1msecの割り込み処理の中でカウント値をインクリメントします。

ストップウォッチの停止
外部割込み(立下り)で停止します。

回路図

ソースコード

//********************************************************************** /* 「簡易ストップウォッチ」 ＜DeviceFlags＞ _IESO_OFF _FNOSC_PRI _FCKSM_CSDCMD _OSCIOFNC_OFF _POSCMOD_EC _JTAGEN_OFF _GCP_OFF _GWRP_OFF _BKBUG_OFF _COE_OFF _ICS_PGx1 _FWDTEN_OFF */ //********************************************************************** #define LED PORTB.F6 #define START_SW PORTB.F8 #define STOP_SW PORTB.F7 //********************************************************************** static unsigned long cnt; static unsigned char flag; void Timer1Int() org 0x1A { IFS0bits.T1IF = 0; if (flag == 1) { cnt++; } } void External0Int() org 0x14 { IFS0bits.INT0IF = 0; flag = 2; // count stop! LED = 1; // LED off! } //********************************************************************** void main() { char buf[20]; // ADPCFG = 0xFFFF; // 全ピンをデジタルで使用する。 TRISA = 0b11111111; TRISB = 0b1111111110111111; CNPU1bits.CN7PUE = 1; // pull-up CNPU1bits.CN8PUE = 1; // pull-up // timer1(16bits) 1msecのタイマー割り込みに使う。 IPC0bits.T1IP0 = 1; IFS0bits.T1IF = 0; IEC0bits.T1IE = 1; T1CONbits.TCKPS0 = 0; T1CONbits.TCKPS1 = 0; T1CON.F15 = 0; PR1 = 16000; // 0.001/(1/(32MHz/2)) TMR1 = 0; // 外部割込み（External Interrupt Input）をカウントの停止に使う。 IPC0bits.INT0IP0 =1; IFS0bits.INT0IF = 0; IEC0bits.INT0IE = 1; INTCON2bits.INT0EP = 1; // 立下りで割り込み // Lcd_Custom_Config(&PORTB, 9, 10, 11, 12, &PORTB, 15, 14, 13); Lcd_Custom_Cmd(LCD_CURSOR_OFF); Lcd_Custom_Out(1, 1, "StopWatch"); Delay_ms(500); Lcd_Custom_Cmd(LCD_CLEAR); // T1CON.F15 = 1; // TIMER1 start! LED = 1; // LED off! // flag = 0; cnt = 0; // while(1) { if ((flag != 1) && (START_SW == 0)) { cnt = 0; flag = 1; // count start! LED = 0; // LED on! Lcd_Custom_Out(1, 1, "Start!"); } if (flag == 2) { Lcd_Custom_Out(1, 1, "Stop! "); flag = 0; } // LongWordToStr(cnt, buf); Lcd_Custom_Out(2, 1, buf); Lcd_Custom_Out(2, 11, "msec"); } } //**********************************************************************

動作確認

緑色スイッチがスタート、黄色スイッチがストップです。

左側:計測しているところです。秒以下は目では見えないです。 右側:停止したところです。1msecの単位まで分かります。