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

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

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

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

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

Q&A

解決済

2回答

789閲覧

マイコンコードの間違っている点はどこか?

saichanian

総合スコア22

C

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

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

0グッド

1クリップ

投稿2022/04/26 07:37

編集2022/04/28 09:00

現在マイコンにて、スイッチを押して離すとLEDの点滅が切り替わるプログラムを考えており、以下のプログラムを作成しました。
スイッチはプッシュスイッチで、変数SWとし、押すと0が入力され、離すと1が入力されます。
LEDは変数LEDとし、0で点灯、1で消灯となります。
また、スイッチ、LEDに関しての変数をそれぞれSW、LEDとしておりますが、これは簡略的に記述したもので、実際はPORT.○○といった変数となっております。

C

1int SWwasON = 1; /*スイッチの状態が変化した際に、変化前の状態を記録する変数。最初はSW=1(入力なし)の状態なので、SWwasON = 1とする*/ 2 3if(SW==0){ /*スイッチが押された状態*/ 4 SWwasON=0; 5} 6 7if((SW==1)&&(SWwasON==0)){ /*スイッチへの入力が解除される(先日は、ここを(SW==0)とする致命的な記入ミスをしておりました。) 8「スイッチの状態が変化前は入力がオン(SWwasON=0)であり、変化後の現在はオフ(SW=1)」の条件を満たしているか*/ 9 LED=1-LED; /*スイッチの点滅状態を反転。最初はLED=1で消灯状態*/ 10 SWwasON=1; 11}

しかしながら、上記のコードを実行しても、LEDの点灯は行われませんでした。

上記の2つ目のif文if((SW==1)&&(SWwasON==0))で、&&(SWwasON==0)をカットした以下のプログラム実行したところ、スイッチを押すとLEDが消灯、離していると点灯するというプログラムとなりました。

C

1int SWwasON = 1; 2 3if(SW==0){ 4 SWwasON=0; 5} 6 7if(SW==1){ 8 LED=1-LED; 9 SWwasON=1; 10}

このプログラムの場合、最初はLED=1で消灯状態となっているので、最初から二つ目のif文の条件を満たし、LEDが点灯、スイッチを押すとその条件を満足しないのでLEDが消灯する、という流れなので、このプログラムはあっているようにも感じます。

1つ目のコードは、どの点が間違っていますでしょうか?

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

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

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

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

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

int32_t

2022/04/26 08:24 編集

このコードはどういうタイミングで実行されるのでしょうか? SWwasON の初期値はどうなってますか?
fana

2022/04/26 09:40

SWにチャタリングの問題があって挙動が意味不明に見えているとか?
jimbe

2022/04/26 10:04

> 上記の2つ目のif文で、SWwasON==0をカットして実行したところ、スイッチを押すとLEDが消灯、離していると点灯するというプログラムとなりました。 ご提示のコードでは SW==0 時には LED になにもしていませんので、そのような動作をするとは思えません。 ご提示のコード以外に何か(ハード的なものも含めて)あるのではないでしょうか。
thkana

2022/04/26 12:31

書かれていない部分になにかあるような気がしてなりません。
dodox86

2022/04/27 00:19

マイコンと言っても色々ありますし、それに対するソフトウェアも色々あります。「LED」とは単なるC言語での変数なのか、何かしらのI/Oポート、アドレスなのか、そうであればどんな仕様なのか分かりません。あと、提示されているコードが使われるタイミング(周期的なのか、何かしらのイベントなのか、など)も。もっと詳細に示しましょう。
tmp

2022/04/27 03:29

LEDへ流す電流不足で暗くて点灯を確認できなかったが、SWwasON==0をカットするとOn/OFFを繰り返して、ダイナミック点灯風になり光るのが見えるようになったとか? もとのソースでも、暗くひかったりしていませんか?
saichanian

2022/04/28 08:50

