• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:PIC Timer0割り込み されない)

PIC Timer0割り込みがされない

このQ&Aのポイント
  • 12F609でTimer0割り込みが実行されません。動作的に割り込みハンドラが呼ばれていない感じです。
  • プログラムの中で割り込みハンドラが定義されており、割り込みフラグのチェックや処理も行われていますが、GP4の出力が正しく反転されません。
  • 初期時にGP4を1に設定しているため、割り込み処理での反転が機能しない可能性があります。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

あ、ごめん、忘れてた! PIC独特の【ページング】は? SFRによっては、ページを切り替えないとアクセスできないでしょ?

maruyama0422
質問者

お礼

やっと原因が特定できました! なんと恥ずかしいことに電源のノイズによる、マイコンの動作不良でした…。 16F84Aでプログラムを組んだ時は自作の実験ボードでテストし、その時は乾電池が電源でした。 だから問題なく動きました。 今回の回路は他回路と一緒に組み込まれたもので、電源にトランスを使っていました。 整流後の平滑が足りず50Hzの波形が大きく残っていたようで、マイコンが動作不良を起こしていたんです。 レギュレータの前に4700uFを足したところ無事動作するようになりました。 もともと680uFをつけていましたが、ほかの回路でも電流を食っているので足りなかったようです。 (素人の推測ですが) 基本的な部分ができていなくて恥ずかしいばかりです。 これほど回答していただいたのに、本当に申し訳ありませんでした。 お二人様ともありがとうございました。

その他の回答 (7)

  • kaoaru
  • ベストアンサー率33% (42/127)
回答No.8

「#include」で何を指定してますか? 肝心なことを聞きわすれていましたが、PIC Cなのでしょうか?これ。 それともPIC C Liteなのでしょうか?12F609ってサポートされてました? コンパイラのライブラリをチェックしてみましたか? 12F609の定義、多分、なかったかと・・・。

maruyama0422
質問者

お礼

回答ありがとうございます。 インクルードは #include "pic12f609.h" #include <htc.h> #include "delay.h" です。 コンパイラはHI-TECH社のCコンパイラを使っています。 (v9.82です) ライブラリを覗いてみると、12F609の定義は確かにありませんでした…。 サポートしていないのですか。 それが原因かもしれません。 12F609をサポートしているコンパイラってあるのでしょうか。

  • kaoaru
  • ベストアンサー率33% (42/127)
回答No.7

わからなくなったら「ソース丸投げ」というのはマズいです。ここでのQ&Aにありがちなパターンです。 「12F609のデータシート」は読まれていないのですね? これを読まないでプログラミングなんかできません。フリーダウンロードできるわけですから、熟読されてください。 http://ww1.microchip.com/downloads/en/DeviceDoc/41302A.pdf 原因は割込み開始の合図がない、ということです。それがわからなければ使えません! OPTION_REGにタイマ0の割込み許可をやってあげないと、割込みアドレスにジャンプしません。 せっかく「void interrupt blink(void)//---割り込みハンドラ---」ってあるのだから・・・これの意味がわかっていて書いているわけですよね? こういうのは、ほんとは先頭に「プロトタイプ宣言」しといたほうがわかりやすのですけど・・・。

maruyama0422
質問者

お礼

回答ありがとうございます。 >わからなくなったら「ソース丸投げ」というのはマズいです。 すみません。 >「12F609のデータシート」は読まれていないのですね? 読んであります。 >原因は割込み開始の合図がない あります。 >ほんとは先頭に「プロトタイプ宣言」 それは知りませんでした…。 チェックしておきます。

回答No.5

じゃあ、あとは、タイマースタートがかかっていないとしか考えられないね。一般的なマイコンでは、何らかのタイマースタート・ストップができるけどね。そうでなければ、完全にお手上げ。もしくは、レジスタの書き換えが、プロテクトされているか。もしくは、その個体が故障しているか。わたしは、PICはン年前に【捨てた】から、これ以上は関わらないよ。 あ、そうそう、一般的なマイコンのポートの入出力の設定は、1で出力、0で入力というのがほとんど。 それと、プログラムは、割り込み関数の中でフラグを立てて、main()の中でフラグをチェックするか、ステートマシンを組むのが定石だよ。割り込み関数の中は、極力処理を減らして、さっさと終わらせる方が良いからね。

maruyama0422
質問者

お礼

ページングを含めいろいろ試してみましたが、やはり状況は変わりませんでした。 タイマーストップもプロテクトもされていませんし、もしかしたら故障しているのかもしれません。 >プログラムは、割り込み関数の中でフラグを立てて、main()の中でフラグをチェックするか、ステートマシンを組むのが定石 なるほど…。 参考にさせていただきます。 取りあえずしばらくの間は、現に動作している16F84Aを使っておこうと思います。 あと時間があれば、上位機種である12F615を買ってきて試してみようと思います。 回答ありがとうございました。

