コンフィグレーションビット設定プログラムでPIC12F683が動作しなくなる原因とは?

このQ&Aのポイント
  • PIC12F683でコンフィグレーションビット設定プログラムを入れると、動作できなくなる。
  • 現在PIC12F683マイコンをC言語でCCSコンパイラを使ってプログラムをやっています。数個マイコンにコンパイラしたプログラムの実行ファイルを書き込んでいくとき、書き込み機にコンフィグレーションビット設定をいちいち撃ち込んでいくのが面倒くさくて、プログラム上にコンフィグレーションビット設定のプログラムというのがあったので、作業を省略してくれるとのことでやってみたのですが、コンパイルして実行ファイルを書き込むとマイコンが全く動かなくなってしまいました。
  • こんプログラムを入れてみたのですが、なぜ、マイコンが全く動かなくなってしまうのでしょうか? 一応main関数の永久ループに行く前に、デバッグとしてprintf文をいれてUART出力で0xFFという文字を出力させているのですが、このコンフィグレーションビット設定プログラムの実行ファイルではこのprintfも出力されていません。
回答を見る
  • ベストアンサー

PIC12F683でコンフィグレーションビット設定プログラムを入れると、動作できなくなる。

現在PIC12F683マイコンをC言語でCCSコンパイラを使ってプログラムをやっています。 数個マイコンにコンパイラしたプログラムの実行ファイルを書き込んでいくとき、書き込み機にコンフィグレーションビット設定をいちいち撃ち込んでいくのが面倒くさくて、ぐぐっていたら、プログラム上にコンフィグレーションビット設定のプログラムというのがあったので、作業を省略してくれるとのことでやってみたのですが、コンパイルして実行ファイルを書き込むとマイコンが全く動かなくなってしまいました。 /* configuration bits */ #fuses INTRC_IO // _INTRC_IO #fuses WDT // WDT_ON #fuses PUT // Power_UP_TIMER_ON #fuses NOMCLR // MCLR_NO #fuses NOPROTECT // PROTECT_NO #fuses NOCPD // CPD_OFF #fuses BROWNOUT // BROUWOUT_ON #fuses NOIESO // IESO_NO #fuses FCMEN // Monitor clock fail-safe_ON こんプログラムを入れてみたのですが、なぜ、マイコンが全く動かなくなってしまうのでしょうか? 一応main関数の永久ループに行く前に、デバッグとしてprintf文をいれてUART出力で0xFFという文字を出力させているのですが、このコンフィグレーションビット設定プログラムの実行ファイルではこのprintfも出力されていません。

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

  • ベストアンサー
  • hashend
  • ベストアンサー率92% (12/13)
回答No.4

ここまで来て言うのもなんですが、私の知識では想像できない部分で不都合があるのかもしれません。ちなみに、#fusesを使わずにライターで直接コンフィギュレーションビットを書き換えた場合でも現在使用しているICで動作確認できますでしょうか? もしHEXファイルを確認するのであれば、最後の方の行にコンフィギュレーションビットが書かれています。下位バイト上位バイトの順に書かれていると思います。しかし、ICに正確にコンフィギュレーションビットが書かれているということは原因はコンフィギュレーションビットではなくプログラムの方にあると思うのですが

その他の回答 (3)

  • hashend
  • ベストアンサー率92% (12/13)
回答No.3

状況をすこし確認したいのですが、 (1)書き込み用のファイルにはフュースビットの情報が書き込まれている。 (2)ICへの書き込み器でICそのもののヒューズビットを呼び出しても正しい情報である。 (3)テスト用のプログラムでもWDTタイマのクリアを行なっている。 (1)が正しければ、#fusesの表記は正しいので、問題は無いでしょう。これは書き込みソフトで確認出来ているようですので、書き方そのものは成功していると言えます。動かないのは他に原因があるようです。 (2)が正しければ物理的に壊れている可能性とソフトウェアの問題の2つが上げられます。 (3)が間違いであれば、WDTをクリアするプログラムを追加する必要があります。

techhouse
質問者

お礼

