ATmega168とWinAVRで割り込みのプログラミングをしています。
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER1_OVF_vect)
{
TCNT1 = 65500;
PORTC ^= 0x02;
}
int main()
{
int i;
DDRC = 0x07;
PORTC ^= 0x01;
TCCR1B = 0x00;
TCNT1 = 65500;
TIMSK1 = _BV(TOIE1);
TCCR1B = 0x05;
sei();
while (1) {
PORTC ^= 0x04;
for(i=0;i=500;i++){}
}
}
上記のプログラムを組んでみたのですが。while文に入ってfor文に少し入ってからISRの処理が始まるのですが。ISRの処理が終わってから又for文の処理に戻ろうとしません。なのでPORTC0x04の点滅が起こりません。PORTC0x04の点滅もしながらPORTC0x02の点滅もしたいのですがどうすれば良いのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (6件)

>回答ありがとうございます。

プログラムの確認はWinAVRのシュミレーションで確認しました。

シミュレータ上でデバッガで停止させて確認したと認識よろしいですか?
なぜ、mainに戻っていないと確信を得たか教えてください。

>あと割り込みと言うのはmain()文を中心に処理するが割り込みの条件がはいったならばmain文の処理をいったん停止し、割り込みの内容を優先する。割り込みの処理が終了したらmain文の処理に戻っていくという認識をしているのですが合っているのでしょうか?

main文だとmain関数の中だけ見たいですが、割り込み処理以外の部分でプログラムが走っている場合は、どこの処理中でも割り込み信号が発生した瞬間に処理を中断して割り込み処理終了後に続きの処理に戻ります。
割り込む命令の単位はマシン語1命令の単位でありC言語の文の単位では有りません。

>メインでPORTCを変更する間は割り込みを禁止してください。
cil();
PORTC ^= 0x04;
sei();

ここらを参考に↓
http://avrwiki.jpn.ph/wiki.cgi?page=Getting+Star …
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
それはプログラム的に言うと
int main(){
  ・
  ・
while (1) {
cil();
PORTC ^= 0x04;
sei();
for(i=0;i=500;i++){}
}
}
こういうことで良いんでしょうか?
うまくいきません。

お礼日時:2009/05/29 18:33

>F11を押すとプログラムが一つずつ進んでいくのでそれを見ていると


>ISRに入った後main文に戻らずにISR文の中でずっとループしていました。

ループ構造を持たないISRの中でループするのは変だと思いません?
それは、割り込みタイマがステップ実行中(F11)でも無関係にカウントダウンしてオーバーフローしてるんじゃないでしょうか?なので割り込みを抜けると直ぐ再度割り込んでいるんじゃ?
割り込みのデバッグはF11で実行しないで下さい。必ずブレーク設定して調べたい命令の所で止めましょう。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。

お礼日時:2009/06/15 18:31

R32Cさんの指摘まで基本的すぎて見落としてましたが、このコードは確実に無限ループします。


>for(i=0;i=500;i++){}
>}
i=500は代入文で条件式では無いので常に真でループから抜けることが出来ません。つまり無限ループです。

>シミュレータ上でデバッガで停止させて確認したと認識よろしいですか?
>なぜ、mainに戻っていないと確信を得たか教えてください。

こちらは答えてもらえないんでしょうか?
デバッガがちゃんと使えたら無限ループしていることは直ぐに確認できたのに勿体無いですね。
    • good
    • 0
この回答へのお礼

i=500になったら終了と言うことではなかったのですね。
シュミレータはデバッガと言うよりビルド&ランをしていました。
F11を押すとプログラムが一つずつ進んでいくのでそれを見ていると
ISRに入った後main文に戻らずにISR文の中でずっとループしていました。

お礼日時:2009/05/30 06:42

>for(i=0;i=500;i++){}


無限ループしているのでは?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
for文を抜けるとwhile文で戻ってまたportにいきますよね。
それがいかないんです。だからiが500に成ったら自動的に上に戻るはずなんですけどね。まだ良くわかっていません。

お礼日時:2009/05/29 18:23

プログラムを見る限りは正常に動作するとは思えません。



PORTC ^= 0x04;
はアセンブラ1命令に置き換えれませんよね?
(1)レジスタ←PORTC
(2)レジスタ←レジスタ XOR 0x04
(3)レジスタ→PORTC
となるはずですので(1)~(3)の間のどこかで割り込む可能性が出てきます。もし(2)で割り込んだらPORTCの書き換えが割り込み中で行われるので(2)の時点でレジスタが保持している値と実際のPORTCの値が違う可能性かが出てきます。

