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

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

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

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

マイコン

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

Q&A

1回答

259閲覧

キーパッドを押すことでLED点灯のパターンを変えていく方法

ghwchikxpgns

総合スコア5

C

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

マイコン

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

0グッド

0クリップ

投稿2024/07/11 12:44

編集2024/07/11 14:07

実現したいこと

・キーパッドを押すことでLED点灯のパターンを変えていく
・キーパッドを離すとLEDは消灯する
・キーパッドは12個あるのでパターンを組み合わせて12通り表現する

実行したい内容のイメージ図:
イメージ説明

回路図:
イメージ説明

フローチャット:
イメージ説明

イメージ説明

発生している問題・分からないこと

FUNCTION()の部分でボタンから離した際にflagの値をリセットするとボタンを押しても反応しない問題が起きる。逆にFUNCTION()の部分でボタンから離した際にflagの値をリセットする項目を外すと他のボタンを押すまで前に押したボタンの項目がループする。

エラーメッセージ

error

1エラーメッセージは出ないが思い通りの動作にならない。

該当のソースコード

/********** 略 **********/ /* グローバル変数 */ int start = 0; //初めに行う設定 int cnt = 0; //カウンター int flag = 0; //判定用フラグ int sw = 0; //スイッチモード int key_no = 0; //マトリックスキーナンバー取得用 /********** 略 **********/ /* メインコード */ static void TMR1_DefaultOverflowCallback(void) { //Add your interrupt code here or //Use TMR1_OverflowCallbackRegister function to use Custom ISR //初期設定(1回だけ呼び出される) if(start == 0){ PWM5_LoadDutyValue(0); //LEDの明るさを0にする start += 1; } //自作関数 MATRIX_SWITCH(); FUNCTION; } /********** 略 **********/ /* オリジナル機能 */ /* MATRIX_SWITCH関数 */ int MATRIX_SWITCH(){ /********** 略 **********/ } /* DATA関数 */ int DATA(){ /********** 略 **********/ } /* STEP_1関数 */ int STEP_1(){ /********** 略 **********/ } /* STEP_2関数 */ int STEP_2(){ /********** 略 **********/ } /* STEP_3関数 */ int STEP_3(){ /********** 略 **********/ }
/* MATRIX_SWITCH関数 */ int MATRIX_SWITCH(){ /* swが4以上の場合はリセットする */ if(sw >= 4){ sw = 0; } /* swの値に応じて出力値を変える */ switch(sw){ case 0: RA2 = 1; RA4 = 1; RA5 = 1; break; case 1: RA2 = 0; RA4 = 1; RA5 = 1; break; case 2: RA2 = 1; RA4 = 0; RA5 = 1; break; case 3: RA2 = 1; RA4 = 1; RA5 = 0; break; } /* swに応じてボタンを押した際の反応を変える */ if(RC0 == 0){ switch(sw){ case 1: key_no = 1; break; case 2: key_no = 2; break; case 3: key_no = 3; break; } } else if(RC1 == 0){ switch(sw){ case 1: key_no = 4; break; case 2: key_no = 5; break; case 3: key_no = 6; break; } } else if(RC2 == 0){ switch(sw){ case 1: key_no = 7; break; case 2: key_no = 8; break; case 3: key_no = 9; break; } } else if(RC3 == 0){ switch(sw){ case 1: key_no = 10; break; case 2: key_no = 11; break; case 3: key_no = 12; break; } } else{ // key_no = 0; } /* swに1を加える */ sw += 1; }
/* DATA関数 */ int DATA(){ /* flagの値に応じて呼び出す関数を変える */ if(flag == 0){ STEP_1(); } else if(flag == 1){ STEP_2(); } else{ STEP_3(); } }
/* STEP_1関数 */ int STEP_1(){ if(cnt < 1000){ //cntが1000未満なら PWM5_LoadDutyValue(100); //明るさを100にする } else{ PWM5_LoadDutyValue(0); //明るさを0にする } if(cnt >= 2000){ //cntが2000以上なら cnt = 0; //cntをリセットする flag += 1 //flagに1加える } else{ cnt += 1; //cntに1加える } } /* STEP_2関数 */ int STEP_1(){ if(cnt < 500){ //cntが500未満なら PWM5_LoadDutyValue(100); //明るさを100にする } else{ PWM5_LoadDutyValue(0); //明るさを0にする } if(cnt >= 2000){ //cntが2000以上なら cnt = 0; //cntをリセットする flag += 1 //flagに1加える } else{ cnt += 1; //cntに1加える } } /* STEP_3関数 */ int STEP_3(){ switch(key_no){ //key_noで動作する関数を判定する case: 1 LED_01(); break; case: 2 LED_02(); break; /********** 略 **********/ case: 12 LED_12(); break; } }

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

特に改善されたことなし

補足

<実現したいもの>
・キーパッドを押すことでLED点灯のパターンを変えていく
・キーパッドを離すとLEDは消灯する
・キーパッドは12個あるのでパターンを組み合わせて12通り表現する

<プログラムの説明>
・PICのRA2,RA4,RA5は出力で、RC0,RC1,RC2,RC3は入力に設定してある
・キーパッドを置くとグローバル変数に定義されている「key_no」に値が代入される
・「key_no」に応じて動作する内容が変わる
・役割ごとに自作関数を分けている()
→ キーパッドを判定する関数
*マイコンのRA(出力)とRC(入力)の部分の値で判定している
*値は0(Low)と1(High)のみでRAとRCの値が0のときのみボタンが押されたことになる
→ スイッチが押されているかを判定する関数
*0か他の値で判定する
→ 点灯パターン関数
*「key_no」の値で動作する内容が変わる
*「flag」の値でモードが変わる
(flag:0【共通】→flag:1【「key_no」に応じて変わる - ループする】)
*再度ボタンが押された際は必ずflag:0からやり直す

<使用する部品>
・PICマイコン(PIC16F18325)  - キーパッドを制御するために用いる
・ピンヘッダー(PHA-1x10RG) - プログラムを書き込む際に使用する
・キーパッド(AE-KIT45-KEYPAD4X3) - LEDを光らせるために使用する
・赤色LED(OSR5JA3Z74A)
*全て秋月電子で取り扱っている

<使用するソフトウェア>
MPLAB X v6.20
https://forum.microchip.com/s/topic/a5CV40000000KRlMAM/t393938

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

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

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

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

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

jimbe

2024/07/11 13:41 編集

ソースコード、なんでメインのあるコードで省略して後ろで別に提示されてるんでしょう。 妙な編集はせずなるべくあるまま載せられたほうが良いです。 ( STEP_2関数ってコメントで STEP_1 が載ってますし、 FUNCTION; には () がありません、一箇所 ; が無い所もあります。弄られたコードではどこが正しいのかも分かりません。) >flag:0【共通】→flag:1【「key_no」に応じて変わる DATA関数によると flag==0 で STEP_1(), flag==1 で STEP_2(), flag が 0,1 以外で STEP_3() を呼び、 STEP_3() が key_no 別に処理してますけど…何が正しいんでしょう。 配列は使えないんでしょうか。 if と switch で値求めるくらいなら配列用意すればもっと簡単になるように見えますが。
guest

回答1

0

キー取得(MATRIX_SWITCH)のフローチャートと関数を見たけど、冗長すぎる反面、しっかりと取得出来ていないです。

フローチャートは本来、プログラム(頭の中)を整理するために書くものだと思うのですけど、
何とか着地点に到着した、というだけのものになっていませんか?

※このモジュールだと、同時押し対策でダイオードが付いています。
なので、本来、全てのキーの状態を取得すべきだと思います。

現状は、1列調べたら終わり(次回は次の列)という仕様で、更に何処かを押していたら今回は終わります。
ダイナミック点灯のようなやり方をしていますね。(スイッチの取得なのに可笑しい、という意味合いです。)
で、一番悪い点は、そういった仕様(一番最後に押しているキー番号が残る)なので、「何も押していない」(key_noが0)という状態になりません。
(1列しか見ていないので、「全ての列が押されていない」と答える事が出来ない、という仕様)

そのあたり、どのようにすればいいのか、(どのようにするのか)をもう一度フローチャートでも書いて考えてみれは?

質問外ですけど、ついでに言っておくと、

int abc(){
//略
return xxx;
}

のように関数の先頭にintが付いている場合は、int型の値を返す、という事を意味しています。
つまり、その関数の最後とかでreturn xxx;とxxxを返す場合に使います。
返すつもりが無い関数ならvoidにした方が良いです。

投稿2024/07/19 08:46

nac_tnk

総合スコア478

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.40%

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

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

質問する

関連した質問