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

Tip / ログイン to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
LinaS_21
Employee
Employee
First question asked First like received

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

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

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

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

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

0 件の賞賛
1 解決策
AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

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

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

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

Aiko Ohtaka
Infineon Technologies

元の投稿で解決策を見る

0 件の賞賛
4 返答(返信)
AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

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

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

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

Aiko Ohtaka
Infineon Technologies
0 件の賞賛
MiNe_85951
Level 7
Level 7
Distributor - TED (Japan)
50 likes received 500 replies posted 50 solutions authored

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コンポーネントが正常に動作しない問題が発生する恐れがあります。

0 件の賞賛
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

こんにちは、

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

0 件の賞賛
Kenshow
Level 8
Level 8
Distributor - Marubun (Japan)
50 solutions authored 25 solutions authored 10 solutions authored

こんにちは、

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

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

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

1.png

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

pastedImage_4.png

 参考になれば幸いです。

Thanks,

Kenshow

0 件の賞賛