回答が遅くなってしまい、大変申し訳ございません。 thkana様 >>書かれていない部分になにかあるような気がしてなりません。 int SWwasON = 1;の記述のほか、PORT.○○をここの質問ではSWやLEDという変数に置き換えていることを記述しておりませんでした。申し訳ございません。 dodox86様 >>「LED」とは単なるC言語での変数なのか、何かしらのI/Oポート、アドレスなのか、そうであればどんな仕様なのか分かりません。 PORT.○○を「SW」や「LED」に置き換えて記述している、という説明が不足しておりました。大変申し訳ございません。 >>提示されているコードが使われるタイミング(周期的なのか、何かしらのイベントなのか、など)も。 本コードは、10m秒ごとに割り込みが発生しており、if文の操作を何度も行っている、という仕組みのようです。(詳しくはまだよくわかっておりません。申し訳ございません。) tmp様 >>もとのソースでも、暗くひかったりしていませんか? 別のコードを行った際、おかしな挙動をしているように感じたので、電力不足問題がもしかしたら発生しているかもしれません。 しかしながら、1つ目のコードでは全く光っておりません。
saichanian

2022/04/28 09:15

int32_t様 >>このコードはどういうタイミングで実行されるのでしょうか? 本コードは、10m秒ごとに割り込みが発生しており、if文の操作を何度も行っている、という仕組みのようですが、その点についての質問でしょうか? マイコンについてまだ勉強中であり、あまり質問の意味を汲めず、申し訳ございません。 >>SWwasON の初期値はどうなってますか? int SWwasON = 1; の記述が抜けておりました。申し訳ございません。 jimbe様 >>ご提示のコードでは SW==0 時には LED になにもしていませんので、そのような動作をするとは思えません。 本コードでは、スイッチへの入力がないときはSW=1となっております。 fana様 >>SWにチャタリングの問題があって挙動が意味不明に見えているとか? マイコン由来の不具合ということでしょうか? 別のコードを実行した際、おかしな挙動をしているように感じたので、確かにそのような可能性も考えられます。
fana

2022/04/28 10:10 編集

SWの信号がどうやって生成されてくるのか?っていう話です. 例えば,機械的なスイッチから直で(チャタリング防止回路とかが間にない状態で)ポートに信号が来ているような状態だと,あなたがソフト的にチャタリングに対応する必要があるだろうと思いますが,そこらへんは大丈夫なのか? という話です. 要は,【スイッチを「1回」押す毎にLEDの 点灯/消灯 状態を切り替える】という処理を書いたつもりだけれども,スイッチを「1回」押した際のSW信号が { ON -> OFF -> ON -> OFF -> ... -> OFF } と振動するならば,状態が落ち着いた際のLEDの状態はその振動回数次第になっちゃうよね,という話.
thkana

2022/04/28 12:43

> ...ことを記述しておりませんでした。 いや、そういう話ではなく、現象が再現するプログラム全体を示して頂きたいなぁ、と。どうしてそうなるかがわからないで質問しているのに、どうして自信を持ってプログラムを省略してしまえるのでしょう? そういえば古いPICなどで、出力ポートを読み出すとポートの状態を実際に読み出すので、ポートを変化させた直後に読み出すと期待した値が読めないなどということがあると聞いたことがありますが、そういうことはないですか? 最近の石は大丈夫みたいですが。(私自身はPICはなんだか好きになれないのであまり使ったことがないのです) 使っているマイコンはなんですか? LEDの点灯状態を別途変数にして、値の操作はその変数に対してのみ行い、ポートはその変数の値を反映するだけ(出力ポートからの読み出しはしない)、としてみたらどうなるでしょう?
saichanian

2022/04/30 06:38