回答頂きありがとうございます。 >2)ICへの書き込み器でICそのもののヒューズビットを呼び出しても正しい情報である。 一応、マイコンの中に書き込んだ#fuses文を含んだデータをMPLAB ICD2を使ってReadしてみて、コンフィギュレーションビットの設定を確認していたのですが、#fusesの内容と同じということを確認しました。 それで、(3) >(3)が間違いであれば、WDTをクリアするプログラムを追加する必要があります。 現在の#fuses文を #fuses INTRC_IO, NOWDT, PUT, NOMCLR, NOPROTECT, NOCPD, BROWNOUT, NOIESO, FCMEN このように宣言してNOWDTでウォッチドックを無効にして動作させてみたのですが、これでもマイコンは全く動作しない状態です。 もしかしたら#fuses文を含んだ実行ファイルと含まない実行ファイルをバイナリ比較で何かわかるかも知れませんね。もしかしたら・・・

  • hashend
  • ベストアンサー率92% (12/13)
回答No.2

フューズビットの呼び出しで、正確に書き換えられているかはチェックしましたか? また、今更ですが、 >#fuses WDT // WDT_ON になっているのですが、ウォッチドックタイマを使用しているのですか?

techhouse
質問者

お礼

回答頂きありがとうございます。 フューズビットの設定をプログラムでしてコンパイル後、作成された実行ファイルを書き込み機のユーティリティソフトで開いた時に、フューズビットの設定の項目で、自分が行った設定にちゃんと表示されるかで、確認はしております。ソフトはSPWriterを使用しています。 今回のプログラムではウォッチドックタイマを使用しています。

  • hashend
  • ベストアンサー率92% (12/13)
回答No.1

CCSのコンパイラを使った事はありませんので憶測で申し訳ないですが、#fuses INTRC_IO,WDT,PUT.... のように改行せずに一行で書かなければならないような気がします。 推測で本当に申し訳ないのですが、各オプションは論理和または論理積で計算されるため、最後に指定した「#fuses FCMEN」だけが適用されている気がします。また純正のプログラマーを使用している場合はフューズビットの呼び出しが可能だと思いますので、マイコンに書き込まれている内容を確認されるとよいと思います。

techhouse
質問者

お礼

回答頂きありがとうございました。 #fuses INTRC_IO, WDT, PUT, NOMCLR, NOPROTECT, NOCPD, BROWNOUT, NOIESO, FCMEN このような感じで一行にフューズビットの設定を行ってみたのですが、結果main関数に動作が到達していないようで、動きませんでした。 シミュレーションではちゃんとプログラムは動いているのですが、実際の動作では違うようです。

