--- ver012/main.c 2013-01-08 09:39:48.000000000 +0900 +++ ver012kai_odo/main.c 2013-02-10 16:43:29.000000000 +0900 @@ -1,3 +1,32 @@ +// 自動車用スピードメータキット(走行距離計測機能追加版) +//2012/02/10 Ver012改(走行距離計測機能追加版) modified by disklessfun +//2011/11/21 Ver011改(走行距離計測機能追加版) modified by disklessfun +// ライセンスはADL(詳細はhttp://a-desk.jp/modules/forum_youbou/index.php?cat_id=4)です。 +// +// 標準ファームウェアの最高速表示モードの代わりに走行距離計測モードを設けます。 +// 最小表示距離は0.1kmで最大99.9kmまで表示できます。 +// 計測開始から100km以上走行した時点で一旦距離表示は0に戻ります。 +// +// ※(JP1 NC, JP2 NC)の通常の周波数を表示する設定時は距離の代わりに積算パルス数の千分の一を表示します。 +// +// 計測した走行距離に基づいて速度表示と距離表示を補正したい場合は、付属の表計算シートを用いて +// 補正を反映したパラメータ群を算出して下さい。白抜きの部分が(一般的に)変更可能な部分です。 +// +// 表計算シート上の「JIS定数&車速パルス変換係数の分子」と「JIS定数&車速パルス変換係数の分母」 +// を修正すると、それを反映した「補正率」と「CCP計測時の変換係数」と「INT0計測時の変換係数」が算出されます。 +// +// ※「分母」と「分子」とを総合した値には「637Xパルス倍数÷10に場合によっては補正を加味したもの」をセットします。 +// ※分母は計算中にオーバーフローしないように「(2^32/100/637)÷パルス倍数」以下にする必要があります。ただし +//  パルスの誤差(補正が必要な根拠)によってはもっと大きな値も実際には可能です) +// +// 「補正率」を確認した上で、表計算シートから、このファイル(main.c)のへcar_type_set構造体の所定部分に +// 「CCP計測時の変換係数」と「INT0計測時の変換係数」と「JIS定数&車速パルス変換係数の分子」と「JIS定数&車速パルス変換係数の分母」を +// コピーして下さい。 +// +// その他の変更によって他のパラメータが変更された場合はそれらもコピーして下さい。 +// +////////ここまではdisklessfunが追加したヘッダ//////////////////////////////////// + // 自動車用スピードメータキット // 2013/01/08 Ver012 brightness_disp変更時のチラツキをなくす為、バッファ化 // 2011/02/04 Ver011 num_disp_filtをlongに変更(オーバーフローを防ぐ為) @@ -45,6 +74,9 @@ #define PORT_DISP_HUD PORTAbits.RA6 //HUD表示の設定ピン #define PORT_DISP_REVERSE PORTAbits.RA7 //180度反転表示の設定ピン +#define T2_POST_DSM T2_POST_1_8 //8MHz時 +//#define T2_POST_DSM T2_POST_1_16 //16MHz時 + //コンフィグレーション設定 #pragma config OSC = INTIO67 #pragma config FCMEN = OFF @@ -79,7 +111,7 @@ void disp_led_op(unsigned char); void (*fun_disp_led)(unsigned char); -//車両のパルスタイプの違いのデータ +//車両のパルスタイプ毎のデータ(全て付属の表計算シートを用いて算出して下さい) const struct car_type_set { long num_CCP; //CCP計測時の変換係数 @@ -87,9 +119,22 @@ unsigned int num_INT0; //INT0計測時の変換係数 int speed_INT0_to_CCP; //INT0計測からCCP計測へ移る速度 int count_INT0_to_ZERO; //INT0計測から車速0モードへ移るカウント数 + int timer1_ps; //(CCP1用)TIMER1のプリスケーラ値 + int timer0_ps; //(INT0モード計測用)TIMER0のプリスケーラ値 + unsigned int jis_revice_numera; //JIS定数&車速パルス変換係数の分子 + unsigned int jis_revice_denomina; //JIS定数&車速パルス変換係数の分母 } car_type_set[] = { - {500000 ,1000 ,977,1440 ,1000}, //通常の周波数への変換(JP1 NC, JP2 NC) + {1000000,1024,1953,1365,1953,2,4,1000 ,1 }, //通常の周波数への変換(JP1 NC, JP2 NC) + {2825746,2816,5519,3755,5519,4,8,637 ,10}, //車速センサ1倍 (JP1 2-3,JP2 NC) + {1412873,1408,2760,1877,2760,4,8,1274 ,10}, //車速センサ2倍 (JP1 1-2,JP2 NC) + {1412873,1408,2760,1877,2760,2,4,2548 ,10}, //車速センサ4倍 (JP1 NC, JP2 2-3) + {706436 ,704 ,1380,939 ,1380,2,4,5096 ,10}, //車速センサ8倍 (JP1 2-3,JP2 2-3) + {706436 ,704 ,690 ,939 ,690 ,1,4,10192,10}, //車速センサ16倍(JP1 1-2,JP2 2-3) + {565149 ,563 ,552 ,751 ,552 ,1,4,12740,10}, //車速センサ20倍(JP1 NC, JP2 1-2) + {452119 ,454 ,442 ,606 ,442 ,1,4,15925,10}, //車速センサ25倍(JP1 2-3,JP2 1-2) + {847724 ,845 ,1656,1126,1656,2,4,12740,30}, //VW(JP1 1-2,JP2 1-2) +/* {500000 ,1000 ,977,1440 ,1000}, //通常の周波数への変換(JP1 NC, JP2 NC) {2825746,3840,5519,5120,5519}, //車速センサ1倍 (JP1 2-3,JP2 NC) {1412873,1920 ,2760,2560,2760}, //車速センサ2倍 (JP1 1-2,JP2 NC) {706436 ,1280 ,1380,1920 ,1380}, //車速センサ4倍 (JP1 NC, JP2 2-3) @@ -97,7 +142,7 @@ {176609 ,384 ,345 ,640 ,345 }, //車速センサ16倍(JP1 1-2,JP2 2-3) {141287 ,320 ,276 ,480 ,276 }, //車速センサ20倍(JP1 NC, JP2 1-2) {113030 ,256 ,221 ,384 ,221 }, //車速センサ25倍(JP1 2-3,JP2 1-2) - {423862 ,960 ,828 ,1440 ,828 }, //VW(JP1 1-2,JP2 1-2) + {423862 ,960 ,828 ,1440 ,828 }, //VW(JP1 1-2,JP2 1-2)*/ }; char car_type = 0; //車のパルスタイプ @@ -140,6 +185,11 @@ unsigned int timer_opening = 0; unsigned int timer_opening2 = 0; +//距離計測用 +unsigned char odd_mode = 0; //1で距離計測モードがON,0でOFF +unsigned long odd_counter = 0; //パルス数の生データ +unsigned long long_work; //unsigned long型作業変数 + void main() { unsigned int temp; @@ -172,7 +222,22 @@ car_type += ((int)(ReadADC()/342)) * 3; //タイマ1の設定(キャプチャ用) - OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_4 & T1_OSC1EN_OFF); +// OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_4 & T1_OSC1EN_OFF); + switch (car_type_set[car_type].timer1_ps) { + case 1: + OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_1 & T1_OSC1EN_OFF); + break; + case 2: + OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_2 & T1_OSC1EN_OFF); + break; + case 4: + OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_4 & T1_OSC1EN_OFF); + break; + case 8: + OpenTimer1(TIMER_INT_OFF & T1_16BIT_RW & T1_SOURCE_INT & T1_PS_1_8 & T1_OSC1EN_OFF); + break; + default:break; + } WriteTimer1(0); //キャプチャソースの設定(タイマ1を使用) T3CONbits.T3CCP1 = 0; @@ -180,9 +245,25 @@ OpenCapture1(CAPTURE_INT_ON & C1_EVERY_RISE_EDGE); //タイマ2の設定 (LED点灯用 1.024ms毎に割り込み) - OpenTimer2(TIMER_INT_ON & T2_PS_1_1 & T2_POST_1_8); +// OpenTimer2(TIMER_INT_ON & T2_PS_1_1 & T2_POST_1_8); + OpenTimer2(TIMER_INT_ON & T2_PS_1_1 & T2_POST_DSM); WriteTimer2(0); +//タイマ0の設定 (低速時用のパルス計測とモード判定用 8MHz時にはPS値x128μs毎に割り込み) + switch (car_type_set[car_type].timer0_ps) { + case 4: + OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_4); + break; + case 8: + OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_8); + break; + case 16: + OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_16); + break; + default:break; + } + WriteTimer0(0); + //INT0割り込み(低速時のパルス計測) INTCONbits.INT0IE = 1; INTCON2bits.INTEDG0 = 1; @@ -222,7 +303,7 @@ { //スピードメータ //INT0モード用車速計算 temp_hold_timer2 = hold_timer2; - if(temp_hold_timer2 != 0) //hold_timer2 == 0であった場合は極端に短いパルスであるので処理しない + if(temp_hold_timer2 != 0) //hold_timer2 == 0であった場合は極端に短いパルスもしくは車速0モードであるので処理しない culced_speed_INT0 = (car_type_set[car_type].num_INT0 * FILT_FACTOR) / temp_hold_timer2; //CCPモード用車速計算 // diff_hold_timer1は0とはならない。また、ここではオーバーフローも起こらないので除算のチェックを割愛 @@ -268,8 +349,28 @@ } //最高速表示 - if(!PORTCbits.RC7) - num_disp = max_speed; +// if(!PORTCbits.RC7) +// num_disp = max_speed; +//走行距離表示 + if(!PORTCbits.RC7){ + if (!odd_mode){ + odd_mode = 1; // 距離計測モードをON + odd_counter = 0; + } + + long_work = odd_counter; + long_work *= car_type_set[car_type].jis_revice_denomina; // JIS定数&車速パルス変換係数の分母を掛ける + num_disp = long_work / car_type_set[car_type].jis_revice_numera; // JIS定数&車速パルス変換係数の分子で + // 割る + + if (num_disp > 999){ + odd_counter = 0; // 100km走行する毎に距離表示は0に戻る + num_disp = 0; + } + }else{ + if (odd_mode) + odd_mode = 0; // 距離計測モードをOFF + } //7segLED表示用データ作成 put_led[0] = num_disp % 10; @@ -304,6 +405,8 @@ LATCbits.LATC3 = !LATCbits.LATC3; //パルス出力ポートの値をトグルする devide_counter = PULSE_DEVIDE; } + + odd_counter++; // 走行距離の計測 } if(INTCONbits.INT0IF) @@ -320,12 +423,9 @@ } } - if(PIR1bits.TMR1IF == 1) - PIR1bits.TMR1IF = 0; - - if(PIR1bits.TMR2IF) - { //タイマ2割り込み LEDのダイナミック点灯 - PIR1bits.TMR2IF = 0; + if(INTCONbits.TMR0IF) + { //タイマ0割り込み + INTCONbits.TMR0IF = 0; //INT0モード用のタイマ timer2_count++; @@ -335,6 +435,23 @@ culced_speed_INT0 = 0; culc_mode = CULC_ZERO; } + } + + if(PIR1bits.TMR1IF == 1) + PIR1bits.TMR1IF = 0; + + if(PIR1bits.TMR2IF) + { //タイマ2割り込み LEDのダイナミック点灯 + PIR1bits.TMR2IF = 0; + +////INT0モード用のタイマ +// timer2_count++; +// if(timer2_count >= car_type_set[car_type].count_INT0_to_ZERO) +// { //車速0モードへ +// timer2_count = 0; +// culced_speed_INT0 = 0; +// culc_mode = CULC_ZERO; +// } //オープニングモード timer_opening++;