>上記のプログラムを組んでみたのですが。while文に入ってfor文に少し入ってからISRの処理が始まるのですが。ISRの処理が終わってから又for文の処理に戻ろうとしません。

これはどのようにして確認しましたか?
LEDの点滅以外のデバッガ等で確認しましたか?

>なのでPORTC0x04の点滅が起こりません。PORTC0x04の点滅もしながらPORTC0x02の点滅もしたいのですがどうすれば良いのでしょうか?

メインでPORTCを変更する間は割り込みを禁止してください。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。プログラムの確認はWinAVRのシュミレーションで確認しました。
あと割り込みと言うのはmain()文を中心に処理するが割り込みの条件がはいったならばmain文の処理をいったん停止し、割り込みの内容を優先する。割り込みの処理が終了したらmain文の処理に戻っていくという認識をしているのですが合っているのでしょうか?

お礼日時:2009/05/28 17:26

こんにちは。


ええと、多分ですが、関数ISRが割り込みハンドラとしてコンパイルされていないため、正しくリターンできていないのではないでしょうか。
割り込みハンドラとしてのコンパイルの仕方は、コンパイラのマニュアル等を見てください。
あと、蛇足ですが、PORTCをメインルーチンと割り込みの両方から変更していますが、メインルーチンで変更する間は割り込み禁止にするとかしないと、動きがおかしくなると思います。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
割り込み禁止とはcil();のことでしょうか?
具体的にどこに入れれば良いのでしょうか?
ソースで示していただけると大変うれしいです。
どうか、よろしくお願いします。

お礼日時:2009/05/28 17:20

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q中高年の方の電車待ちの列への割り込み

東京都心及び多摩地区での、特にJR東日本線の電車に乗車の際ですが、どの乗車口でも二列に並んで皆さん電車の到着及び乗車待ちをされているところで、最近立て続けに男女問わず50歳前後から60歳くらいの中高年の方があからさまな割り込みを当然のようにされてきます。

例えば乗車口の表示や案内がわかりずらいとか他の乗車口も含め整列されていない、とか、故意ではない場合は何も思わないのですが、あからさまな割り込みにあたる行為で、たまにならまだ質問するには至らなかったのですが、最近急に何度もあったので、どうしても気になってしまいました。

また、先頭に並んでいて横入りされるパターン以外にも、整列していて列の途中にいる場合でも私の前に割り込んできます。

別に年上を敬わない訳でもないし、お体が悪い方や理由があれば譲るし、という風には思うのですが、無言で当然のように横入りしてくるのは、ここまで頻発していると、怒りというよりかは理由が知りたくて質問させていただきました。

何か理由があるなら一言言ってもらえれば、とは思うのですが・・なぜ当たり前のように皆さん横入りされるのでしょうか。またよく思わない私の方がおかしいのでしょうか。やはり当然のように横入りされた場合でも快く入れてあげるべきなのでしょうか。

東京都心及び多摩地区での、特にJR東日本線の電車に乗車の際ですが、どの乗車口でも二列に並んで皆さん電車の到着及び乗車待ちをされているところで、最近立て続けに男女問わず50歳前後から60歳くらいの中高年の方があからさまな割り込みを当然のようにされてきます。

例えば乗車口の表示や案内がわかりずらいとか他の乗車口も含め整列されていない、とか、故意ではない場合は何も思わないのですが、あからさまな割り込みにあたる行為で、たまにならまだ質問するには至らなかったのですが、最近急に何度もあっ...続きを読む

Aベストアンサー

あ~ありますね。更年期が始まった男女50歳前後~60歳くらいの方々の割り込み…

ちょうど男性はテストステロンが、女性はエストロゲンが急激に減少する時期ですね。

男性のテストステロンの急激な減少は、物や事の認知に関係します。
悪い言葉を使えば、空気が読めず相手の立場を考えられなくなってきたり、うつや短気を起こしやすくなったりと、感情のコントロールが難しくなります。
性格的にも、バブル期を経験して得た根拠のない自信とでも申しますか、草食系などと呼ばれる今の時代の方々より貪欲で少々気が太いというか大きい方もいますね。