関連するQ&A

  • PIC16F88のエラーについて教えてください

    PICを勉強中ですが、16F88用にコーディングしたソースをMPLAB IDE v8.66を使用してアッセンブルすると必ずコンフィグの部分で Error[108]の Illegal character (,) になり原因がわかりません。何方かご教授お願いします。ちなみにコンフィグは下記(1)(2)(3)で試しましたがどれも同じエラーになります。 ンフィグの部分でにコーディングしたソースを (1)__CONFIG _CONFIG1, _WDT_OFF & _BOREN_ON & _PWRTE_ON & _INTRC_IO & _CCP1_RB3 & _LVP_OFF (2)__CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_IO (3)__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC

  • 16F873Aのコンフィギュレーションビット

    16F873Aのコンフィギュレーションビット がいまいちわかりません。。。 普段は16F84を使っていたのですが、同じようにコンフィギュをかいていてもどうも動きません。 Bポートをすべて転倒させたいのですが下記のようなプログラムでは動きませんでした、どうかご教授ください。 #include<16F873A.h> #fuses RC,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP #use delay(clock=1000) main(){ set_tris_a(0x00); set_tris_b(0x00); set_tris_c(0x00); for(;;){ output_b(0xff); } }

  • PICKit3でのコンフィグレーションビット操作をするときに出てくるエラーメッセージの内容。

    現在、PIC12F683という8端子の小さなマイコンを使ったプログラミングを行っていて、プログラムをMPLABとCCSコンパイラを使って作成、コンパイルしてHEX実行ファイルを作成して、それをPICKit3という書き込み器を使って書き込みを行っています。 PICKit3 http://www.youtube.com/watch?gl=JP&hl=ja&v=FBbcIV1-bZw PIC12F683のコンフィグレーションビットで、初期値は外部オシレータを使う設定にしているので、それを内部オシレータに切り替えたり、リセット端子のMCLR端子はI/Oポートで使いたいので、その設定をするためにコンフィグレーションビットの設定をするときがあるのですが、そのときに必ず ”Settings in this configuration Bits view will override settings in code until you rebuild your project” このようなメッセージが出てきます。 このエラーメッセージはどのような意味なのでしょうか? ご存じの方いらっしゃいましたらご教授よろしくお願いいたします。

  • PICが動作しません。

    以前に加速度センサーとI2C通信のことで質問したものです。 基礎から勉強しているのですが、一番初めで躓きました。 PICが動作しません。 MPLAB IDE v8.88 CコンパイラはXC8です。 後閑さんの本「PICマイコンの基礎」で勉強しています。 PICが動作しません。 MPLAB IDE v8.88 CコンパイラはXC8です。 PICは16F1936です。 ライターはPICkit3です。 【現象】 本のプログラムで書き込みをしても PICが動作しません。 テスターで出力設定したピンの電圧を測定しても、出力がでません(0Vです) 【調べたこと】 1・ライターはエラーでは無さそうです。 「Programming/Verify complete」 と表示されます。 しかし、PICkit3の3番ピンをブレッドボードにさすと、 「Target Device ID (00000000) does not match expected Device ID (00002360).」 と出ます。 このままでは、書き込みも出来ないので、 「READ」を押してからだと、上記のIDエラーが解消され、書き込みができますが、動きません。 条件はわかりませんが、 「he following memory regions failed to program correctly: Program Memory Address: 00000000 Expected Value: 00003180 Received Value: 00000000」 というエラーもたまにでます。 2.PICは2つあるので、交換しても同じです。 【考察】 1.プログラムが間違っている (1)本のプログラムを何度も見直し+サポートページからコピペでしてます。 ただ、コンフィグレーション設定の「BORV19」と打つとコンパイルエラーが出ますので、入れていません。 →関係あるのでしょうか?これは「どの電圧まで下がったらリセットするか」なのと、デフォルトでも1.9なので関係ないと思います が・・・ 2.XC8のコンパイラが悪い? ヘッダファイルは「XC.h」と「htc.h」両方で試しました。 何か相性等があるのでしょうか。 【プログラム】 25ピンから電圧を出力するだけのプログラムに変更し確認しましたが動作しませんでした。 #include <xc.h> __CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_ON & CLKOUTEN_ON & IESO_OFF & FCMEN_OFF); __CONFIG(WRT_OFF & PLLEN_OFF & STVREN_OFF & LVP_OFF); #define _XTAL_FREQ 8000000 // クロック周波数設定 void main(void) { OSCCON = 0x70; // 8MHz INTOSC ANSELB = 0; // PORTBをデジタルに設定 TRISB = 0; // PORTBすべて出力モード /** メインループ 永久ループ **/ while(1) { RB5=1; } } 私なりに色々とネットで調べても解決しませんでした。 長文で、大変失礼ですが、ご回答下さると幸いです。

  • PIC初心者です。 PIC16F88のLED制御で以下のプログラムを実

    PIC初心者です。 PIC16F88のLED制御で以下のプログラムを実行すると点滅を繰り返します。 意図としては1度だけ光って消えてほしいのですが… CONFIG部分がおかしいのでしょうか? 環境として、PCはVista、MPLABとPICkit2を使用しています お分かりになる方、お願いいたします。 以下ソースです LIST P=PIC16F88 INCLUDE "P16F88.INC" __CONFIG _CONFIG1, _INTRC_IO & _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_ON BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 BCF STATUS,0 CLRF PORTB MAIN BSF PORTB,0 NOP NOP NOP (以下、NOPが100個ほど) NOP BCF PORTB,0 END

  • PIC 16F877について

    現在は16F84Aをアセンブラでプログラムしていますが、LEDを繋いでON,OFFさせたり、入力待ちでプログラムを切り替えたりということが出来る程度です。 16F877なんかにも最近興味が出てきたのですが、素人なので違いが良く分かりません(でかくてピンの数が多い・・という位)。 16F84Aなんかは13本のIOポートがあって8ビット分つまり8つのピンを同時に動作可能ですが877はもっとたくさんのピンを同時に動作可能なのですか? あと、プログラムに使う命令は16F84Aとは同じなのでしょうか? ピンの名称が違うのでそれは変更しないといけないと思いますが。 プログラムに関して基本的にあまり違いがないのなら一度877にも挑戦したいと思っていますので詳しく教えてください。 ただし、本当にど素人なので分かりやすく教えてください。

  • PICのプログラムカウンタについて

    プログラムカウンタでポートAに4bitの2進数を入力して、変換された2進数のデータをポートBに出力させることはできたのですが、 ポートCにも違うデータを同時に出力させたいのですが、どういった命令文を作ったらいいでしょうか? 例えば、ポートAが「HLHL」の入力の時にポートBでは「HLLH」、ポートCでは「LLHL」を出力させる方法です。 言語はアセンブラ、マイコンはPIC16F886です。 よろしくお願いします。

  • PICマイコンのCLRWDT動作について

    PIC16F84Aの勉強中です。 CLRWDTの動作に不明点があり、どなたか教えて下さい。 <質問1> 1.WDTに割り当てた分周比がCLRWDTでクリアされません。なぜでしょうか ■概略 WDT_ON、ポストスケーラをWDTに割り当て、スケール値は110(1:64)で用いています。 CLRWDTの作用は、データシートやその他の文献を見ると (1)WDTのクリア(カウンターが0になる?←私の考えです) (2)ポストスケーラのクリア(スケール設定値が000になる?←私の考えです) (3)TO―>1 (4)PD―>1 の4つが記載されておりますが、(2)だけが確認できません。 クリアされるとすれば、CLRWDT文の次には必ず「スケール値再設定」の処理が必要となるはずですが、処置しなくても試作機は無事動いております。 MPLAB(Ver6.50)のシミュレーション(WATCHでOPTIONレジスタ値を観察)でも値は動きません。もちろんCLRWDT文を外せば試作機でもシミュレーションでもリセットがかかるので、WDTは確実にONしています。 CLRWDT文の使い方には何か条件があるのでしょうか。 <質問2> 2.SLEEP in時にもWDTがクリアされるはずですが、上記(2)も実行されるのでしょうか。 ■概略 WDTでWAKEUPさせるのですが、その間隔が約1秒でして、どうも実行されていない様子なのです。 <質問3> 3.スケーラ値のデフォルトは111なのでしょうか。 ■概略 MPLABのシミュレーション(WATCHでOPTIONレジスタ値を観察)では、最初はいつも111からスタートしているのでそう思いました。(設定文通過後はきちんと設定値に変化します) もしデフォルト(=クリア値?)が111ならば、プログラムでわざわざ110にしなくても111でも問題ないので設定無しにしようかなと。更に、CLRWDT文の次の「スケール値再設定」処置が省略できるのでは・・・と考えております。(もともと必要ない\(◎o◎)/?) 以上、よろしくお願い致します。

  • PIC12F675、HC-SR04のプログラム

    PIC12F675にプログラムをMPLABX IPEで書き込んで、超音波センサ HC-SR04の距離が5cm以下の時にブザーが鳴る(出力が5Vになる)ようにしたいです。 以下のプログラムで出力は、距離に関わらず5Vか0Vで一定になっています。 プログラムに間違いがあれば、教えていただけないでしょうか。 #include <xc.h> #include <stdio.h> //12F675 #include <stdlib.h> #pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-Up Timer Enable bit (PWRT enabled) #pragma config MCLRE = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD) #pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled) #pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled) #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled) #define _XTAL_FREQ 32000000 #define TX_UART_SIZE 3 #define SONIC_TRIG GPIO5 #define SONIC_ECHO GPIO4 #define SONIC_TEMP GPIO2 #define SONIC_BUZZ GPIO1 #define IO_OFF 0 #define IO_ON 1 #define TIME_OFF -1 #define TIME_UP 0 #define TIME_START_H 0xD8 #define TIME_START_L 0xF0 #define TIME_LED_CNT_MAX 5 #define TIME_LED_CNT2_MAX 15 unsigned char cnt10ms; char TimerLed1; char TimerLed2; int main(int argc, char** argv) { long echo_time; long dist; OSCCAL = 0b00110000 ; // 内部クロック8MHz ANSEL = 0x00 ; // AN未使用、デジタルI/Oに割当てる CMCON = 0x07; // コンパレータ未使用 TRISIO = 0b00011100 ; // RA2,3,4を入力にし、他は出力に割当てる GPIO = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) T1CON = 0b01110000 ; // ゲート有効、Hiでカウント、単一パルス、T1Gピン TMR1ON = 1; // タイマー1開始 while(1) { // タイマ1のカウンタ準備 TMR1 = 0; // カウンタの初期化TMR1 = 0; // トリガ送信 SONIC_TRIG = IO_ON; __delay_us( 10 ); SONIC_TRIG = IO_OFF; // エコー信号のON待ち while( SONIC_ECHO == IO_OFF ) { } // エコー信号のOFF待ち while( SONIC_ECHO == IO_ON ) { } // 超音波の往復時間を取得 echo_time = TMR1; // 往復時間から片道の時間にする echo_time /= 2; // パルス時間から距離(cm)に変更 dist = echo_time * 34 / 1000; if( dist <= 5 ) //距離5cm以下でブザー出力 { (SONIC_BUZZ = 1); } else { (SONIC_BUZZ = 0); } __delay_ms( 1000 ); } return (EXIT_SUCCESS); }

  • H8 3664Fのプログラム

    タクトスイッチのチャタリングを回避し、奇数回めのONで LEDの交互点灯を(タイマを使って) やろうとしていますが、なかなかうまくいきません。 入門者でお恥ずかしいですが、下記コードの誤りをご指摘頂けませんでしょうか? 宜しくお願い致します。 以下、コード。 #include <3664.h> //プロトタイプ宣言 void main(void); int SW_Read(void); // 入力SWの状態読み込み 関数 void wait(int); // nミリ秒待つウエイト 関数 void wait1ms(void); // 1ミリ秒待つウエイト 関数 void IOinit(void); // I/O の初期化 関数 void main(void) { if (SW_Read()==1) { IO.PDR8.BIT.B0 = 1; // ポート8のビット0を出力ON IO.PDR8.BIT.B1 = 0; // ポート8のビット1を出力OFF DI; // 割り込み禁止 TA.TMA.BYTE = 0x0A; // タイマーA、低速発信・0.25sec設定(タイマーのカウント開始) IRR1.BIT.IRRTA = 0; // タイマーA 検知フラグをゼロクリア IENR1.BIT.IENTA =1; // 割り込み許可 EI; // 割り込み許可 } else { } while(1) { } } /////////////////// I/Oの初期化 void IOinit(void) { IO.PCR8 = 0x03; // ポートコントロールレジスタ: ポート8のビット0・1を出力に設定 // その他のビットは入力に設定 IO.PDR8.BIT.B0 = 0; // ポート8のビット0を出力OFF IO.PDR8.BIT.B1 = 0; // ポート8のビット1を出力OFF IO.PCR1 = 0x00; // ポートコントロールレジスタ: ポート1を全ビット0とし、入力に設定 } /////////////////// タイマーA関数 void int_timera (void) // タイマーA関数 { IO.PDR8.BIT.B0 = ~IO.PDR8.BIT.B0; // ポート8のビット0を反転して出力(赤)LED用 IO.PDR8.BIT.B1 = ~IO.PDR8.BIT.B1; // ポート8のビット1を反転して出力(緑)LED用 IRR1.BIT.IRRTA = 0; // タイマーA検知フラグをゼロクリア } /////////////////// スイッチの状態読み込み int SW_Read(void) { int sw1; //スイッチ状態読み込み1回目 int sw2; //スイッチ状態読み込み2回目 int val; //スイッチの状態判定値の入力値 int memval; //入力信号の全回の値 int numcnt; //奇数偶数判定ループ用カウンタ while(1) //モニタリング { sw1 = IO.PDR1.BIT.B7; // スイッチの状態読み込み1回目 wait(10); // 10mS待つ sw2 = IO.PDR1.BIT.B7; // スイッチの状態読み込み2回目 memval=val; //現行のスイッチ状態判定値をメモリに入れ替える if(sw1==1 & sw2==1) // スイッチ読み込み1回目と2回目共にONだったら { //スイッチ状態判定を<押した>と見なして、 val=1; } else { val=0; } if(memval==0 & val==1) //パルスの前後状態を比較し、新規に立ち上がりONであれば、 { numcnt=++numcnt; if(numcnt%2!=0) //ループカウンタが奇数だったら { return(1); // 1を返す } else { } } else { } } } //////////////////// nミリ秒待つウェイト関数 void wait(int time) { int i; // ループカウンタ for(i = 0 ; i < time ; i++) // time回数分ループ wait1ms(); // 1ミリ秒のウェイト関数を呼び出す } //////////////////// 1ミリ秒待つウェイト関数 void wait1ms(void) { int i; // ループカウンタ for(i = 0 ; i < 2662 ; i++); // 1ミリ秒の間ループする } 以上、宜しくお願い申し上げます。

専門家に質問してみよう