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

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

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

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

Q&A

解決済

6回答

2286閲覧

無限ループが中にある場合にfor文で繰り返し処理を行う方法

Merrifield

総合スコア31

C

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

0グッド

0クリップ

投稿2020/06/09 00:01

下記のプログラムの部分はPWM制御に関するプログラムの一部です。この部分を、STM_MINI()に、増加していく値を代入させながら、、for文で繰り返し処理を行うことを考えています。for文で処理を行おうとしても、途中でwhile(1)の無限ループのようなものがあり、そこで処理が止まってしまうのですが、どのようにして繰り返し処理を行えばよいでしょうか?下記の部分をSTM_MINI()に値を代入させながら、繰り返し処理が出来ればよいので、for文でなくても、なにか別のよい方法があれば教えてください。

  STM_MINI(); /* Initial Setting */ STM_MSTT(); /* Operation Start */ /* main loop */ while(1) {    WDTE = 0xac; /* watchdog timer counter clears and restarts */   } STM_MSTP(); /* Operation Stop */

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

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

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

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

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

thkana

2020/06/09 03:37

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12226501897 https://teratail.com/help#posted-otherservice によると、 「やむを得ず複数のサイトに質問を投稿された場合は、質問内容にマルチポストをする理由を書き、他のサイトの投稿へのリンクを貼ってください。また、解決した際には必ずteratail及びすべての投稿に解決した旨と、どのように解決したかを記載してください。」 とのことです。解決は未だのようですが、マルチポストする理由は今でも追記できますね。
thkana

2020/06/09 03:45

> STM_MINI()に、増加していく値を代入させながら STM_MINI()は変数ではないので「代入」できません。 ググったらルネサスのドキュメントがひっかかりましたが、それによれば、関数です。
guest

回答6

0

詳細がわからないですが、見たところ組み込み系に近い作りと思われます。
たいていの場合、無限ループの処理の中で目的の処理を行いますので、無限ループの外に処理を置くのは間違っています。
よって次のようにウォッチドッグの処理の前後(以下のサンプルはうしろ)に処理を追加してみてください。

c

1STM_MINI(); /* Initial Setting */ 2STM_MSTT(); /* Operation Start */ 3 4/* main loop */ 5while(1) 6{ 7 WDTE = 0xac; /* watchdog timer counter clears and restarts */ 8 9 /* 10 * ここに処理を書く 11 */ 12} 13 14STM_MSTP(); /* Operation Stop */ 15

投稿2020/06/09 00:31

ttyp03

総合スコア17000

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

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

Merrifield

2020/06/09 00:44

質問文で書いたコード自体が目的の処理で、質問文には書いていないですが無限ループの中に組み込んでいます。STM_MINIが初期設定の部分なので、ここでデューティー比を変化させて、繰り返し処理を行いたいのです。
ttyp03

2020/06/09 01:08 編集

デューティー比とか言われてもわかりませんが。。。 であるなら、無限ループの中で初期設定とかやればいいのでは? while(1){  WDTE = 0xac;  for(ループ条件){   STM_MINI();   STM_MSTT();  }  その他の処理 } STM_MSTP(); ※インデントのために全角空白使ってます。
guest

0

この部分を、STM_MINI()に、増加していく値を代入させながら、、for文で繰り返し処理を行うことを考えています。

この部分の処理の考え方がずれているのではないでしょうか?

何をしたいのかがはっきりとわからないので、
想像が含まれますが、
下記のコードのコメントにはInitial Settingとコメントが入っている通り、
初期化の処理に相当するものがあると考えると、
何度も呼び出す想定はされていないのではないでしょうか?

c

1  STM_MINI(); /* Initial Setting */

なにかのサンプルコードからの引用であるなら、
元のコードの記述が何をしているのかを確かめてみてはいかがですか?

投稿2020/06/09 00:18

yamame

総合スコア81

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

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

Merrifield

2020/06/09 00:28