女性のエストロゲンは、淑女ホルモンと呼ばれることがあります。
女性らしい感情や体形など淑女のようになる時期で、これに対して女性の生理前などは悪女期などとも呼ばれています。

その割り込みがよく起きる場所が都心や多摩地区とのことで、進歩が速く中高年が時代の流れについてゆけない都会での生活のストレスが更年期に拍車をかけているのではないかと思いました。

更年期は目に見える部分はご自覚できるのですが、精神的なものの多くは自覚がないので困りものです。
怒りっぽいとか図太くなったと子供に言われても、自分はまだまだ現役であり、目上を労わらない生意気な若者が悪いのだといった意識ですしね。

自分では空気が読みにくくなりますが、他人には空気を読んでほしいという欲求が強くなる時期でしょうね(苦笑)

僕の周囲のこの年代の方々で、妙な部分でのみプライドが高い方々がいます。
その方々には「割り込むな」と言うと逆ギレするので、「ご存知ですか」を付け加えると良いです。
「並んでいますよ。ご存知ですか?」といった具合いに、今の時代からはずれてしまっていますよという意味の言葉を付け加えると、「分かっている!」「間違えただけ!」となりやすいです。

あ~ありますね。更年期が始まった男女50歳前後~60歳くらいの方々の割り込み…

ちょうど男性はテストステロンが、女性はエストロゲンが急激に減少する時期ですね。

男性のテストステロンの急激な減少は、物や事の認知に関係します。
悪い言葉を使えば、空気が読めず相手の立場を考えられなくなってきたり、うつや短気を起こしやすくなったりと、感情のコントロールが難しくなります。
性格的にも、バブル期を経験して得た根拠のない自信とでも申しますか、草食系などと呼ばれる今の時代の方々より貪欲で少々...続きを読む

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

QAVRマイコンの割り込みについて

AVRマイコンの割り込みについて

初心者です。
・AVRマイコンの割り込みの優先順位ですが、割込みベクターのアドレスが小さい順に優先度が高いでよろしいでしょうか?
・優先低の割り込みルーチンを処理している時に、優先高の割り込みが入った場合、
 (1)優先低の割り込みルーチン処理中断→優先高の割り込みルーチンの処理、完了→優先低の割り込みルーチン処理再開(中断ヶ所から)
 (2)優先低の割り込みルーチン処理、完了→優先高の割り込みルーチンの処理、完了
 (3)その他
(1)、(2)、(3)のどの処理が行われますか?
・優先高の割り込みルーチンを処理している時に、優先高の割り込みを禁止し、ルーチン内で優先低の割り込みが入った場合、優先高の割り込みルーチンから優先低の割り込みルーチンにとばすことは可能でしょうか?

以上、よろしくお願い致します。

Aベストアンサー

AVRは使用経験がないのでマイコン一般的な回答ですが、
・優先度は割り込みごとに設定できるものが多いです。同優先度の割り込みが複数入った場合にどうなるかはハンドラ次第です。

・多重割り込みをサポートしていない、あるいは有効にしていない場合は(2)です。多重割り込みが有効の場合は(1)ですね。

・多重割り込みで可能なのはより高優先の割り込みのみです。ISR実行中にその割り込みを禁止したとしても、ISR自体が終了する訳ではない上に優先度は有効のままですから、ISR中に低優先度割り込みが入ることはできません。

Qint nII[10] = { 0 }について

久々にCを使ってプログラムを組んでいるのですが、基本的な構文を思い出せず
いくつか教えていただきたく質問させていただきました。

1)配列すべてを初期化するのに、宣言時に

int nII[10] = { 0 };

で大丈夫だった(全ての要素が0で初期化)と記憶しているのですが、間違いないでしょうか?

2)構造体の初期化は

struct tm tm;
memset(&tm, 0, sizeof(struct tm))

で大丈夫でしょうか?

3)構造体の宣言は

typedef struct{
int a;
}HOGE, *LPHOGE;

HOGE st; // <- struct HOGE stと同じ
LPHOGE pst; // <- struct HOGE* pstと同じ

で問題ないでしょうか?

以上、3つ質問になって申し訳ないのですが、よろしくお願いします。

Aベストアンサー

1)OK
2)たぶんOK
3)HOGEという名前の構造体はない(当該の構造体には名前がない)ので、
// 以下のコメント記述が誤っています。ただし、

HOGE st;
LPHOGE pst;
という定義そのものはOK

Q割り込み処理について

割り込み処理について

