![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
HI-TechのPICC PRO 9.65を使ってPIC16F877Aのプログラミングをしています。
しかし、最近マイコンの動作が不安定になり、突然プログラムが暴走したりするので、プログラムカウンタに問題があると疑っています。
昔、アセンブラでプログラムしていた頃はPCLATHに書き込んでからPCLに書き込んだり、ORG命令などで対処していましたが、今回初めてPICCを導入したので対処の仕方がわかりません。
またCコンパイラによっては自動でPCLATHを繰り上げてくれるようなのですが、PICCの場合はどうなのでしょうか。
hexを除いてみると0x0800のあたりもびっしりコードでうまっているのですが。。。
ちなみに
asm("ORG 0x0800");
などのようにC言語の中にアセンブラで記述してもうまく解決できませんでした。
PCLATH = PCLATH + 0b000?????;
とか色々やってみたのですがだめでした。
そもそもヘッダやインクルードの内容がどの番地に書き込まれているかを調べる良い方法はないでしょうか。
1.PICCはPCの操作を自動でやってくれているのか
2.もしそうでなければどのようにして解決すればよいのか
で宜しくお願い致します。
No.3ベストアンサー
- 回答日時:
1.PICC(コンパイラ)はPCの管理を行いません。
2.暴走の原因を最近プログラミングしてしまったものと見受けられます。
PIC16Fxxxのアーキテクチャの問題ですが、内部にPC用の専用スタック(LIFO)が存在します。
アセンブラ上でCALL(関数呼び出し)が発生した場合、現状のPCカウント値を専用スタックへPUSHし、return命令時に自動でPOPします。
但し、このスタックはデバイスに拠りますがリングバッファとして大概8層程度しかありませんので、PICCを使って関数コールを8層以上掛けた場合容易に上書きされてしまいます。
C言語上で確認が可能です。関数コールを連続してスタック数以上呼んでいませんか?
正確なPCスタック数はMicrochipのサイトからデータシート内の記述で確認が可能です。
問題部の記述が無いので憶測ですが、知らずに使うと簡単に暴走する部分ですので。たぶんココじゃないかなぁ?
この回答への補足
アセンブルリストで何層スタックしているかを数えてみましたが、0x0000番地に急に飛んでしまう問題の箇所ではスタックは全くオーバーフローしていませんでした。
そのかわり、0x0000番地に飛んだときにスタックはリセットされないままですので、プログラムの2周目か3周目でオーバーフローしていることがわかりました。
つまりなぜ”CALL 0”という変な命令が生成されてしまったかを解決しないといけないようです。
遅くなりました、ありがとうございます。
PIC16F877Aのスタックは物理的に8層までです。アセンブラのときは8層も使わなかったためスタックのことはすっかり忘れていました。ありがとうございます。
本日シミュレーターで1ステップずつ確認してみましたが、0x0000番地に急に飛んでしまうという問題の箇所に差し掛かるまでに、”C言語の関数は”3~5層しか呼んでいませんでした。
ですがコンパイルされたアセンブラリストを見ると、どうもひとつの関数のために何度かcall命令が生成されているので、C言語としては3層でもアセンブラ上では8層を超えている可能性がありそうです。。。正確に何層かは簡単には数えられなさそうです。
ちなみにMPLAB-IDEでは、C言語としてのスタック数はメニューからView-HardwareStackでみれたのですが、アセンブラのスタック数を見られるはずのView-CallStackのとこはなぜか灰色でクリックできません。なので明日かあさってにはなんとか手動で数えてみます。
これで数えてみてもし9層目をcallしていたらbug_bugさんには非常に感謝しなければいけないですね。。。ありがとうございます。調べるので少々お待ちください。
あと参考程度なのですが、0x0000番地に急に飛んでしまうという問題の箇所が、アセンブラリスト上では実は
2000 (CALL 0)
となっていることがわかりました。そのまますぎて笑えるのですが、「call 0」とかいうこんな明らかに間違っているコンパイルをするというのは、無理に9層目をcallしようとして起きたという理解でいいんでしょうか。?
このようなことを何か経験された方がいらっしゃったら引き続き教えてください>< もう表題と関係ないのでスタック数のことが正式に解決しましたら質問し直します。
bug_bugさんありがとうございました。
No.4
- 回答日時:
call 0 がコンパイラによって生成されるとは考えにくいので、MPLAB上の逆アセンブルリストを参照しているのであればconst値などのデータセクションにPCが飛んでしまっているのかもしれません。
逆アセンブルリストでプログラムROM上のアドレスさえ確認できれば、.mapファイルを参照し何が格納されているのか確認できますね。
仕様が不明なのでちょっと解答は難しいですが、割り込み発生時や、割り込み処理での要因別ブランチの関数コールなどでもPCスタックは行われるので注意が必要です。
とりあえず思いつくトコだけ・・・。
No.2
- 回答日時:
C18やC30は、PIC16Fでは使えません。
他のコンパイラだと「SDCC」とか「CCS C/PCM」とか「FED-C」とかでしょうか。
c2cと言うのもあるみたいですが、Linux版のみ無料のようです。
http://ww2.tiki.ne.jp/~maro/old/PIC/C2C/
と思ったらc2cは入手不能になってました。
私は16F84しか書いたことないのでPCLATH対応については未知ですが、上記のc2cのアセンブルリストを見る限りは他のコンパイラでも対応している可能性が有ります。
No.1
- 回答日時:
PICCには詳しくないんですが、とりあえずPC系の誤動作を疑うならアセンブルリストを取ってコードを確認してみてはどうでしょうか。
PICC-LITEと同じなら-ASMLISTで取れると思います。
実際上のメモリの配置アドレスは、リンカでマップファイルを作成する必要があります。調べてみてください。
なんにしても無理やりPCLATHを変更するのはC言語として矛盾が生まれるで無理があると思います。
ありがとうございます。
アセンブルリストというものを知りませんでした。。。
いい忘れてましたがPICCはMPLABIDEと統合して使っていましたので、探してみたところMPLABのViewメニューのDisassemblyListingで見れました。
これでどの番地にどの関数が書いてあるか一目でわかりました、ありがとうございます。
で早速問題を調べてみましたが、シミュレータで見てみてもやはりreturn命令などの後にいきなり0x0003番地に戻されたりしているのでPC関連の問題な気がします。しかしどう対策するのかわかりません。。。
マップファイルやらでメモリの配置を触ったところで解決できる自信がありませんが一応今調べてみています。一応それぞれの関数はページをまたがない様に配置してくれていました。
あきらめてC18やC30に移行してみたくなっていますがこれらはPCの問題はないのでしょうか。。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
unsigned long long 型のフォー...
-
ソフトの開発言語を調べる方法
-
変数の内容がコロコロ変わる、...
-
組み込みソフト。ROM領域にデータ
-
VB6のコンパイラ
-
「javac」は、何と読むのでしょ...
-
24bit サイズの変数
-
for文内での変数定義
-
cc と gcc の違い
-
COBOLのALPHABET...
-
PICマイコンのプログラムカウン...
-
HDLについて
-
自作ゲームをPSPで出来ますか?
-
LSI C-86を利用した時の乱数の...
-
BorlandC++
-
python エラー
-
<unistd.h>をVisualStudioでつ...
-
エクセルのエラーメッセージ「4...
-
アプリケーションのDLLファイル...
-
デバッガでステップ実行してい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
unsigned long long 型のフォー...
-
ソフトの開発言語を調べる方法
-
プログラマーに向いている人の...
-
printfなど、標準関数のソース...
-
cc と gcc の違い
-
組み込みソフト。ROM領域にデータ
-
C++Builder → Visual C++ 移植...
-
COBOLの論理演算子について質問...
-
COBOLのALPHABET...
-
VC++の/Zm オプションについて
-
リリースモードとデバッグモー...
-
C++でデスクトップGUIアプリ開...
-
PICでのI2C通信でのマスタ、ス...
-
C言語の規格
-
パーサとコンパイラの違いって?
-
void型のポインタで構造体の参照
-
VisualC++6.0でのProfessionalE...
-
OpenMAXというものについて、簡...
-
#pragmaとは
-
<conio.h>?
おすすめ情報