4 Replies Latest reply on Sep 6, 2020 10:55 PM by NoTa_4591161

    割込みハンドラ内の動作について

    LinaS_21

      SW2を押すと、割込み処理によってLEDをCapSenseによって調光するようなプログラムを書いています。

      しかし、SW2を押さない初期状態の時点で既に、LEDが点いたままになってしまっています。

       

      まだ、調光処理は完成ではないのですが、LEDの処理はハンドラ内にしか書いていないのに、SW2を押さずにLEDが点くのはおかしいです。

      そのため、SW2がきっかけとなった割込み処理になっていないように思います。

       

      この問題を解決する方法を教えてください。

        • 1. Re: 割込みハンドラ内の動作について
          AikoO_51

          AN90799 – PsoC®4 割り込み – Community Translated (JA)のスレッドをご参照ください。

          割り込みベースのプロジェクトを開発する際のガイドとしてアプリケーションノートAN90799 についても紹介してあります。

           

          ご質問頂いた内容についてですが、割り込みハンドラは割り込み自体を処理するために定義されており、割り込みとして実施する動作については、主にmain()for文内に記入します。Start() などの割り込み API 関数についても今一度確認をお願いします。

          • 2. Re: 割込みハンドラ内の動作について
            MaMi_1205306

            PSoC Creatorの設定を確認しなければ分かりませんが、

            恐らくPWMの初期化が割り込み処理内にしかないため、

            main関数が起動していても割り込みが発生しない限り、

            PWMコンポーネントは初期化されていないのが問題だと思います。

             

            CY_ISR( Pin_SW2_Handler )

            {

            //略

                PWM_Start();

                CapSense_Start();

                UART_Start();

             

             CapSense_InitializeAllBaselines();

             CapSense_ScanEnabledWidgets();

            //略

            )

             

            main(){

                CyGlobalIntEnable; /* Enable global interrupts. */

                Pin_SW2_Int_StartEx( Pin_SW2_Handler );

             for{

                 }

            }

             

            上記の処理を下記のように変更してみてください。

             

            CY_ISR( Pin_SW2_Handler )

            {

            //略

            )

             

            main(){

                PWM_Start();

                CapSense_Start();

                UART_Start();

             

                CyGlobalIntEnable; /* Enable global interrupts. */

             

             CyDelay(xx);

                CapSense_InitializeAllBaselines();

             CapSense_ScanEnabledWidgets();

             

                Pin_SW2_Int_StartEx( Pin_SW2_Handler );

             for{

                 }

            }

             

            PWM_StartでPWMコンポーネントの初期設定を消灯する値(Compere値を0)にしてみてください。

            方法はPWMコンポーネントをダブルクリックして設定画面から数値を入力できます。

             

            あとは    CapSense_InitializeAllBaselines();のAPIをコールするタイミングですが、

            電源の起動時間を測定し、設定電圧までの到達時間を確認後、

            CyDelay()のAPIでxx msのディレイを配置することをお勧めします。

            理由としてPSoC4は1.8Vから起動します。

            電源の出力コンデンサ容量が高いと電源の立ち上げスルーレートが遅くなり、

            もしも3.3Vや5Vでお使いの場合、規定電圧に到達していないタイミングでCapSenseをイニシャライズすると、

            CapSenseコンポーネントが正常に動作しない問題が発生する恐れがあります。

            • 3. Re: 割込みハンドラ内の動作について
              MoTa_728816

              こんにちは、

               

              PWM の出力はデバイスのリセット直後は 0 (LOW) になっています。

              その為、負論理の LED では初期状態で点灯してしまっているのではないかと思います。

               

              また、割込み処理ルーチン ISR は、非常に短時間の処理をすることを想定されていますので、

              ISR 内では目的のフラグだけを立てて、割込みフラグをクリアして

              メイン関数・ループ内でフラグを回収するのが通常の使い方になっていると思います。

               

              ワークアラウンドとしては、下記の回路図のように PWM 出力に NOT をかけてから LEDに接続すると

              リセット直後でも LED は消灯しています。(以下、CY8CKIT-044 でサンプルを作成してみました)

              001-schematic.JPG

              ピン

              002-pins.JPG

               

              ご質問の文から、SW2 で何をされたいのか読み切れなかったので、

              sw2_isr では sw2_pushed というフラグだけを立てて、

              後はそのフラグが立っている場合には main が do_sw2() を呼ぶようにしました。

              中では LED_R のオン・オフだけをしています。

               

              また、CapSense もこれから開発をされるのでしたら v7.0 がお勧めですので、

              v7.0 を使用したサンプルになっています。

              CY8CKIT-044 の基板上の5つの CapSense ボタンを

              中央: Center

              上: Up

              右:Right

              下:Down

              左:Left

              として、

              Center で PWM のスタート・ストップ

              Up と Down で compare の値を変化させる

              Right と Left で period の値を変化させる

              つもりでプログラムを書きましたが

              充分なテストは行えていない事ご了承ください。

               

              main.c

              =========================

              #include "project.h"

              #include "stdio.h"

               

              #define LED_ON  0u

              #define LED_OFF 1u

               

              #define MODE_STOP    0

              #define MODE_RUNNING 1

               

              #define MAX_PWM_PERIOD 60000

              #define MIN_PWM_PERIOD 100

               

              uint16_t pwm_period = 10000 ;

              uint16_t pwm_compare = 5000 ;

              int      pwm_mode = MODE_STOP ;

               

              char str[128] ; /* print buffer */

              void print(char *str)

              {

                  UART_UartPutString(str) ;

              }

               

              void cls(void)

              {

                  print("\033c") ; /* reset */

                  CyDelay(20) ;

                  print("\033[2J") ; /* clear screen */

                  CyDelay(20) ;

              }

               

              volatile int sw2_pushed = 0 ;

               

              CY_ISR(sw2_isr)

              {

                  sw2_pushed = 1 ;

                  SW2_ClearInterrupt() ;

              }

               

              void init_hardware(void)

              {

                  CyGlobalIntEnable; /* Enable global interrupts. */

                 

                  UART_Start() ;

                 

                  CapSense_Start(); /* Initialize Component */

                  CapSense_ScanAllWidgets(); /* Scan all widgets */

                 

                  SW2_ClearInterrupt() ;

                  isr_1_ClearPending() ;

                  isr_1_StartEx(sw2_isr) ;

                 

                  PWM_Start() ;

              }

               

              void splash(void)

              {

                  cls() ;

                  sprintf(str, "CapSense Button Test (%s %s)\n", __DATE__, __TIME__) ;

                  print(str) ;

              }

               

              void do_capsense(void)

              {

                  CapSense_ProcessAllWidgets(); /* Process all widgets */

              //       CapSense_RunTuner(); /* To sync with Tuner application */

                  if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS0_ID)) { /* center */

                      print("Center\n") ;

                      if (pwm_mode == MODE_STOP) {

                          pwm_mode = MODE_RUNNING ;

                      } else {

                          pwm_mode = MODE_STOP ;

                      }

                  } else if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS1_ID)) { /* up */

                      print("Up\n") ;

                      pwm_compare++ ;

                      if (pwm_compare >= pwm_period) {

                          pwm_compare = pwm_period ;

                      }

                      PWM_WriteCompare(pwm_compare) ;

                      PWM_WriteCounter(0) ;

                  } else if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS2_ID)) { /* right */

                      print("Right\n") ;

                      pwm_period++ ;

                      if (pwm_period >= MAX_PWM_PERIOD) {

                          pwm_period = MAX_PWM_PERIOD ;

                      }

                      PWM_Stop() ;

                      PWM_WritePeriod(pwm_period) ;

                      PWM_Enable() ;

                  } else if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS3_ID)) { /* down */

                      print("Down\n") ;

                      if (pwm_compare > 0) {

                          pwm_compare-- ;

                      }

                      PWM_WriteCompare(pwm_compare) ;

                      PWM_WriteCounter(0) ;

                  } else if (CapSense_IsSensorActive(CapSense_BUTTON0_WDGT_ID, CapSense_BUTTON0_SNS4_ID)) { /* left */

                      print("Left\n") ;

                      pwm_period-- ;

                      if (pwm_period <= MIN_PWM_PERIOD) {

                          pwm_period = MIN_PWM_PERIOD ;

                      }

                      PWM_Stop() ;

                      PWM_WritePeriod(pwm_period) ;

                      PWM_Enable() ;

                  }

                  CapSense_ScanAllWidgets(); /* Start next scan */

              }

               

              void do_sw2(void)

              {

                  if (LED_OFF == LED_R_Read()) {

                      LED_R_Write(LED_ON) ;

                  } else {

                      LED_R_Write(LED_OFF) ;

                  }

              }

               

              int main(void)

              {

                  init_hardware() ;

                 

                  splash() ;

               

               

                  for(;;)

                  {

                      if (CapSense_NOT_BUSY == CapSense_IsBusy()) {

                          do_capsense() ;

                      }

                      if (sw2_pushed) {

                          do_sw2() ;

                          sw2_pushed = 0 ;

                      }

                  }

              }

              =========================

               

              moto

              • 4. Re: 割込みハンドラ内の動作について
                NoTa_4591161

                こんにちは、

                 

                 LEDにつながるGPIOの設定(初期値)はどうなっておりますか?

                 LEDの回路次第ですが、電流引き込みタイプの場合、ピン設定は出力LowでLEDのは点灯しっぱなしになります。出力Highとすれば、LEDは消えます。

                 

                例えば、こういうH/W場合です。

                1.png

                ピン設定は以下になります。ポイントはInitial drive stateの設定で、ここがLow(0)だと、何もしなくてもLEDのは点灯します。

                 

                 参考になれば幸いです。

                 

                Thanks,

                Kenshow