初心者です。
AVRマイコンの割り込み処理について質問させて頂きます。
INT0割り込みの割り込みが入ったら、割り込みルーチン中の他の割り込みを許可し、かつINT0の割り込みを禁止したいのですが、下記ソースで問題はありませんか?
INT0割り込みが終了して、メインルーチンに復帰した直後にINT0割り込みを許可したいのですが、下記ソース(1)で問題はありませんか(メインルーチンに復帰した直後に許可したいのですが、方法がわかりません)?

ISR(INT0_vect,ISR_NOBLOCK)
{
    int0割り込み禁止
     ・
     ・
     ・
     ・
   (int0割り込み要求フラグクリア) ・・・・(1)    
   (int0割り込み許可)         ・・・・(1)  
}

よろしくお願い致します。

Aベストアンサー

初心者なら、マイコンのマニュアルを見てプログラムできるようになる練習をすることです。

URLに個別の割込みマスクとretiでの動作等書かれています。

・SREG ($3F) : Status Register
bit7-I : Global Interrupt Enable
すべての割り込みを可能にするにはこのビットを1にする必要があります。割り込みがかかるとクリアされ、割り込みルーチンの終わりでRETI命令がかかると同時に再びセットされます。CEI,SEI命令でクリア,セットできます。

にあるように、基本的にはAVRの割込みモデルは多重割込みでない対応としているようです。
これを
>割り込みルーチン中の他の割り込みを許可し
ということなので、多重割込みの対応をしたいようですが、多重割込みについての問題点等
検討されているでしょうか。たとえば、多重割込みでは何重の多重割込みを想定して、それに必要なスタックサイズは検討されていますか?

されているとして、以下のようになると思います。

ISR(INT0_vect,ISR_NOBLOCK)
{
    int0割り込み禁止
    ・SREG ($3F) : Status Register bit7-I : Global Interrupt Enableを1にする。
     (これで割込み許可になる。もともと他の割込みは許可されているものと考えています。)
     ・
     ・このへんは他の割込みが許可状態。
     ・
     ・
    ・SREG ($3F) : Status Register bit7-I : Global Interrupt Enableを0にする。
   (int0割り込み要求フラグクリア) ・・・・(1) これは不要と思います。(理由)   
   (int0割り込み許可)         ・・・・(1)  
}

理由:
・割り込みフラグは割り込みが起こったときにセットされ、割り込みハンドリング時に自動でクリアされます。割り込みをマスクしていた場合にはフラグは立ったままとなります。

参考URL:http://ww2.tiki.ne.jp/~maro/AVR/programing/index.html

初心者なら、マイコンのマニュアルを見てプログラムできるようになる練習をすることです。

URLに個別の割込みマスクとretiでの動作等書かれています。

・SREG ($3F) : Status Register
bit7-I : Global Interrupt Enable
すべての割り込みを可能にするにはこのビットを1にする必要があります。割り込みがかかるとクリアされ、割り込みルーチンの終わりでRETI命令がかかると同時に再びセットされます。CEI,SEI命令でクリア,セットできます。

にあるように、基本的にはAVRの割込みモデルは多重割込みでない対応と...続きを読む

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Qシステムの割り込みについて システムの割り込みで調べてもよく分からないのですが遅延など調べましたが、

システムの割り込みについて
システムの割り込みで調べてもよく分からないのですが遅延など調べましたが、主にシステムの割り込みとはどんなのでしょうか?
先程cpuが1%(何もしてない時1〜0%)でしたがシステムの割り込みというはじめて聞いた単語がありましたので質問されていただきました。
システムの割り込みが0〜0.3%になっていて何か動いているのかなと思い数分ほど放置しましたが常に0〜0.3%だったのでシャットダウンしましたが割り込みと書いてましたのでもしかしたらシャットダウンとかしない方が良かったのでしょうか?

Aベストアンサー

ある処理の途中に、その処理以外の事象発生により、処理を中断(これが割り込みです)して別のことを行う様なことを言います。
例えば、円周率πの計算プロセスが稼働中はほぼCPU100%で動作しますが、この計算中にDVDメディアが装填されて自動再生が動き出すケースです。これは円周率πの計算中にDVDデバイスからシステムに割り込みが入り、システムが計算を一旦中断して自動再生プログラムを起動(CPUをこの処理に回す)したらかなる状態なのです。
割り込み要件には、上記のデバイスの割り込みの他にタイマーの割り込み(特定の時間が経過したらある処理を実行する等)や他のプロセスが終了したことによる割り込み等多種多様なものがあります。

