====== ストップウォッチ(16ビット版)(PIC24FJ64GA002) ====== ===== 概要 ===== 回路的にはシンプルですが、高性能(分解能1msec)なストップウォッチを製作しました。 ===== 動作原理 ===== * クロックには、32.00000MHzの高精度なクロックモジュールを使用しました。 * 正確な1msecを得る方法\\ TIMER1(16ビット)をフリーランで使用して、1msecを得ます。\\ TMR1とPR1がコンペアされTMR1がPR1に達すると割り込みが発生します。プリスケール値は、1/1とします。\\ PR1には、16000を設定します。\\ %%16000=1msec÷(1÷(32MHz÷2))%%\\ {{:imgpaste:202004:admin-20200430-183146.png}} * ストップウォッチの開始\\ 単純にポートを監視し、立下りで、即開始します。 * カウント\\ 開始されると、先程の1msecの割り込み処理の中でカウント値をインクリメントします。 * ストップウォッチの停止\\ 外部割込み(立下り)で停止します。 ===== 回路図 ===== {{:imgpaste:202004:admin-20200430-183214.png}} ===== ソースコード ===== //********************************************************************** /*   「簡易ストップウォッチ」  <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"); } } //********************************************************************** ===== 動作確認 ===== 緑色スイッチがスタート、黄色スイッチがストップです。 {{:imgpaste:202004:admin-20200430-183420.png?500}} {{:imgpaste:202004:admin-20200430-183428.png}}{{:imgpaste:202004:admin-20200430-183432.png}} 左側:計測しているところです。秒以下は目では見えないです。 右側:停止したところです。1msecの単位まで分かります。 {{:imgpaste:202004:admin-20200430-183440.png}}{{:imgpaste:202004:admin-20200430-183444.png}} このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。[[elechobby:picdic:picdic|詳細]] This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.[[elechobby:picdic:picdic|Details]]