質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

347閲覧

マイコンで外部からスタートコマンドが入ってきたらストップコマンドが来るまで処理を繰り返したい

sotooki

総合スコア15

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/06/11 10:02

前提・実現したいこと

マイコンであるdspicを利用し、UARTを用いて

①外部から'1'が受信されたら割り込み処理関数内のOnePoint()という関数が50msごとにループで動作し続ける
②'1'以外が受信されたらループが終了し、再度'1'が受信されるまで待機する

というプログラムを作成したい。

発生している問題・エラーメッセージ

プログラムは動作するのですが、スタートコマンドである'1'を外部から取得し、割り込み処理関数内のOnePoint();が動作すると取得波形に影響が及んでしまいます。
計測画面
割り込みのタイミングが問題なのではと推測しておりますが、対処法が分かりません。

一方、外部のプログラムを用いて50ms毎に'1'を連続的に送り続け、送られてくるタイミングごとにOnePoint();を動作させた際には波形に影響が出ませんでした。

しかし、外部から50ms毎に'1'を連続的に送り続けるシステムは時間精度が低いため、マイコン内部でOnePoint();を動かしたいです。

該当のソースコード(割り込み関数内でOnePoint();動作)

/***1point 関数***/ void OnePoint(void) { Red=0; WriteUART1((unsigned int)(0x02)); while(BusyUART1()); for(h=1; h<=2; h++) { WriteUART1((unsigned int)(0x41+((Vmin[h]>>12) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((Vmin[h]>>8) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((Vmin[h]>>4) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((fmin[h]>>8) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((fmin[h]>>4) & 0x000F))); while(BusyUART1()); WriteUART1((unsigned int)(0x41+((fmin[h]>>0) & 0x000F))); while(BusyUART1()); } WriteUART1((unsigned int)(0x03)); while(BusyUART1()); CRLF(); Red=1; } /*** タイマ1 割り込み処理関数 ***/ void __attribute__((__interrupt__, __shadow__))_T1Interrupt(void) { IFS0bits.T1IF=0;//割込みフラグクリア if(cmnd =='1') {OnePoint();}//1point送信 } /*** メイン関数 ***/ void main(void) { //初期設定省略 ///OnePoint();動作(0.05秒間隔) OpenTimer1(T1_ON & T1_GATE_OFF & T1_PS_1_256 & T1_SOURCE_INT , 5769);//50ms毎 ConfigIntTimer1(T1_INT_PRIOR_3 & T1_INT_ON); while(1) { while(!DataRdyUART1());  cmnd = ReadUART1(); }  }

該当のソースコード('1'が取得されるごとにOnePoint();動作)

/*** メイン関数 ***/ void main(void) { //初期設定省略 while(1) { while(!DataRdyUART1()); cmnd = ReadUART1(); ///受信コマンドの処理 switch(cmnd) { case'1': ///1point measure OnePoint(); break; case'2': break; default : break; } } }

補足情報(FW/ツールのバージョンなど)

dsPIC
MPLAB
c言語

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

OnPaint処理が50ms以上かかっているため、タイマー割込みが重なり、OnPaintが同時に2個以上実行されることはないでしょうか。

投稿2018/06/12 13:38

akiruno-oneone

総合スコア815

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

前回の質問からすると、やりたいことがそもそも、
周波数を電圧に変換するシステムがあって、
入力周波数をスイープして対応する出力電圧を求め、
電圧が最大になる周波数を求めたい。
ということかと思います。

となるとそもそもAD変換を一定間隔で行う必要もないので

  • 周波数を設定してAD変換する
  • これを必要な回数繰り返したら最大値などをシリアル送信する
  • 送信が終わったらまた最初に戻る

だけでいいです。割り込みとか必要ないです。

投稿2018/06/11 14:09

ozwk

総合スコア13521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

ふつう、そういうコードを組む場合、タイマ割り込みで50msを生成して周期実行させ、シリアルの送受信動作も、それぞれ割り込み駆動させるようにして、わざわざビジーループを待つようなことはしません。

それよりも、その入力波形に影響を及ぼしてるのは何かを特定することでしょうね
#A/D入力がバッファリングされてるdsPICの上位CPUに換装する、という選択肢はないんでしょうか

投稿2018/06/11 11:26

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sotooki

2018/06/11 13:05

すみません、上段に関して具体的にはどのようにプログラムを書き換えればよいのでしょうか。
y_waiwai

2018/06/11 13:15

1バイト受信した場合に割り込みをかけることができるので、割り込みルーチン内で受信データを読み出し、予め確保しているバッファにためていきます また、送信レジスタが空いた場合に割り込みをかけることができるので、予めバッファに展開しておいたデータ列を送信割り込みで順番に送信レジスタに設定していきます
sotooki

2018/06/11 13:30

いわんとすることは理解できるのですが、現状知識不足のためプログラムに書き起こすのが困難です。 もう少し学んでいきたいと思います。
sotooki

2018/06/11 13:31

いつもご回答ありがとうございます
y_waiwai

2018/06/11 13:53

CPUのデータシートやハードウエアマニュアルを擦り切れるほど「読む」ことですねー
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問