fana様 >>SWの信号がどうやって生成されてくるのか?っていう話です. 申し訳ございません。信号の生成過程はよくわかりません。 現在マイコンが手元にない状態でGWが明けたら確認してみようと思います。 >>ソフト的にチャタリングに対応する必要があるだろうと思います 確かに、別のプログラムを動かした際、変な挙動をしていたので、チャタリングの問題があるかもしれません。スイッチの構造などを確認してみます。 >>状態が落ち着いた際のLEDの状態はその振動回数次第になっちゃう 1つ目のプログラムでは、LEDがついたり消えたり、という状態ではなく、全く点灯しなかったので、上記のような状況でもないように感じます。 thkana様 >>どうして自信を持ってプログラムを省略してしまえるのでしょう? 本マイコンプログラムには、どの部分にコードや変数を記述し、どの部分には変更を加えないというような注意書きが書かれていたので、それに従い記述可能な部分にプログラムを記述しておりました。 >>現象が再現するプログラム全体を示して頂きたい 承知いたしました。 プログラム全体とは、このプログラムのメインプログラムのことでしょうか? それとも、ヘッダーファイルまで含めたファイルのことでしょうか? 現在マイコンが手元にない状況ですので、GW明け後に確認し、こちらのページに記載いたします。 >>ポートを変化させた直後に読み出すと期待した値が読めないなどということがあると聞いたことがあります 本プログラムでは、実際に期待した値が読み込めていませんが、これがプログラムによるものなのか、ポートを変化させた直後であることに由来しているかはわかりません。 しかし、「スイッチを押している間は点灯し、離すと消灯する」というプログラムを動かした際には問題なく動作したので、プログラムによる問題であると考えております。 >>使っているマイコンはなんですか? はっきりとは確認しておりませんが、renesas社製のマイコンであったように感じます。 >>LEDの点灯状態を別途変数にして、値の操作はその変数に対してのみ行い、ポートはその変数の値を反映するだけ(出力ポートからの読み出しはしない)、としてみたらどうなるでしょう? 承知いたしました。GW明けにそのようなプログラムを実践してみます。
thkana

2022/04/30 08:18

理想は、「私があなたと同じことを試せるだけの情報が提供されること」です。 そして、無償であなたの相談に載ってきた回答者が「本当に試さなくても起こっていることがわかるように」あなたのしたこと、起こったことを細大漏らさず提供すると、有効な回答が得られやすくなるのではないかと私は思うのですがどうでしょう。情報が不要だったら無視すればいいだけですが、提供されていない情報は知りようがないのです。 で、私は、あなたが質問に書いたこと以外は知り得ないので、あなたが作ったのがプログラムのごく一部であることなど知らず、他の部分も含めて疑うしかない状況にある、というのはわかっていただけますか? (しかも、あなたが作ったのでないということは正しさの保証にはなりません) そして今でも「提供された部分とあなたが書いた部分が整合していない」という可能性は排除されていません。 問題なく動作した、というのは > int SWwasON = 1; > if(SW==0){ > SWwasON=0; > } > if(SW==1){ > LED=1-LED; > SWwasON=1; > } このプログラムの事ですか? これが、「スイッチを押している間は点灯し、離すと消灯する」という動作をしたのなら、かなり不思議な現象と言わざるを得ないと思います。 (有償の相談だったらもっと我慢強くなりますけれど...でも、必要な情報が提供されなかったら解決出来ないことは無償でも有償でも変わりません)
saichanian

2022/04/30 12:24

thkana様 >>理想は、「私があなたと同じことを試せるだけの情報が提供されること」 承知いたしました。マイコンの型式、プログラム全体並びにヘッダーファイル等を追記いたします。 >>問題なく動作した、というのは 問題なく動作したのは、上記とはまた別のプログラムのことになります。 こちらも併せて、コードを記載いたします。 int SWwasON = 1; ~ SWwasON=1; > } こちらのプログラムは、スイッチを押していないときには点灯し、押したときには消灯するプログラムとなります。
jimbe

2022/04/30 20:39