回答No.4

タイマ割り込みの周期は何秒? それの15回分って何秒? 出力GP4がHighのままって何で確認したの? 周期って、クロックが8MHzでクロック分周比が1/4でプリスケーラが1/256だと約520Hzだから、19.2ミリ秒になるよね。まさか、LEDの点灯でHighと判断したの? それともテスタ? オシロスコープじゃないの?

maruyama0422
質問者

お礼

回答ありがとうございます。 >クロックが8MHzでクロック分周比が1/4でプリスケーラが1/256 8bitのTMR0レジスタをオーバーフローさせるので、さらに1/256ですよ。 クロック分周比が1/4なので1サイクルにかかる時間は0.5us 割り込みが呼ばれる周期は0.5*256*256=32768us =32.768ms それを15回分なので32.768*15=491.52 約0.5秒になります。 これは16F84Aで動作確認をしており、きちんと0.5秒周期で動作していますので、計算ミスはありません。 ちなみに目に見えないだけで、実は高速でLEDが点滅しているのかと思いまして、 GP4 ^= 1; を GP4 = 0; に置き換えた (つまり、0.5秒後にLEDが消灯して終わり) →しかしLEDは消灯しない。 メインの GP4 = 1; を GP4 = 0; に置き換えた (つまり、消灯から点滅を始める) →しかしLEDは点灯しない、消灯したまま。 もし、高速で点滅しているのなら、この場合でも点灯しっぱなしになるはず。 >まさか、LEDの点灯でHighと判断したの? それともテスタ? オシロスコープじゃないの? オシロは持っていないのでLED点灯でしか確認できません。 ちなみにさらに、GP2/INT端子の変化で割り込みを発生させるINTEbitでの割り込みを試したところ割り込みハンドラは呼ばれました。 やはりTimer0自体が動作していないように感じるのですが…

回答No.3

GP4の示すポートを出力にし忘れているとか・・・。 > TRISIO = 0x00; は、 # TRISIO=0x10; ではないの? あーあ、PICのアークテクチャ見直すなんて、ン年ぶりだわ。疲れるね。

maruyama0422
質問者

お礼

回答ありがとうございます。 TRISIO<5:0>: GPIO Tri-State Control bit 1 = GPIO pin configured as an input (tri-stated) 0 = GPIO pin configured as an output とデータシートに記載があるので大丈夫かと思われます。

回答No.2

残念ながら、 > while(1) は、C言語の文法的に誤りです。 PICの書き方とか、どうとかいうレベルではなくね。 正しくは、 # while(1); もしくは、 # while(1){ #   ; # } などとなります。わたしの言った「文」とは、プログラムのことではなく、式文すなわち「;」で終わる式のことです。

maruyama0422
質問者

お礼

そういうことでしたか(汗) そう言われれば確かにその通りです… 私のミスでした。 回答ありがとうございました。

回答No.1

PICのプログラムをC言語で書こうというのが間違いだね。 これ、エラーでないの? やっぱり、PICのC言語はモドキだわ。 1.変数aが宣言されていない。・・・変数aは、【静的変数】であるはず。 2.while(1) に文が付いていない。 3.なんらかのヘッダーファイルがインクリュードされると思うけど・・・。 4.割り込みベクトルの設定はいらないのか。   たしか、PICは4番地が割り込みベクトルになっているから、   interrupt修飾子で勝手にテーブルに貼ってくれるのかな? > if(a%15==0) > { > GP4 ^= 1; > a=0; > } は、 # if(a==15) もしくは if(a>14) # { # GP4 ^= 1; # a=0; # } とすべし。なぜか、わかるでしょ?

maruyama0422
質問者

お礼

>1,3 ごめんなさい、当たり前のことなので記載していませんでしたが、メインプログラムの前にはちゃんとインクリュードや変数aの宣言、コンフィグなど書いてあります。 >2 while(1)に文がないのは、PICの割り込みでは普通です。 調べて頂ければすぐにお分かりになります。 >4 16F84Aではこれで大丈夫でした。 ネットで調べる限り、設定はないと思います。 >if(a%15==0) 確かにその通りです。 修正しました。 (無論状況は何も変わらず) 16F84Aはこれで普通に動いていますので、12F609固有の設定があるのだと思っているのですが、データシートを見ても見つけることができず、困惑している次第です。 回答ありがとうございました。

関連するQ&A