チョコミントアイス

12F609でTimer0割り込みが実行されません。

実行されないというか、動作的に割り込みハンドラが呼ばれていない感じです。

以下がプログラムです。


void main(void)//メインプログラム
{
T0IE = 0;
GPIO = 0;

T0CS = 0;
PSA = 0;
PS0 = 1;
PS1 = 1;
PS2 = 1;
TMR0 = 0;
TRISIO = 0x00;

a = 0;
GP4 = 1;

T0IE = 1;
GIE = 1;

while(1)
}

void interrupt blink(void)//---割り込みハンドラ---
{
if(T0IF==1)
{
T0IF = 0;

if(a%15==0)
{
GP4 ^= 1;
a=0;
}

a++;
}
}




以上です。

割り込み15回ごとにGP4の出力を反転させるプログラムです。
が、反転されずGP4は1のままになってしまいます。
(初期時にGP4=1としているので)

二週間粘りましたが、まったく解決できず困っています。

何がいけないのでしょうか。
ご教授お願いします。

A 回答 (8件)

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

    • good
    • 0
この回答へのお礼

やっと原因が特定できました!
なんと恥ずかしいことに電源のノイズによる、マイコンの動作不良でした…。

16F84Aでプログラムを組んだ時は自作の実験ボードでテストし、その時は乾電池が電源でした。
だから問題なく動きました。

今回の回路は他回路と一緒に組み込まれたもので、電源にトランスを使っていました。
整流後の平滑が足りず50Hzの波形が大きく残っていたようで、マイコンが動作不良を起こしていたんです。

レギュレータの前に4700uFを足したところ無事動作するようになりました。
もともと680uFをつけていましたが、ほかの回路でも電流を食っているので足りなかったようです。
(素人の推測ですが)


基本的な部分ができていなくて恥ずかしいばかりです。
これほど回答していただいたのに、本当に申し訳ありませんでした。

お二人様ともありがとうございました。

お礼日時:2012/11/20 18:15

「#include」で何を指定してますか?



肝心なことを聞きわすれていましたが、PIC Cなのでしょうか?これ。

それともPIC C Liteなのでしょうか?12F609ってサポートされてました?

コンパイラのライブラリをチェックしてみましたか?


12F609の定義、多分、なかったかと・・・。
    • good
    • 0
この回答へのお礼

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

インクルードは

#include "pic12f609.h"
#include <htc.h>
#include "delay.h"

です。

コンパイラはHI-TECH社のCコンパイラを使っています。
(v9.82です)


ライブラリを覗いてみると、12F609の定義は確かにありませんでした…。
サポートしていないのですか。
それが原因かもしれません。

12F609をサポートしているコンパイラってあるのでしょうか。

お礼日時:2012/11/08 23:54

わからなくなったら「ソース丸投げ」というのはマズいです。

ここでのQ&Aにありがちなパターンです。


「12F609のデータシート」は読まれていないのですね?

これを読まないでプログラミングなんかできません。フリーダウンロードできるわけですから、熟読されてください。

http://ww1.microchip.com/downloads/en/DeviceDoc/ …


原因は割込み開始の合図がない、ということです。それがわからなければ使えません!
OPTION_REGにタイマ0の割込み許可をやってあげないと、割込みアドレスにジャンプしません。

せっかく「void interrupt blink(void)//---割り込みハンドラ---」ってあるのだから・・・これの意味がわかっていて書いているわけですよね?

こういうのは、ほんとは先頭に「プロトタイプ宣言」しといたほうがわかりやすのですけど・・・。
    • good
    • 0
この回答へのお礼

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

>わからなくなったら「ソース丸投げ」というのはマズいです。
すみません。

>「12F609のデータシート」は読まれていないのですね?
読んであります。

>原因は割込み開始の合図がない
あります。

>ほんとは先頭に「プロトタイプ宣言」
それは知りませんでした…。
チェックしておきます。

お礼日時:2012/11/08 22:44

じゃあ、あとは、タイマースタートがかかっていないとしか考えられないね。

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

ページングを含めいろいろ試してみましたが、やはり状況は変わりませんでした。

タイマーストップもプロテクトもされていませんし、もしかしたら故障しているのかもしれません。


>プログラムは、割り込み関数の中でフラグを立てて、main()の中でフラグをチェックするか、ステートマシンを組むのが定石
なるほど…。
参考にさせていただきます。


取りあえずしばらくの間は、現に動作している16F84Aを使っておこうと思います。
あと時間があれば、上位機種である12F615を買ってきて試してみようと思います。


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

お礼日時:2012/10/31 19:47

タイマ割り込みの周期は何秒? それの15回分って何秒? 出力GP4がHighのままって何で確認したの?


周期って、クロックが8MHzでクロック分周比が1/4でプリスケーラが1/256だと約520Hzだから、19.2ミリ秒になるよね。まさか、LEDの点灯でHighと判断したの? それともテスタ? オシロスコープじゃないの?
    • good
    • 0
この回答へのお礼

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

>クロックが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自体が動作していないように感じるのですが…

お礼日時:2012/10/27 00:22

GP4の示すポートを出力にし忘れているとか・・・。



> TRISIO = 0x00;

は、

# TRISIO=0x10;

ではないの? あーあ、PICのアークテクチャ見直すなんて、ン年ぶりだわ。疲れるね。
    • good
    • 0
この回答へのお礼

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

TRISIO<5:0>: GPIO Tri-State Control bit
1 = GPIO pin configured as an input (tri-stated)
0 = GPIO pin configured as an output

とデータシートに記載があるので大丈夫かと思われます。

お礼日時:2012/10/26 18:19

残念ながら、



> while(1)

は、C言語の文法的に誤りです。
PICの書き方とか、どうとかいうレベルではなくね。
正しくは、

# while(1);

もしくは、

# while(1){
#   ;
# }

などとなります。わたしの言った「文」とは、プログラムのことではなく、式文すなわち「;」で終わる式のことです。
    • good
    • 0
この回答へのお礼

そういうことでしたか(汗)

そう言われれば確かにその通りです…
私のミスでした。

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

お礼日時:2012/10/25 23:03

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;
# }

とすべし。なぜか、わかるでしょ?
    • good
    • 0
この回答へのお礼

>1,3
ごめんなさい、当たり前のことなので記載していませんでしたが、メインプログラムの前にはちゃんとインクリュードや変数aの宣言、コンフィグなど書いてあります。

>2
while(1)に文がないのは、PICの割り込みでは普通です。
調べて頂ければすぐにお分かりになります。

>4
16F84Aではこれで大丈夫でした。
ネットで調べる限り、設定はないと思います。

>if(a%15==0)
確かにその通りです。
修正しました。
(無論状況は何も変わらず)



16F84Aはこれで普通に動いていますので、12F609固有の設定があるのだと思っているのですが、データシートを見ても見つけることができず、困惑している次第です。

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

お礼日時:2012/10/25 18:34

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