初期設定の部分で、PWMのデューティー比を設定します。デューティー比を少しずつ変化させていくことが目的です。
yamame

2020/06/09 00:54

初期設定を変えるという話をしたいのはわかりますが、 その結果として何を得たいのでしょうか? STM_MINIは"初期"設定ですので、 ただ設定を変化させたいのならプログラムとしては、 その他の処理から、設定を変更させるのではないでしょうか? 別の回答者も指摘していますが、 ループの内側で設定変更する方法などを検討してみてはいかがですか?
Merrifield

2020/06/09 01:04

目的は、先ほどのコメントで書いた通りデューティー比を少しずつ増加させていくことです。LEDを明るさを調整しています。質問で書いたコードで全体でPWMの動作をするのです。 ループの内側で設定変更するということについては、これから試してみます。
guest

0

for文で処理を行おうとしても、途中でwhile(1)の無限ループのようなものがあり、そこで処理が止まってしまうのですが、どのようにして繰り返し処理を行えばよいでしょうか?

無限ループさせずに済むような方法に書き直してください(チップの詳細がわからない以上、それしか言えません)。

投稿2020/06/09 00:05

maisumakun

総合スコア146018

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

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

0

ファームのようなのでハード構成を教えていただかないと
どこに記述されるコードなのか次第で答えが変わります。

そのコードでも割り込み処理に記述するだけで
デューティ比の変更は可能です。
ハード次第でwhile(1)なくても動作可能ですし、FORを使っても動作させる
ことも可能です。FORでループ回数指定が必要なら難度が上がります。

ただし、デューティ比変更後になんからのPWN関係のリセット処理が必要で
その処理がウォッチドックタイマ発動後の処理に記述されて
いるならwhile(1)は必要です。

もしくはウォッチドックタイマでCPUリセットだけをかけてPWNの値は
RAM等のハードから取得し設定するハード構成なのかもしれません。
ハード次第なのです。

投稿2020/06/09 03:30

neko8man

総合スコア2

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

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

0

ベストアンサー

ご提示のサンプルらしきコードで使われているWDT(WatchDogTimer)とは、一般的にCPUとプログラムの暴走を防ぐためのもので、独立したデバイス(SoCとして組み込まれている場合もありますが)です。WDTは自力でカウントし続けていて、一定時間内にクリアされない場合、CPUにリセットをかけ、最初からやり直させるように使います。一定時間中にWDTをクリアできないと言うことは、プログラムがその為のルーチンを正しく走っていない、すなわち暴走ということが言えるのです。暴走し続けるよりリセットの方がまし、と言う考えです。

なぜ今、ご提示のサンプルらしきコードのwhileループ中でWDTのクリアを実行し続けているかと言えば、そのまま上記理由によるからです。今のコードは最低限のテンプレートとも言えるはずのコードで、一定周期でWTDTをクリアしないとダメ、と言うプログラムの基本的な作りを示しています。つまり反対に言えばwhile内から外しても、一定周期ごとにWDTをクリアするようなつくりに質問者さんができれば良い訳です。タイマー割込みなどが使えれば、連携して定周期で呼ぶルーチン(コールバック)を用意するなどが考えられます。

別の例ですが、Arduinoのプログラムの作りなどは言うなればフレームワーク化していて、まさにそのようになっています。初期化時にsetupと言う関数が一回だけ呼ばれ、loopと言う関数が繰り返し呼ばれます。質問者さんの環境でそんなようなかたちに仕立てあげられれば、whileから出し、呼ばれるごとに値を少しずつ変えることができるようになるでしょう。ただ、タイマー割込みを使いたいのであれば、既に別回答でもご指摘いただいているように、お使いのCPUの仕様を含め、ハードウェアの仕様が分かる必要があります。(尚、それを新たに示されても私が回答できるとは限りません)

投稿2020/06/09 02:20

dodox86

総合スコア9256

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

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

dodox86