プログラムの動作から考えますと、LED は点灯状態を(プログラムの動作周期である) 10ms しか維持しないのではないでしょうか。 つまり、LED を点灯し続けたければプログラムから常に 0 を送り(設定し)続けなければならない、という仕様ではありませんか?
saichanian

2022/05/01 16:04

jimbe様 >>LED は点灯状態を(プログラムの動作周期である) 10ms しか維持しないのではないでしょうか もし、LED が点灯状態を10msしか保てていないとすると、 if((SW==1)&&(SWwasON==0)){ LED=1-LED; SWwasON=1; } の操作が2回のみ実行され、LEDの点灯状態が2回ひっくり返ったことになるように思えます。 すなわち、条件(SW==1)と、条件(SWwasON==0)が一瞬の間に2回のみ判定されることになります。 一方で、上記のプログラムには操作 SWwasON=1; が入っておりますので、再びスイッチをオンにしない限りはSWwasON=0とならず、条件if((SW==1)&&(SWwasON==0)) は満たされないように思えるのですが、いかがでしょうか?
fana

2022/05/02 04:24

おそらく各自が「常識的に考えて」な感じに情報を補っているがために誰も現在まで問うてないのだと思うが……念のため問うておこう. > int SWwasON = 1; ってのはどこに書かれてるの? と! それローカル変数じゃないよね? と!
saichanian

2022/05/02 08:42

fana様 >> int SWwasON = 1;ってのはどこに書かれてるの? と! それローカル変数じゃないよね? と! 本マイコンプログラムには、どの部分にコードや変数を記述し、どの部分には変更を加えないというような注意書きが書かれおります。 そのため、「ここに変数の宣言を行え」という場所に int SWwasON = 1;と記述いたしました。 そしてその記述場所はmain関数の外であったと思われるので、グローバル変数であると認識しております。 現在マイコンが手元にないので、GW明けにそれも含めて確認いたします。
thkana

2022/05/02 10:09

BAを選んだということはGW明けを待たずして試したということかな?
saichanian

2022/05/02 10:16

thkana様 まだ回答にあったコードは試しておりませんが、非常に納得のいく回答だったので、BAとさせていただきました。 しかしながら、確かに試す前にBAを選ぶのはプログラミングのセオリーに反しているように思えます。 申し訳ございません。 GW明けに、回答にあったコードの結果を報告させていただきます。
saichanian

2022/05/02 11:21

GW明けに回答にあったコードの結果を報告させていただきたいのですが、きちんと動作が行われた場合、上に回答したようなプログラム全体の追記は必要でしょうか? マイコンの種類・型番、スイッチの構造やチャタリング対策、割り込みにかかわる情報、SWwasON変数がグローバル変数であるかについては、追記いたします。
guest

回答2

0

ベストアンサー

「質問への追記」によれば、LED、SWは、実際のレジスタ操作(defineされている?)で、
この部分は10ms毎の割り込み関数内、という事ですね。

int SWwasON = 1; //①

if(SW==0){ //②
SWwasON=0;
}

if((SW==1)&&(SWwasON==0)){ //③
LED=1-LED;
SWwasON=1;
}

<スイッチを押している場合(SWは0)>
①で変数SWwasONが作られ1が代入される
②のIF文で、スイッチが押されたている場合SWが0ですから、中が実行され、SWwasONに0が代入される。
③IF文のSW==1の部分が偽なので、中は実行されない。
つまり何も起こりません。

<スイッチを押していない場合(SWは1)>
①で変数SWwasONが作られ1が代入される
②のIF文で、偽ですから中は実行されない
③IF文のSWwasON==0の部分が偽なので、中は実行されない。
つまり何も起こりません。

int SWwasON = 1; //①

if(SW==0){ //②
SWwasON=0;
}

if(SW==1){ //③
LED=1-LED;
SWwasON=1;
}

