マイコン、電気回路初心者です。 h8 3052で回転計を作製をしたいのですが・・・知識を貸していただきたいです
マイコン初心者です。。。
h8 3052で回転計を作製をしたいのですが・・・知識を貸していただけたら幸いです。
回転数を算出の式として次を用いたいと思います(精度はあまり気にしないでください。。。)
回転数[rpm]=60[sec]/1回転に要する時間[sec]
リードスイッチとマグネット4つを使い回転数を算出したいと思っています。
リードスイッチが4つカウントしたときの時間(1回転に要する時間)を上の式の分母(t)に入れ演算させたいです。
ITUのタイマー割り込みを使い分母の時間をカウントをしカウントが4のときt=0と考えてました。
しかし、カウントを迎えてもtは永遠に1ずつ足され続け0に戻りません。 プログラムの考え方が違うのでしょうか?
使用環境からロータリーエンコーダ、フォトトランジスタなどが使えません。
チャタリングについては、本からRC積分回路(0.1μFとVccに10KΩ)使い、そこからさらに74HC04通してつかっているのですが・・・見よう見まね状態です。
開発環境はHEWを使っています。
勉強不足だと思いますが、10日くらい悩んでいます。力を貸してください。よろしくお願いします。
僕が立てたプログラムは次の通りです。
vector 12 IRQ0 (リードスイッチ 立下りエッジで割り込み要求)
__interrupt(vect=12) void INT_IRQ0(void)
{
count++;
INTC.ISR.BIT.IRQ0F=0;
}
vector 28 IMIA1
__interrupt(vect=28) void INT_IMIA1(void)
{
ITU1.TSR.BIT.IMFA = 0;
taco_interrput-=1;
if(taco_interrput==0)
{
t++;
}
taco_interrput=1;
}
void main()
{
set_imask_ccr(1); //割り込み禁止
INTC.ISCR.BIT.IRQ0SC=1; //タコメータ 入力立下りエッジで割り込み発生
INTC.IER.BIT.IRQ0E=1; //IRQ0割り込み許可(タコメータ)
ITU1.TCR.BIT.CCLR=1; //ITU1カウンタクリア要因
ITU1.TCR.BIT.TPSC=3; //ITU1 3.125MHz
ITU1.GRA=3125-1; //ITU1 3.125MHz/3125=1000Hz、周期1ms(0からカウントされるため必ず-1)
ITU1.TIER.BIT.IMIEA = 1; //ITU1 IMFAフラグによる割り込み許可
ITU.TSTR.BIT.STR1=1; //ITU1タイマスタート
taco_interpput=1; //ITU(imia)割り込み回数1 割り込み先で1に戻るので無限
while(1)
{
if(count==4)
{
time=t;
t=0;
count=0;
n=60[sec]/time;
}
if(count>4) //カウントが4より大きくなってしまったとき
{
t=0;
count=0;
}
}
}
(LCDのプログラムは長いので省きました)
LCDの液晶を使い以下のことは確認をしています。
・カウントが4を迎えたときカウントは0に戻っています。(IRQのカウントのことです)
・カウントを何回与えてもtが0に戻りません。なので演算されてないです。(tは永遠に1ずつ足され続けてます)
回転数の使う範囲は50~200rpmです。
tのカウントを0に戻す記述をどうしたいいのかよろしくお願いします。
A 回答 (10件)
- 最新から表示
- 回答順に表示
No.10
- 回答日時:
No.9 お礼への回答です。
cShiftReg に staticが付いているので初期値は0 です。
とゆうより、まともなパワーオンルーチンが働けば 0で初期化されます。
わざわざ関数内に cShiftReg を置いているのは、他の関数ではこれを
触る必要もないし、触ってもらっては困るので、他の関数からは見えない
ようにしているわけです。
P8-0が1の場合1msごとにcShiftRegの内容は以下のように変わって行きます。
0000,0000
0000,0001
0000,0011
0000,0111 <---- ここでHIと判定される
0000,1111
0 になる場合は、自分で考えて下さい。
いずれにしても3ms間 1/0が連続しないと判定がひっくり返らないので
チャタリングレスになります。
大変遅くなり申し訳ございません。
分かりやすい解説ありがとうございます。誤検知はされないでなんとかできました!
いろいろとお世話になりました。またなにか機会ありましたらよろしくご教授よろしくお願いします。
No.9
- 回答日時:
以下は1msタイマー割込みでP8-0をチェックするようにしてあります。
main()で何もしない場合、IRQ0によるcountの値とnShiftCountの値が
+/- 1 以内であればcountは正しくカウントされています。
なお入力のチャタリングが5msなら、5ms間隔、10msなら10ms間隔で
入力をチェックするようにするとCRを付けなくてもチャタリングの影響
が除けます。
---------------------------------------------------------------------
#include "iodefine.h"
typedefunsigned charuchar;
volatileintnShiftCount;
volatileintcount;
volatileinttaco_interrput;
volatileintt;
#defineSHIFT_AND0x07
__interrupt(vect=12) void INT_IRQ0(void)
{
count++;
INTC.ISR.BIT.IRQ0F=0;
}
/* vector 28 IMIA1 */
__interrupt(vect=28) void INT_IMIA1(void)
{
/*----------------------------------------*/
staticucharcShiftReg;
staticucharcOldP8_0;
ucharcAndValue;
/*----------------------------------------*/
ITU1.TSR.BIT.IMFA = 0;
taco_interrput-=1;
if(taco_interrput==0)
{
t++;
}
taco_interrput=1;
/* ------ シフトにより連続1/0確認 ------ */
cShiftReg <<= 1;
if (P8.DR.BIT.B0) {/* 現在はHI ?*/
cShiftReg |= 0x01;
}
cAndValue = cShiftReg & SHIFT_AND;
if (cAndValue == SHIFT_AND) {
/* 完全なHI*/
if (cOldP8_0 == 0) {
cOldP8_0 = 1;
/* 必要なら立ち上がりの処理*/
}
}
if (cAndValue == 0) {
/* 完全なLOW*/
if (cOldP8_0) {
cOldP8_0 = 0;
nShiftCount++;
}
}
}
チェック用のプログラムまで作製していただけるとは・・・なんとお礼をしたらよいか。。。実家がペンションで、ご招待したいぐらいです!
ひとつわからないことがあります。
ビット演算子のところを読みながらこのプログラムを見ています。cShiftRegには、もともとどうゆう値が入っているのでしょうか?それに0が1つ補充されORを取るとなど・・・あとは本を見ながらなんとなくですが理解できるのできるのですが。。。
No.8
- 回答日時:
No.6回答へのお礼に対する書込みです。
オシロスコープの写真見ました。
チャタリングは完全に取れています。
小信号用のリードリレーの動作時間は1ms以下のようなので
CRの値は適当であったようですね。
IRQ入力にしているので、CRを付けたのでしょうが、通常の入力ポートに
スイッチを付けた場合の例を明日アップします。
何度も、協力していただきチェックまでしていただきありがとうございます。
私は機械科ですが、丁寧に教えていただいてるため最近電気のことや情報処理ができてきて大変楽しい毎日を過ごさせていただいてます。
No.6
- 回答日時:
74HC14入力波形ですが
━━┓ ┏━━━ 5V
┃ ┃
┃ ┃
┗━━━┛ 0V
↑ ↑ フォントの関係で絵がうまくいきません
正しい絵を推測して下さい。
↑の部分がCRによりなまっているでしょうが、途中に山や
谷が無ければ大丈夫です。
また、途中に山/谷が有ったとしてもVIH 2.53[v]とVIL 1.25[v]
の間を往復していなければ大丈夫です。
74HC14とH8/3052 P8-0,1,2入力はヒステリシスを持っているので
多少のノイズは有ってもかまいません。
なお、電圧値は東芝TC74HC14APの値です。
使用しているメーカのデータシートで確認して下さい。
オシロスコープで入力波形を観測したら最高回転数時のLOWレベル
時間を答えて下さい。
リードスイッチ割り込み回数確認の方法を示す事が出来ます。
大変、遅くなりました。申し訳ございません。
アナログのオシロスコープしかなくデジタルのあるところで波形を止めて観測しました。
http://album.yahoo.co.jp/photos/1672401/4768587/
ウェブアルバムに保存したので、見ていただけたらありがたいです。
常に使いたい回転数が約120rpmであり、その回転数あたりの波形です。 マグネットなんですが大きさを間違えて注文してしまったため、吸着力が弱くリードスイッチが反応しませんでした。なのでマグネットが一つの時の波形しかとれませんでした。
オシロスコープを使ったのが今回で2回目なので、ほんと初心者ですが・・・きれいな波形になったと思うのですがどうなんでしょうか?
No.4
- 回答日時:
>(0.1μFとVccに10KΩ)
測定もせずに勘でやるなら、この程度で適当です。
CRの積が大き過ぎると、スイッチの開閉周波数が高くなるとカウントしなくなる。
CRの積が小さすぎるとチャタリング除去の効果が無い。
オシロが有れば74HC14の入出力波形を見れば、適当かどうか分かります。
スイッチまでの配線が長いと外部ノイズでカウントするかも知れない。インダクタンス分を生じて振動するかも知れない。その場合は、スイッチに直列に100Ωぐらいを入れれば良いでしょう。この抵抗は、コンデンサの急激な放電を制限する働きも有ります。
再度、ご教授ありがとうございます。
Cの容量ばかりを気にしていました。 インダクタンス分を生じて振動した場合、10kを100に落とすということでいいのでしょうか?勉強不足で申し訳ございません・・・電流が変わると磁束が変化し逆起電力を誘導するために抵抗を下げるということでいいのでしょうか?
またNo.2の回答のお礼に載せたとおりにプログラムを載せたところ(空白を合わせたつもりが、見にくくてすみません) 判別したところできたのですが、処理が途中で止まってしまいフリーズ状態になってしまいます。 アドバイスとしてvolatile宣言をもらったのですが、調べたのですが使い方と最適化がわからないのですが、どう解釈したらいいのか教えていただければ幸いです。
度々の質問お許しください。
No.3
- 回答日時:
大ざっぱなヒントだけです。
・周波数が高ければ周波数を測定する。
・周波数が低ければ、周期の逆数で周波数を求める。
・チャタリングの所は74HC04ではなく、74HC14を使う。
オシロで測ってみないと、適正なCRの値か分からない。
・リードスイッチがどの位の周波数まで応答するのか注意。
・簡単な実験回路ならリードスイッチでも良いでしょうが、本格的にやるのなら、近接スイッチを使います。
ご回答、ご指摘ありがとうございます。
機械科なため、わからないことだらけでアドバイスなどとても感謝しています。
周波数=1/周期 というのはわかるのですが、オシロで見てどのような形の波形までになればいいのか教えていただければありがたいです。
74HC14はさっそく使ってみます。
今後ともまたよろしくお願いします。
No.2
- 回答日時:
No.1の回答は無視して下さい。
リードスイッチオン1回で count が+1される事は確認されている
でしょうから、t,countをvolatile宣言してみるとか。............
ご回答ありがとうございます。いろいろあれからやってみたところ次のようにやってなんとか動きました。
vector 28 IMIA1
__interrupt(vect=28) void INT_IMIA1(void)
{
ITU1.TSR.BIT.IMFA = 0;
taco_interrput-=1;
if(taco_interrput==0)
{
t++;
a-=1;
}
void main()
{
a=1;
while(1)
{
if(a==0)
{
a=1;
if(count==4)
{
time=t;
t=0;
count=0;
n=60[sec]/time;
}
if(count>4&&t>3000)//カウントが4より大きくなってしまったとき
{
t=0;
count=0;
}
}
}
}
新しくaという変数を作り、while文よりしたのものをaに対するif条件を作りくくりまして、割り込んだ先でa=0にしました。そうしたところ、判別というのでしょうか・・・表現の仕方がわからないんですけど、今どちらの関数にいるのかを明確にしたところt=0になりました。
ただ、まだ不完全であるらしく処理が止まってしまうことがあります。ここで、バグといえばいいのでしょうか?処理を止めてしまう要因はどの辺にあたるのかご指摘あればよろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# ある線が円の範囲に入っているかの計算 1 2022/12/07 16:14
- Visual Basic(VBA) Sheet1の出荷日と品名が並んだ表からSheet2の品名別出荷日別の個数一覧表を作っています。 オ 3 2022/12/01 23:54
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- Visual Basic(VBA) Sheet「状況」から、分類の年齢別カウント数をSheet「D表」へ転記する下記マクロを作っています 7 2022/12/14 17:57
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- Visual Basic(VBA) Sheet2からオートフィルターで売上日を抽出した件数をカウントし、その件数をSheet1のセルB1 2 2023/01/12 12:24
- Excel(エクセル) マクロ/VBAについて教えてください。 10 2022/05/27 12:59
- C言語・C++・C# C言語 3 2022/11/09 13:27
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PICの入出力切り替えの時間がプ...
-
SHマイコンについて
-
0xffffとは?
-
エクセルVBAのIf,Then 構...
-
8ビットのデータの、先頭ビット...
-
レジストってなんですか?
-
ライン数とステップ数の違いは?
-
ビットシフトってどんな時使うの?
-
コンピュータ言語とプログラミ...
-
PICのC言語でキャリーオーバー
-
[C言語→アセンブリ言語]はどう...
-
CASL(アセンブラ言語)に関する...
-
算術シフト演算が成り立つ理由...
-
Delphiでのメモリリーク検出
-
アセンブラからC言語に変換する...
-
シーケンサのデータレジスタD...
-
実行ファイルからソースはみれる?
-
CASLIIでかけ算
-
GCCの.cfi_系について
-
本気でマシン語を覚えたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
PICでパルス数をカウントする方法
-
PICでパルス数をカウントし、カ...
-
PICマイコンを使った分解能1μs...
-
C言語によるウェイト
-
マイコンのCCRのIビット
-
PICの入出力切り替えの時間がプ...
-
入力回数のカウントをする方法
-
シリアル通信のデータ受信につ...
-
H8を利用したPWMのパルス生成に...
-
PICでスピードメーターを作...
-
RTCの通信方法(I2C、S...
-
組み込みマイコンの誤動作について
-
H8/3069Rでパルス時間間隔測定
-
0xffffとは?
-
エクセルVBAのIf,Then 構...
-
8ビットのデータの、先頭ビット...
-
情報科学の飽和演算、ラップア...
-
ビットシフトってどんな時使うの?
-
ライン数とステップ数の違いは?
-
アセンブラからC言語に変換する...
おすすめ情報