2020/06/09 02:29

それと、別にタイマーを含む割込みを使わなくても、状態遷移の考え方を用いればwhileループの中でも少しずつ処理を進めていくことはできるはずです。そちらの方が簡単かつ安全かもしれません。状態に応じて細切れに処理をし、合間でWDTをクリアし、進めていくイメージです。組み込み系でよくあるパターンです。
fana

2020/06/09 02:54 編集

経験がないので実際のところをよくわからないですが, PWM制御ってこういったループ内(最も処理優先度が低い場所?)でやるものなのでしょうか? (各種割り込みとかでのタイミングずれが大きそうな気がする)
Merrifield

2020/06/09 03:12

dodox86さん もしよろしければ、状態遷移の考え方というのを詳しく教えていただけないでしょうか。
dodox86

2020/06/09 03:16

>fanaさん PWM制御自体はそうタイミングを求められることではないと思うので、割込み処理ではなくてメインループ内で自前のタイミング制御でも問題ないと思います。(<例えばLEDの明滅のような簡単なものとか)制御対象(ハード)や見た目の動きでシビアなものを求めるのであれば、厳密に割込みなどでタイミング制御する必要があるかと。しかしながら割込みでの処理はそのハンドラ内で雑に実行すると別の問題も起きがちなので、極力避けるべきだと思います。
fana

2020/06/09 03:30

あ,本件の制御対象ってLED(タイミングわりとどうでもいい)なんですね.
dodox86

2020/06/09 03:57

いえ、LEDは私が単に例として出しただけのものです。相手がモーターで、速度や距離を正確に制御するような場合もありますし。
fana

2020/06/09 04:30 編集

自身の言葉足らずを補っておきます. ・コメント(11:53)の時点ではモータとか発熱体とかの話かと思っていました. ・(12:30)では,LEDだという話は他回答のコメント欄内にて見つけました.
Merrifield

2020/06/09 04:33

dodox86さん whileの部分を削り、タイマ割り込みを使用することで解決しました。dodox86さんのコメントが一番参考になりました。ありがとうございました。
dodox86

2020/06/09 04:57

あ、すぐにタイマ割り込みが使えたのですね。解決して良かったです。
guest

0

whileのループはプログラムが「止まって」いない場合にWDTを設定する(つまり,プログラムが「止まって」しまったらWDTにてそのことが検出される)処理だと見えますから,

STM_MINI();
STM_MSTT();

の部分で全ての処理(の仕込み)が済む形なのでしょう.
割り込み(例えばタイマ割り込みだとか)で処理が進む話だと思うので,
「forでどうの」という話ではないと思います.然るべくやってください.

#STM_MSTP();が実行されることってあるんだろうか?


STM_MINI();STM_MSTT();の中あたりで,割り込みに関連する設定(レジスタの値をどうのこうのしているような)があるんじゃないかと想像しますので,それを手掛かりにして,既存コードでどんな割り込みが使われているかを見ていくところから始めるとよいのではないか,と.
つまり,結局のところ,回答としては,**「まずは既存コードをちゃんと読んで動作を把握せよ,改造はそれから」**になる…

投稿2020/06/09 01:17

編集2020/06/09 01:25
fana

総合スコア11996

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

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

fana

2020/06/09 01:19

もちろん,whileループ内に何か処理を書くということも可能ですが,既存コードの動作を把握してからでないと,きっと何が何だかわからない結果になるでしょう.
Merrifield

2020/06/09 01:23

WDTの部分がないとなぜか上手く動作しないんですよね。
fana

2020/06/09 01:26

WDTってなんだろう? っていうのを知っていますか?
Merrifield

2020/06/09 01:32

「まずは既存コードをちゃんと読んで動作を把握せよ,改造はそれから」 その通りですね。WDT自体は、ある程度意味は分かっていますが、なぜこのコード内に必要なのかが分かっていないので、割り込みに関する部分を調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問