<スイッチを押している場合(SWは0)>
①で変数SWwasONが作られ1が代入される
②のIF文で、スイッチが押されたている場合SWが0ですから、中が実行され、SWwasONに0が代入される。
③IF文が偽なので、中は実行されない。
つまり何も起こりません。

<スイッチを押していない場合(SWは1)>
①で変数SWwasONが作られ1が代入される
②のIF文で、偽ですから中は実行されない
③IF文が真なのでLEDはトグル動作して、SWwasONに1が代入される(元々1が入っているけど)
つまり、LEDがトグル動作するので10ms毎の割り込みの場合は50Hzの高速点滅(実際には点灯状態に見える)になります。

※つまり、「スイッチを押すとLEDが消灯、離していると点灯」ではなく、「離しているときは点灯(高速点滅)、押した時は押した瞬間の状態」でしょうね。

正しく(押す度にトグル動作)動かすのなら

interrupt_10ms

1 2static int SWwasON = 1;//staticを付けてデータを次回以降に残す。 3 4if(SW==0 && SWwasON==1){//「SWを押していて前回押していない」→押した瞬間 5 SWwasON=0; 6 LED=1-LED;//LEDをトグル 7} 8 9if(SW==1){//押していない時 10 SWwasON=1; 11}

のように、前回のSWの状態とを比べて「押した瞬間」を取得する必要があります。
(SWwasON にstaticを付けるとか、外部変数にするとかが必要です)

※質問に倣ってSWwasONの処理をしたが、普通はSWwasON(SWはオンだった)なら押している時が1だよ。

投稿2022/05/02 07:13

編集2022/05/02 10:00
nac_tnk

総合スコア463

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

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

saichanian

2022/05/02 09:27

nac_tnk様 ご回答、誠にありがとうございます。 非常に納得がいきました。 確かに、プログラムを記述した際は割り込みのことを全く考えておりませんでした。 丁寧なご説明、誠にありがとうございました。 ※SWwasONについて、承知いたしました。
saichanian

2022/05/02 11:08

一度BAを付けましたが、GW明けにプログラムが動作することを確認したのち、再度BAをつけさせていただきます。 何卒よろしくお願いいたします。
fana

2022/05/03 05:39

> int SWwasON こいつがグローバル変数だというのならば,少なくともこの回答の前半部は見当違いということになるわけだが.
nac_tnk

2022/05/05 13:07

回答の前提は書いてありますけど。 > この部分は10ms毎の割り込み関数内
saichanian

2022/05/07 06:18

fana様 nac_thk様 回答ありがとうございます。 現在手元にコードがない状況ですので、実際に int SWwasONがグローバル変数かどうか、改めてGW後に確認させていただきます。 また、実際にコードが意図したとおりに動くかどうかを報告させていただきます。 何卒よろしくお願いいたします。
saichanian

2022/05/14 09:18

結果の回答が遅くなってしまい、申し訳ないのですが、現在まだマイコンを操作することができておりません。 回答していただいた皆様には大変申し訳ありませんが、今しばらくお待ちくださいますようお願い申し上げます。
saichanian

2022/06/01 01:57

回答が遅くなってしまい、申し訳ありません。 結論から申し上げますと、nac_tnk様のおっしゃった通り、SWwasON変数が割り込み関数内で定義されていたために、割り込みが発生するたびに値のリセットがかけられていたようです。 また、そのため、fana様のご指摘の通り、グローバル変数ではなくローカル変数となっておりました。 ご回答、誠にありがとうございました。 また、回答が度々遅くなってしまい、申し訳ありませんでした。
guest

0

どういう動作をするのか、あなたなりに追いかけていこう。
そのコードで点滅になる、という説明はできるでしょうか

投稿2022/04/26 08:26

y_waiwai

総合スコア87749

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

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

saichanian

2022/04/28 09:01 編集

回答が遅くなってしまい、大変申し訳ございません。 コードにコメントにて動作の内容を記述いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問