大文字と小文字を区別して入力すると、すべての変数といくつかのヒントがゼロにリセットされます。

私は自分の試験でこのコードを書きましたが、それにはいくつかの問題があります(そしてこれが原因で失敗します)。

私のボードを通してデバッグしている間(私はatmel atmega328p Xplained miniを持っています)、なぜかわかりませんが、メインスイッチに入るときと switch(currentstatus)の間でチェックされるケース:私のステータス変数はすべてゼロにリセットされます。 私はシミュレータを介してそれをデバッグする場合それはうまく動作するようです。

私がボードにコードをアップロードした場合、それはいくつかの割り込みを認識しない場合のように、それは悪い動作します。

さらに私はあなたに別のことを頼みたいです。私は私の試験のためにPWM出力の正しいピンにアクセスすることを妨げるドーターボードを使用しています。だから私は手でPWM を実装する必要があります。私はあなたがコードで見ることができる解決策を実行しようとしました(私は1msのタイマーを使っています)。もっとシンプルでスマートな解決策はありますか?

手伝って頂けますか?

#include 
#include 

typedef enum{checkled, heatingup, exposure, stop} machine;
machine currentstate=checkled;

typedef enum{twenty, fourty, sixty, eighty} brightness;
brightness light=twenty;

typedef enum{twoseconds, fourseconds, eightseconds, sixteenseconds} exposuretime;
exposuretime time=twoseconds;

volatile uint16_t tick=0;
volatile uint16_t oldtick=0;

volatile uint8_t flagchanged=0;