Q※int nyuuryoku_kosuu = 0; ※の部分は何を宣言しているのでしょうか?

#include <stdio.h>
struct tanka_ kosuu {
  構造体名
int tanka;
int kosuu;         型 構造体のメンバ(変数名)
int kingaku;
};
int main()
{
struct tanka_kosuu data [10];
構造体宣言 構造体名  変数名 値・・10を代入
      struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
               型 構造体メンバ(変数名)の初期化
※int nyuuryoku_kosuu = 0;
以上※の部分は何を宣言しているのでしょうか?
while(kari_nyuuryoku.tanka != 0){
scanf("%d %d", &kari_nyuuryoku.tanka,
&kari_nyuuryoku.kosuu);
data [nyuuryoku_kosuu] = kari_nyuuryoku;
nyuuryoku_kosuu++;
}
return 0;
}
 
以上よろしくお願いいたします。

#include <stdio.h>
struct tanka_ kosuu {
  構造体名
int tanka;
int kosuu;         型 構造体のメンバ(変数名)
int kingaku;
};
int main()
{
struct tanka_kosuu data [10];
構造体宣言 構造体名  変数名 値・・10を代入
      struct tanka_kosuu kari_nyuuryoku = {-1, 0, 0};
               型 構造体メンバ(変数名)の初期化
※int nyuuryoku_kosuu = 0;
以上※の部分は何を宣言しているのでしょうか?
while(kari_nyuuryoku.tanka != 0){
scanf("%d ...続きを読む

Aベストアンサー

※のところでnyuuryoku_kousuuの初期値を0と置くことで、data[nyuuryoku_kosuu]=kari_nyuuryoku;でkari_nyuuryokuの値をnyuuryoku_kosuuに正しく入れるための宣言だと思います

Qpicタイマ0割り込みについて

タイマ0割り込みについて教えて下さい。
解説書などに、割り込みルーチンの最初の部分で

(1)割り込みフラグ(TMR0IF)を消す
(2)TMR0を再設定する

と書かれていますが、なぜ(2)を割り込みルーチンの最初で行うのでしょう?
これでは、
・1秒ごとに割り込みを発生させたい
・割り込みルーチンの作業時間は0.5秒
だとすると、結果的に割り込み発生は0.5秒ごとになってしまいます。

TMR0再設定は割り込みを抜ける時(retfie の直前)に行えば、ほぼ希望通りの間隔で、割り込みを発生させられると思うのですが、それはルール違反なのでしょうか?

Aベストアンサー

N0.2です。
普通の処理だったら問題無いのですが、
たとえば、割り込みが発生してもすぐに
割り込みルーチンに入れない様な場合、
気を付けないと次の割り込みが発生してしまいます。
で、マニュアルでは割り込み原因となる
TMR0を再設定するように指示をしているのですが、
たしかに割り込み後に一定時間間隔でまた割り込みたい
場合には、抜ける前にまた再設定するしかありません。

ただ、通常の場合、一定時間の割り込みというのは
割り込みそのものを一定時間毎に発生させたい筈
なんです。
たとえば、割り込みは10mSおき、処理は1mSだとすると
スタート(0mS)から数えて
10mS 割り込み発生 TMR0再設定
11mS 割り込み処理終了
20mS 割り込み発生 TMR0再設定
21mS 割り込み処理終了
30mS 割り込み発生 TMR0再設定
と言うぐらいに、きれいに
10mSおきに割り込みが発生します。
しかも、割り込み処理が長くなっても短くなっても
間隔は変わりません。

Qthix.x = x; について(this.x とxの違い)

this xとxの指しているものは違うのだと思いますが、
それぞれが指しているものの違いについて教えてください。
public class aaa
{
//(中略)
public bbb (int x)
{
this.x = x;
}
}

Aベストアンサー

どっちの変数名も「x」だから悩ましいだけ。

メンバ変数の「x」を「Member_Value」に名前を変え、引数として与えられた仮変数の「x」を「Function_Paramater」に名前を変えてみましょう。

public class aaa
{
//(中略)
public bbb (int Function_Paramater)
{
this.Member_Value = Function_Paramater;
}
}
はい、こうなりました。

何か疑問点や質問はありますか?


人気Q&Aランキング