自作タコメーターとりあえずは完成
長い間放置していた自作タコメーターを完成させました。
物はこんな感じ

PIC16F648Aを用いて7セグLEDで回転数を表示させるようにしています。
7セグの下二桁は0で固定して、変化させるのは100回転より上の領域にしています。
回路図はこんな感じ

プログラムはcc5xcで作成
ソースはこんな感じ
実際に動かしてみたのがこれ
タコメーター動作動画
500ms毎の更新なのでちょっと反応が鈍い
7セグダイナミックドライブなので動画を撮ってもまともに見えない・・・・・・
やっていることは単純で
CDIのタコ信号を取得、これをPICのINT割込み(頭痛が痛いみたいな表記になった))に繋ぎ
タイマー0で500ms毎に回転数をカウント
これを120倍させてRPMを取得
それぞれの桁を分解して7セグで表示
こんな感じです。
PICの割り込みがシュミットトリガー入力なのが何気に便利です。
そして、何よりも
ウェブリブログがリニューアルしてから
ソースコードの字下げが反映されるようになったのが凄い助かります。
これができないせいで、今までどれだけ記事の投稿を諦めたことやら
物はこんな感じ
PIC16F648Aを用いて7セグLEDで回転数を表示させるようにしています。
7セグの下二桁は0で固定して、変化させるのは100回転より上の領域にしています。
回路図はこんな感じ
プログラムはcc5xcで作成
ソースはこんな感じ
/********************************************************************/
/* */
/* PICテスト用プログラム */
/* 作成者:M.Sato */
/* 作成日:19年10月20日 */
/* 概要 :cc5xで単機能タコメーター作成 */
/* device:16F648A */
/* */
/********************************************************************/
//#include "..\16F648A.H"
#include "..\int16cXX.h"
#pragma config = 0X3F18 // //OSC:内蔵クロック WDT:OFF PUT:OFF MCLRE:無効(RA5入力ピンとして使用)
//ブラウンアウトリセット:禁止 LVP:禁止 CP、CPD:プロテクト オフ
// 11111100011000
#pragma origin 4 //割り込みベクターアドレスを&h04に指定
#pragma chip PIC16F648A
#define TRUE 1
#define FALSE 0
unsigned long g_cnt;
unsigned long g_cnt2;
int in_flg;
int g_flg;
int g_flg2;
int tmp1;
unsigned long g_tacho_cnt;
/********************************************************************/
/* */
/* 割り込み処理 */
/* */
/* 10-02/01 */
/********************************************************************/
interrupt int_serverX( void)
{
int_save_registers // W STATUS PCLATHを保存
if (T0IF) { // タイマー0オーバーフロー
// TMR0 = 0;
g_cnt++;
if (g_cnt == 39){ // 10ms 1クロック=0.25μs TMR0カウント=4クロック=1μs
// TMR0オーバーフロー=256カウント=256μs ×39=9.984ms≒10ms
g_cnt2++;
g_cnt = 0;
if (g_cnt2 == 50){ // 500ms
g_flg2 = 1;
g_cnt2 = 0;
}
}
T0IF = 0; // reset flag
}
if (INTF) { // INT/RB0割り込み発生
g_tacho_cnt++;
INTF = 0;
}
int_restore_registers // W STATUS PCLATHを復帰
}
/********************************************************************/
/* */
/* pause */
/* */
/* 06-03/27 */
/********************************************************************/
void pause(long t)
{
unsigned long d, i;
while( t ) {
for(d = 0 ; d < 255 ; d++ );
t--;
}
} // end pause
/********************************************************************/
/* */
/* 表示0 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg0()
{
PORTB &= 0x01;
PORTB |= 0x80;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示1 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg1()
{
PORTB &= 0x01;
PORTB |= 0xf2;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示2 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg2()
{
PORTB &= 0x01;
PORTB |= 0x48;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示3 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg3()
{
PORTB &= 0x01;
PORTB |= 0x60;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示4 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg4()
{
PORTB &= 0x01;
PORTB |= 0x32;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示5 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg5()
{
PORTB &= 0x01;
PORTB |= 0x24;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示6 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg6()
{
PORTB &= 0x01;
PORTB |= 0x04;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示7 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg7()
{
PORTB &= 0x01;
PORTB |= 0xb0;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示8 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg8()
{
PORTB &= 0x01;
PORTB |= 0x00;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示9 */
/* */
/* 06-03/27 */
/********************************************************************/
void seg9()
{
PORTB &= 0x01;
PORTB |= 0x20;
pause(2);
return;
}
/********************************************************************/
/* */
/* 表示o */
/* */
/* 06-03/27 */
/********************************************************************/
void seg_o()
{
PORTB &= 0x01;
PORTB |= 0x46;
pause(2);
return;
}
/********************************************************************/
/* */
/* 7セグ動作確認 */
/* */
/* 2019-10/20 */
/********************************************************************/
void initSeg()
{
unsigned int i, j, v, vw[3];
unsigned long n;
v = 0;
for (i = 0; i < 3; i++){
vw[i] = 0;
}
for (i = 0; i <= 9; i++){
vw[0] = i;
vw[1] = i;
vw[2] = i;
for (n = 0; n < 15; n++){
for (j = 0; j < 3; j++){
switch (j){
case 0:
PORTA = 0x01;
break;
case 1:
PORTA = 0x02;
break;
case 2:
PORTA = 0x04;
break;
}
switch (vw[j]){
case 0:
seg0();
break;
case 1:
seg1();
break;
case 2:
seg2();
break;
case 3:
seg3();
break;
case 4:
seg4();
break;
case 5:
seg5();
break;
case 6:
seg6();
break;
case 7:
seg7();
break;
case 8:
seg8();
break;
case 9:
seg9();
break;
}
}
}
}
}
/********************************************************************/
/* */
/* メインルーチン */
/* INTEはこのバージョンでは初期化すると固まるらしい */
/* 2010-03/2 */
/********************************************************************/
void main()
{
long x;
long y;
long i;
int vw[3];
unsigned long cnt, cnt1, cnt2, cnt3, n, tmp;
int j;
OSCF = 1; // 内蔵4MHz
TRISA = 0x00; // ポートAは全て出力
TRISB = 0x01; // ポートBはRB0:入力 RB1~RB7:出力
CMCON = 0x07; //アナログコンパレータをOFF。
OPTION = 0xc8; // 内蔵プルアップを使用しない
// RB0立ち上がりエッジ
// タイマー0は内部クロック使用
// プリスケーラはWDTへ割り当て
GIE = 1; // 全ての割り込み発生を許可
T0IE = 1; // TMR0割り込みを許可
g_cnt = 0;
g_cnt2 = 0;
cnt = 0;
in_flg = 0;
g_flg = 0;
g_flg2 = 0;
PORTA = 0;
PORTB = 0;
cnt1 = 0;
cnt2 = 0;
cnt3 = 0;
x = 0;
y = 0;
g_tacho_cnt = 0;
for (i = 0; i < 3; i++){
vw[i] = 0;
}
initSeg(); // 7セグ動作確認処理。上3桁を000~999まで表示します
while (1){
if (g_flg2 == 1){
cnt = g_tacho_cnt * 120; // 500ms × 120 = 60秒
cnt1 = (cnt % 1000) / 100;
tmp = cnt % 10000;
cnt2 = tmp / 1000;
cnt3 = cnt / 10000;
vw[0] = cnt1;
vw[1] = cnt2;
vw[2] = cnt3;
g_tacho_cnt = 0;
g_flg2 = 0;
}
for (j = 0; j < 3; j++){
switch (j){
case 0:
PORTA = 0x01;
break;
case 1:
PORTA = 0x02;
break;
case 2:
PORTA = 0x04;
break;
}
switch (vw[j]){
case 0:
seg0();
break;
case 1:
seg1();
break;
case 2:
seg2();
break;
case 3:
seg3();
break;
case 4:
seg4();
break;
case 5:
seg5();
break;
case 6:
seg6();
break;
case 7:
seg7();
break;
case 8:
seg8();
break;
case 9:
seg9();
break;
}
}
}
}
実際に動かしてみたのがこれ
タコメーター動作動画
500ms毎の更新なのでちょっと反応が鈍い
7セグダイナミックドライブなので動画を撮ってもまともに見えない・・・・・・
やっていることは単純で
CDIのタコ信号を取得、これをPICのINT割込み(頭痛が痛いみたいな表記になった))に繋ぎ
タイマー0で500ms毎に回転数をカウント
これを120倍させてRPMを取得
それぞれの桁を分解して7セグで表示
こんな感じです。
PICの割り込みがシュミットトリガー入力なのが何気に便利です。
そして、何よりも
ウェブリブログがリニューアルしてから
ソースコードの字下げが反映されるようになったのが凄い助かります。
これができないせいで、今までどれだけ記事の投稿を諦めたことやら
"自作タコメーターとりあえずは完成" へのコメントを書く