ISR(PCINT2_vect)
{
    if((PIND&(1<=95 && counter<=101)//per il 5% del periodo sta acceso
                            {

                                if(counter==101)
                                {
                                    PORTC&=~(1<=5 && counter<=6)//20% on
                                    {
                                        if(counter==6)
                                        {
                                            PORTC&=~(1<=4 && counter<=6)//40% on
                                    {
                                        if(counter==6)
                                        {
                                            PORTC&=~(1<=3 && counter<=6)//60% on
                                    {
                                        if(counter==6)
                                        {
                                            PORTC&=~(1<=2 && counter<=6)//80% on
                                    {
                                        if(counter==6)
                                        {
                                            PORTC&=~(1<
0
この質問チェックリストとすべてを読んでください。質問が不承認となる可能性のある理由については、 idownvotedbecau.se をご覧ください。最後に、プログラムのデバッグ方法をご覧ください。 。
追加された 著者 Some programmer dude,
この質問チェックリストとすべてを読んでください。質問が不承認となる可能性のある理由については、 idownvotedbecau.se をご覧ください。最後に、プログラムのデバッグ方法をご覧ください。 。
追加された 著者 Some programmer dude,
あなたのデバイスはウォッチドッグを持っていますか?誤って有効にした場合(またはデフォルトで有効になっている場合)、吠えないように無効にする必要があります。これが、予期しないリセットの原因の1つです。
追加された 著者 Yunnosch,
あなたのデバイスはウォッチドッグを持っていますか?誤って有効にした場合(またはデフォルトで有効になっている場合)、吠えないように無効にする必要があります。これが、予期しないリセットの原因の1つです。
追加された 著者 Yunnosch,
あなたのデバイスが予期せぬリセットを受けていないことを証明できますか?それらは予期せずに変数を初期状態に戻すためのもっともらしい情報源です。
追加された 著者 Yunnosch,
あなたのデバイスが予期せぬリセットを受けていないことを証明できますか?それらは予期せずに変数を初期状態に戻すためのもっともらしい情報源です。
追加された 著者 Yunnosch,
あなたはすべての割り込み関連のコードなしで問題を実証することができますか?そうでなかったらそれはおそらく割り込みがあなたの論理と混乱していることを意味します。もしそうであれば、ここに割り込みのないコードを表示すれば、たぶん早くより良い助けになるでしょう。それはMCVEのMにもっと良くマッチするでしょう。
追加された 著者 Yunnosch,
あなたはすべての割り込み関連のコードなしで問題を実証することができますか?そうでなかったらそれはおそらく割り込みがあなたの論理と混乱していることを意味します。もしそうであれば、ここに割り込みのないコードを表示すれば、たぶん早くより良い助けになるでしょう。それはMCVEのMにもっと良くマッチするでしょう。
追加された 著者 Yunnosch,
すべての識別子を英語に翻訳することによって、表示されているコード、したがって質問を理解しやすくすることができます。
追加された 著者 Yunnosch,
すべての識別子を英語に翻訳することによって、表示されているコード、したがって質問を理解しやすくすることができます。
追加された 著者 Yunnosch,
@RawCodeから[email protected]に連絡してください。すぐに話します。
追加された 著者 Tim Wensky,
@RawCodeから[email protected]に連絡してください。すぐに話します。
追加された 著者 Tim Wensky,
私はここのコメント欄がコミュニケーションの良い方法だとは思いません。私はあなたに連絡するもう一つの方法を見つけられなかった、難しい。あなたのEメールを送ってもらえますか?
追加された 著者 Tim Wensky,
私はここのコメント欄がコミュニケーションの良い方法だとは思いません。私はあなたに連絡するもう一つの方法を見つけられなかった、難しい。あなたのEメールを送ってもらえますか?
追加された 著者 Tim Wensky,
どういたしまして。 PWM出力は問題ありませんが、コードを大幅に単純化することができます。どれがあなたにとって非常に役に立つかもしれないかについて考えるべきことだけです:counter =(counter + 1)%MAX_COUNT_VALUE;それはどのようにあなたを助けますか?これはあなたのすべての 'if'節にcounterを使って何をするのでしょうか?また、 '<='や '> ='のように常にカウンタを比較する必要がありますが、ほとんどの場合は '=='で十分ではないでしょうか。もしそうなら、「switch」文はそれほど良くないでしょうか。自分のコードを最適化し、よりエレガントにすることに興味がある場合は、ここに別のコメントを投稿してください。ここでチェックします。
追加された 著者 Tim Wensky,
どういたしまして。 PWM出力は問題ありませんが、コードを大幅に単純化することができます。どれがあなたにとって非常に役に立つかもしれないかについて考えるべきことだけです:counter =(counter + 1)%MAX_COUNT_VALUE;それはどのようにあなたを助けますか?これはあなたのすべての 'if'節にcounterを使って何をするのでしょうか?また、 '<='や '> ='のように常にカウンタを比較する必要がありますが、ほとんどの場合は '=='で十分ではないでしょうか。もしそうなら、「switch」文はそれほど良くないでしょうか。自分のコードを最適化し、よりエレガントにすることに興味がある場合は、ここに別のコメントを投稿してください。ここでチェックします。
追加された 著者 Tim Wensky,
もちろん、タイマーの初期化に間違いがあったり、間違った割り込みベクトルを使用している可能性があります。必ず確認してください。すみません、しかし私はこれらのコントローラーをあまりよく知らないので、私はあなたに言うことができません。
追加された 著者 Tim Wensky,
もちろん、タイマーの初期化に間違いがあったり、間違った割り込みベクトルを使用している可能性があります。必ず確認してください。すみません、しかし私はこれらのコントローラーをあまりよく知らないので、私はあなたに言うことができません。
追加された 著者 Tim Wensky,
これが本当の問題だとは思わない。注意してください!これは、これら2つのISRが同時に実行されていて、一緒にスタックがオーバーフローするためです。私はこれらのISRが入れ子になっていると思います。 ISRの優先順位を変更して、これら2つのISRが相互に干渉できないようにすることはできますか。
追加された 著者 Tim Wensky,
これが本当の問題だとは思わない。注意してください!これは、これら2つのISRが同時に実行されていて、一緒にスタックがオーバーフローするためです。私はこれらのISRが入れ子になっていると思います。 ISRの優先順位を変更して、これら2つのISRが相互に干渉できないようにすることはできますか。
追加された 著者 Tim Wensky,
わかりました、スタックオーバーフローに直面している可能性が非常に高いです。 ISRに入ると、スタックが大きくなりすぎ、変数が上書きされます。私のIDEはわかりませんが、スタックサイズを変更できる場所があるはずです。試してみて、スタックサイズを増やしてみましょう。約32バイトとしましょう。
追加された 著者 Tim Wensky,
わかりました、スタックオーバーフローに直面している可能性が非常に高いです。 ISRに入ると、スタックが大きくなりすぎ、変数が上書きされます。私のIDEはわかりませんが、スタックサイズを変更できる場所があるはずです。試してみて、スタックサイズを増やしてみましょう。約32バイトとしましょう。
追加された 著者 Tim Wensky,
どういたしまして!さらに割り込みを有効にして、ISR(PCINT2_vect){return;の直後に 'return'ステートメントを配置します。エラーが再度発生するかどうかを確認してください。
追加された 著者 Tim Wensky,
どういたしまして!さらに割り込みを有効にして、ISR(PCINT2_vect){return;の直後に 'return'ステートメントを配置します。エラーが再度発生するかどうかを確認してください。
追加された 著者 Tim Wensky,
もう1つ指摘したいことは、変数が変更される時間は完全に非同期であるため、ISRおよび通常の関数で変数(この場合はcurrentstate)を変更することは常に悪い考えです。 while(1)ステートメントの直後に、currentstateのコピーを作成し、そのコピーを使って作業します。そうすれば、メインループでそれを使用している間に値が変更されないようにすることができます。
追加された 著者 Tim Wensky,
もう1つ指摘したいことは、変数が変更される時間は完全に非同期であるため、ISRおよび通常の関数で変数(この場合はcurrentstate)を変更することは常に悪い考えです。 while(1)ステートメントの直後に、currentstateのコピーを作成し、そのコピーを使って作業します。そうすれば、メインループでそれを使用している間に値が変更されないようにすることができます。
追加された 著者 Tim Wensky,
コードを読むだけでは、コントローラの動作を判断することはできません。私は、問題を解決するために私が何をするのかを段階的に説明することしかできません。最初のステップは、sei()命令をコメントアウトすることで、割り込みを許可しないことです。問題が解消されれば、それは割り込みに関連し、そうでなければそうではありません。非常に典型的な問題はこれらの小さなコントローラのスタックオーバーフローです。
追加された 著者 Tim Wensky,
コードを読むだけでは、コントローラの動作を判断することはできません。私は、問題を解決するために私が何をするのかを段階的に説明することしかできません。最初のステップは、sei()命令をコメントアウトすることで、割り込みを許可しないことです。問題が解消されれば、それは割り込みに関連し、そうでなければそうではありません。非常に典型的な問題はこれらの小さなコントローラのスタックオーバーフローです。
追加された 著者 Tim Wensky,
助けてくれてありがとう!私はエラーを見つけた:私はTIMER0を設定したが、ISRで私はTIMER1をチェックしていた。ちょっとしたエラーです。 PWM出力についてどう思いますか?
追加された 著者 RawCode,
確かに2分ください
追加された 著者 RawCode,
確かに2分ください
追加された 著者 RawCode,
はい、この問題は割り込みとは無関係であることを証明できます。ウォッチカードから変数の値を変更しても問題が解決しません。私の教授は決してウォッチドッグタイマーについて話しませんでした、このクラスではそれらを使用しないので、私はそれらを使用する方法を知りません。編集:私は私のコードを翻訳
追加された 著者 RawCode,
はい、この問題は割り込みとは無関係であることを証明できます。ウォッチカードから変数の値を変更しても問題が解決しません。私の教授は決してウォッチドッグタイマーについて話しませんでした、このクラスではそれらを使用しないので、私はそれらを使用する方法を知りません。編集:私は私のコードを翻訳
追加された 著者 RawCode,
counter =(counter + 1)%MAX_COUNT_VALUE; がどのように役立つかわかりません。本当にありがとう!
追加された 著者 RawCode,
counter =(counter + 1)%MAX_COUNT_VALUE; がどのように役立つかわかりません。本当にありがとう!
追加された 著者 RawCode,
助けてくれてありがとう!私はエラーを見つけた:私はTIMER0を設定したが、ISRで私はTIMER1をチェックしていた。ちょっとしたエラーです。 PWM出力についてどう思いますか?
追加された 著者 RawCode,
はい、問題は再び発生します。私は自分のすべての条件をコメントアウトし、あなたが示唆したように return; を入れます。
追加された 著者 RawCode,
sei()命令をコメントアウトしたところで、今はうまくいくようです。わかりません。この問題の原因は何ですか?何の割り込み?アドバイスをありがとう@TimWensky、私は本当に感謝しています。
追加された 著者 RawCode,
sei()命令をコメントアウトしたところで、今はうまくいくようです。わかりません。この問題の原因は何ですか?何の割り込み?アドバイスをありがとう@TimWensky、私は本当に感謝しています。
追加された 著者 RawCode,
理由はわかりませんが、タイマー命令とタイマーISRをコメントアウトしただけで問題は発生しません。たぶん私は何か悪いことを設定しましたか?
追加された 著者 RawCode,
理由はわかりませんが、タイマー命令とタイマーISRをコメントアウトしただけで問題は発生しません。たぶん私は何か悪いことを設定しましたか?
追加された 著者 RawCode,
はい、問題は再び発生します。私は自分のすべての条件をコメントアウトし、あなたが示唆したように return; を入れます。
追加された 著者 RawCode,

4 答え

メインコードでは、タイマ0のアウトプットコンペア割り込みを有効にしています。

TIMSK0|=(1<

しかし、このベクタに対する割り込みハンドラはありません(代わりにTIMER1_COMPA_vect - タイマ1用)。

そのため、タイマー割り込みが発生すると、デフォルトのベクトルによって処理されます。これは、制御をリセットベクトルにリダイレクトするだけです。これにより、変数の初期化を含むアプリケーションが最初から開始されます。

そのため、解決策は簡単です。OCIE0Aを無効にするか、この割り込み用のハンドラを作成します。

1
追加された

メインコードでは、タイマ0のアウトプットコンペア割り込みを有効にしています。

TIMSK0|=(1<

しかし、このベクタに対する割り込みハンドラはありません(代わりにTIMER1_COMPA_vect - タイマ1用)。

そのため、タイマー割り込みが発生すると、デフォルトのベクトルによって処理されます。これは、制御をリセットベクトルにリダイレクトするだけです。これにより、変数の初期化を含むアプリケーションが最初から開始されます。

そのため、解決策は簡単です。OCIE0Aを無効にするか、この割り込み用のハンドラを作成します。

1
追加された

あなたは以下の行でタイマ/カウンタ 0の比較一致A割り込みを許可しています。

TIMSK0|=(1<

しかし、下の項でタイマ/カウンタ 1の比較A割り込みISRを使おうとしています。

ISR(TIMER1_COMPA_vect) { tick++; }

修正案

以下のようにタイマ初期化を変更することによって、タイマ/カウンタ1のコンペアマッチA割り込みを有効にして、ISRをそのままにします。

`TIMSK1|=(1<

OR

タイマ/カウンタ 0の比較一致A割り込み初期設定をそのまま保ち、割り込み時にタイマ/カウンタ 0のISRを呼び出すために以下のようにISRを変更してください。

ISR(TIMER0_COMPA_vect) {     tick ++;

これが役立つことを願っています..

0
追加された

あなたは以下の行でタイマ/カウンタ 0の比較一致A割り込みを許可しています。

TIMSK0|=(1<

しかし、下の項でタイマ/カウンタ 1の比較A割り込みISRを使おうとしています。

ISR(TIMER1_COMPA_vect) { tick++; }

修正案

以下のようにタイマ初期化を変更することによって、タイマ/カウンタ1のコンペアマッチA割り込みを有効にして、ISRをそのままにします。

`TIMSK1|=(1<

OR

タイマ/カウンタ 0の比較一致A割り込み初期設定をそのまま保ち、割り込み時にタイマ/カウンタ 0のISRを呼び出すために以下のようにISRを変更してください。

ISR(TIMER0_COMPA_vect) {     tick ++;

これが役立つことを願っています..

0
追加された