PICマイコン、水晶発振子の異常

このQ&Aのポイント
  • PICマイコンと水晶発振子に関する質問です。
  • 水晶発振子が異常発信し、リセット後に正常に発振することが確認されています。
  • コンデンサや回路の状態を確認しましたが、問題は見つかりませんでした。マイコンの故障の可能性についても考えたいと思っています。
回答を見る
  • ベストアンサー

PICマイコン、水晶発振子の異常

カテ違いかも知れませんがマイコンおよび電子回路についての質問です。 水晶発振子が異常発信しMCLRによるリセット後、正常に発振します。 マイコン:PIC16F887 水晶発振子:VT-200-F コンフィグは以下のように設定 __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _LP_OSC __CONFIG _CONFIG2, _WRT_OFF & _BOR21V OPTION_REGは以下のように設定 movlw B'01011000' ; 7.ポートBのプルアップ:無効 ; 6.ポートBの割り込みエッジ ; 5.TMR0のクロック源:内部命令サイクル ; 4.TMR0のカウントするクロックエッジ ; 3.プリスケーラ:WDTに割り当て ; 2.1.0.プリスケーラ初期値(未使用) movwf OPTION_REG 13ピン(CLKIN)と14ピン(CLKOUT)に水晶発振子を接続。 それぞれに15pFのコンデンサを接続。 40ピン(RB7)にLEDを接続(TMR0で割込みが発生したタイミングで点灯消灯を繰り返します。) 1ピンはMCLRとして利用 で、計算上の割込みタイミング(プリスケーラなし) (1/(32.768/4))*256=31.25ms なのですが40ピンのHI、LOWタイミングをオシロで観測したところ 実測値は以下のとおりでした。 電源接続直後:256.7us 1ピンでのリセット後:31.37ms(ほぼ計算通り) 電源接続直後は必ず上記のようになり1ピンでリセットすると正常に発振し始めます。 コンデンサの容量が合っていないのかと思いいくつか試してみました結果は同じでした。 水晶発振子も変えてみましたがやはり結果は同じでした。 コンデンサの足も切って短くしてみましたがこれも結果は変わりませんでした。(この程度の距離は関係ない?) 回路はブレットボード上です。 マイコンが壊れているのでしょうか? 今までもっぱらセラロックや水晶発振器を使っていて今回初めて水晶発振子を使ってみてこのような事象に遭遇しました。 どのようにしたら正常発振するか詳しい方、ご教示いただけたら幸いです。

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

  • ベストアンサー
  • koujikuu
  • ベストアンサー率43% (428/992)
回答No.1

ブレッドボードの接触不良のような気がしますが、プリント基板で組んでみては? 参考ページがありましたので http://www.kds.info/html/products/technical_guide/circuit_investigation/index.htm http://www.sii.co.jp/components/quartz/productDetailJP.jsp?recordID=1300 http://120.blog.shinobi.jp/Page/28/

chibichan_dayo
質問者

お礼

お礼が遅くなりすみません。 その後色々調べた結果CONFIGのFCMENをOFFにする事で解消しました。 原因としては上記設定がONになっていたため電源投入直後の水晶安定発振前に内部発振が始まってしまっていたようです。 ご回答ありがとうございました。

その他の回答 (1)

  • kngj1740
  • ベストアンサー率18% (197/1052)
回答No.2

power on reset回路が拙いのでは。

chibichan_dayo
質問者

お礼

お礼が遅くなりすみません。 その後色々調べた結果CONFIGのFCMENをOFFにする事で解消しました。 原因としては上記設定がONになっていたため電源投入直後の水晶安定発振前に内部発振が始まってしまっていたようです。 ご回答ありがとうございました。

関連するQ&A

  • PIC16F タイマ0使い方

    久しぶりにPICを引っ張り出して触っていたのですが、タイマ割込みの部分がうまくできていないようで、LED(led_green)を1秒で点滅させたいのですが2秒ぐらいの中途半端な点滅をしてしまいます。 内部クロックを4MHzに設定しているので、これをプリスケーラで8分周しTMR0の値を130に設定し、1msごとに割込みが発生する算段なのですが、どこか間違えてますでしょうか? マイコンは PIC16F886 を使用しています。 #include<pic.h> #include<stdio.h> #include <stdlib.h> #include <xc.h> #define _XTAL_FREQ 4000000 // 内部クロック 4MHz // CONFIG1 #pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD) #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) #pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled) #pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled) #pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming) // CONFIG2 #pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V) #pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off) #define TMR_set 130 // TMR0初期値 #define led_green RB0 #define led_white RC3 volatile unsigned int count = 0; volatile unsigned int cnt = 0; // タイマー割込みの処理 void __interrupt() int_f (void){ // 割り込みハンドラ if(T0IF == 1){ // 1ms count++; cnt++; TMR0=TMR_set; T0IF = 0; // 割り込みフラグをクリア (オーバーフローフラグ) if(count>=1000){ // 1s count=0; led_green = ~led_green; } } } void init(){ OSCCON = 0b01100000; ANSEL = 0b00000000; ANSELH = 0b00000000; TRISA = 0b00000000; TRISB = 0b00000000; TRISC = 0b00000000; PORTA = 0; PORTB = 0; PORTC = 0; GIE = 1; // すべての割り込みを許可 (0:禁止, 1:許可) T0IE = 0; // タイマー割り込みを禁止 (0:禁止, 1:許可) T0CS = 0; // TIMAR0モジュールをタイマーとして使用 (0:通常のタイマーとして使用, 1:T0CK端子に入ってきた入力のカウンタ) PSA = 0; // プリスケーラをTIMER0モジュール用にセット OPTION_REG = 0x02; // プリスケーラ 1:8 TMR0 = TMR_set; T0IE = 1; // タイマー割り込みを許可 (0:禁止, 1:許可) T0IF = 0; // 割り込みフラグをクリア (オーバーフローフラグ) } void main(void){ init(); led_white = 1; while(1){ } return; }

  • picのタイマ1発振開始時間に関して

    マイコン Pic16F1939を使用して回路を組み、タイマ1を外部に取り付けた水晶で 動作させています(pic自体は内部オシレータで8MHzで動作させ、Timer1は正確な 1秒を取得するために使用しています) 使用している水晶は32768Hzの時計用のものです。 タイマ1が0.5秒ごとにオーバーフローするように設定し、割込みの関数で液晶の 点滅処理をおこなっています。 水晶の両端はそれぞれコンデンサが添付画像のような接続でつながっています。 また、関連部分のプログラムの抜き出しは以下のようになっています。 // 割込み処理 static void interrupt isr(void) { if (PIR1bits.TMR1IF) { // 32Khz水晶 割込み Int_Timer1(); } ~ 省略 ~ } // タイマー1割り込み(32khz水晶) : 0.5秒ごと void Int_Timer1(void) { PIR1bits.TMR1IF = 0; // 次の割り込み許可のためクリア // 0.5秒で次の割り込みが発生するように設定 TMR1H = 0b11000000; TMR1L = 0b00000000;     ~ 点滅処理 ~     ~省略~ return; } そして以下の初期設定用関数 InitTimer1()と InitInterrupt()を main()の始めに呼んでいます。 // Timer1 setting 32kHz , external crystal void InitTimer1(void) { T1CONbits.TMR1CS1 = 1; T1CONbits.TMR1CS0 = 0; T1CONbits.T1CKPS1 = 0; T1CONbits.T1CKPS0 = 0; T1CONbits.nT1SYNC = 1; T1CONbits.T1OSCEN = 1; T1CONbits.TMR1ON = 1; } // 割込み初期化 void InitInterrupt(void) { PIE1bits.TMR1IE=1; // enable timer 1 interrupt INTCONbits.PEIE=1; INTCONbits.GIE=1; } 質問なのですが、実際に液晶が点滅するまでに2秒ほどかかっています。 どこかのホームページでタイマ1の水晶の発振が安定するまでに 数msecかかるというような情報が書いてあったので、ずいぶん 遅いなと感じ2つのコンデンサの容量を10pF~200pFくらいのあいだで色々 変更して試しているのですが、2秒より早く点滅開始となることはありませんでした。 これは、上記プログラムの問題なのでしょうか? それとも2秒ほどかかって発振するのは仕方ない(Picの仕様)なのでしょうか? どなたかご存知の方いらっしゃいましたらご回答をお待ちしております。

  • 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

  • 水晶発振子の学習

    現在、水晶振動子について勉強しています。 最終的には実験を行い、レポートをまとめて提出と言った形なのですが、提示されている内容が ディジタル発振回路の基本回路とその周辺定数の設定方法についての学習。実際に発振回路をバラック製作し、実験と評価をし電気特性や問題点を学習する。 と言った感じです。 今のところ書物やネットを利用し、水晶振動子についての基礎知識を学習して、時計やマイコン等のタイミングを測るところに使われると言う事は分かってきました。 しかし、実験をする上で水晶発振子のどの特性を基に実験したり、またその特性を調べる為の回路のイメージが掴めないでいます。 例えば、トランジスタで言えば増幅率のhFE、フォトカプラで言う直流伝達比のCTRなどその素子の特徴とも言える部分?見たいなのを教えていただければと思います。 役立ちそうな書物やサイト、水晶振動子ならこのパラメータ、このような実験をしてみては?と言った内容で回答を頂けると幸いです。 一度別のカテゴリーで質問させて頂いたので、目を通してる方もいらっしゃるかもしれませんが、頂いた回答で「カテゴリーが違うのでは?」と言うのがありましたのでカテゴリーを変更し再度質問させていただきます。 ご回答どうぞよろしくお願いします。

  • 水晶振動子の負荷容量について

     水晶振動子のスペックに負荷容量があります。(例:8pF, 10pF, 12pFなど)  マイコンの発信源と利用する場合,発信子接続ピン(入出力)に接続し,さらに,両方の端子をセラミックコンデンサでGNDに接続します。  さて,水晶振動子の負荷容量からみた場合,マイコン,外付けコンデンサをどのようにマッチングさせればよいのでしょうか?計算式としてはどうなりますか?  どうぞ,よろしくお願いします。

  • PIC16F88の使い方?に関する質問(アセンブラ)

    現在PICの16F88に書きこむプログラムをアセンブラで書いてます。4番ピンのMCLRをRA5として使いたいのですが、MPLABのWATCHの機能を使って、ポートAの動きを見てみると、ポートAが出力になっているはずなのに、何をしてもポートAの0~4がHにならず、ポートAのRA5はBSF,BCFの命令が利きません。コンフィグの設定が怪しいと思うのですが、自分には理由が分からないので、誰か教えてください。お願いします。(下に書いたプログラムはテスト用に書いたプログラムなので特に目的はありません) ;外部発振,セラロック20MHz使用 LIST P=PIC16F88 INCLUDE P16F88.INC __CONFIG _CONFIG1, _CP_OFF & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF BSF STATUS,RP0 MOVLW B'000000' MOVWF TRISA MOVLW B'00000000' MOVWF TRISB BCF STATUS,RP0 MAIN CLRF PORTA MOVLW B'11111111' MOVWF PORTA MOVWF PORTB BSF PORTA,0 BCF PORTA,0 BSF PORTA,1 BCF PORTA,1 BSF PORTA,2 BCF PORTA,2 BSF PORTA,3 BCF PORTA,3 BSF PORTA,4 BCF PORTA,4 BSF PORTA,5 BCF PORTA,5 GOTO MAIN END

  • PIC タイマー0の使い方

    PIC16F886を触り始めたのですが、タイマー割り込みで苦戦しています。 タイマー割り込みを使ったLEDの点滅の間隔が、自分の思った時間にならないのです。 下に今のプログラムを載せておきます。 私の今の考え方はこうです。 ・内部クロックは4MHzに設定してある ・TMR0のカウントはクロックの1/4らしい→1MHzなので周期は1μsec ・プリスケーラは1:128に設定→128μsecでTMR0がカウントアップ ・TMR0の初期値を61に設定→195回のカウントアップでT0IF=1 ・128μsec*195μsec=2496μsec≒0.025msec←タイマー割り込み ・40回カウントすると1秒 と、1秒ごとにLEDのON,OFFが切り替わるはずだと考えているのですが、書き込んで計測したところ、約0.8秒でon,offを繰り返しています。 私の考え方やプログラムに間違いがあるのでしょうか? もしくはPICがハード的に壊れているのでしょうか?(picに5Vをかけても動かず、mainが実行中に点灯するLED(この時点では点いていない)の端子の両端を指で触ると何故か動き出します。) 以下プログラムです。(注釈などは省いたので見難いかもしれません) #include <stdio.h> #include <stdlib.h> #include <xc.h> #include <pic.h> #pragma config FOSC = INTRC_NOCLKOUT #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config MCLRE = OFF #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = ON #pragma config IESO = OFF #pragma config FCMEN = OFF #pragma config LVP = ON void interrupt tc_int(void); volatile unsigned int cnt = 0; volatile unsigned int cnt1 = 0; #define sw RB0 #define led RA0 #define led2 RA1 #define led3 RA2 #define _XTAL_FREQ 4000000 void init(void) //初期設定 { OSCCON=0b01101000; // 内部クロック設定 4MHz TRISA=0b00000000; TRISB=0b00000000; TRISC=0b00000000; ANSEL=0x00; /* 割り込み初期設定 */ GIE = 1; // すべての割り込みを許可 T0IE = 0; // タイマー割り込みを禁止 T0CS = 0; // TIMAR0モジュールをタイマーとして使用 PSA = 0; // プリスケーラをTIMER0モジュール用にセット OPTION_REG |= 0x06; // CPUクロックを128分周 TMR0 = 61; // カウンタ値をリセット T0IE = 1; // タイマー割り込みを許可 T0IF = 0; // 割り込みフラグをクリア } int main(void) { init(); sw=1; led=1; led3=0; cnt1=0; LEDflg=0; while(1) { if(cnt1>=10){ led3=~led3; cnt1=0; } } } void interrupt tc_int(void){ // 割り込みハンドラ if(T0IF == 1){ cnt++; TMR0=61; T0IF = 0; // 割り込みフラグをクリア if(cnt>=40){ cnt=0; cnt1++; led2= ~led2; } } }

  • PIC12F629のMCLRピンが出力に?

    PIC12F629でリレーをON/OFFしています。 使用ピンはGP1とMCLRのみです。 動作中にCPUに約0.8Aぐらい流れCPUが発熱(手で触れないほど)するトラブルが発生しました。 このときはMCLRピンは電源(+5V)に直結してあります。 対策としてMCLRピンから抵抗1KΩを経て+5Vへ接続することにより解決しました。 理由としての予想ですが リレーのノイズにより入力専用のMCLRピンが出力になり0出力され +5Vから(抵抗がないので)大電流が流れこんだ・・・ と思うのですが。 入力専用のMCLRピンが出力になるという仮定がへんですが 私には、そうしないと説明がつかないような気がします。 「正しい解釈(?)」を教えてください。

  • 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のPWMの正しい使い方について教えてください

    PIC12F1822用のPWMの基本動作テストプログラムを作りましたが、PWM出力が意図どおりに得られません。 (XC8のテストプログラムを下に添付。テストパターン1/2の切り替えはコメントアウトをお願いします。  アナライザの出力を画像で添付しました。) テスト目的: タイマー0の周期割り込みに合わせて、PWMのデューティー比(または周期)を変更するプログラム   テストパターン 1 : パルスのデューティー比を変えるテスト 質問1: パルスのデューティー比を変えるテストは、PWM設定の一回おきにCCPからのPWMの出力が出ません テストパターン 2 : パルスの周波数を変えるテスト 質問2: 周波数を変えるテストはOKに見えるものの、1回目のPWMがHighとなるのと、割り込みの11回目、13回目あたりでPWM出力が欠落する 【回答のお願い】 どうも、PWMのレジスタ設定に手順、またはタイミングがあるのではないかと思いますが、原因がわからず困っております。 PICに詳しい方からのご指導をよろしくお願いいたします。                                    K.A. ------------------------------------------------------ /* * File: PIC12F1822 PWC * Author: K.A. * * Created on 2014/07/20 * * タイマー0の周期割り込みに合わせて、PWMのデューティー比(または周期)を変更するプログラム * */ #include <stdio.h> #include <stdlib.h> #include <xc.h> #pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=ON, BOREN=ON, MCLRE=OFF #define _XTAL_FREQ 8000000 // クロック8MHz /* * */ // タイマー割込みの処理 int TMR0_Count = 0; // タイマーの割込み発生回数をカウントする変数 void interrupt Timer0(void) { // タイマー0の割込み発生か? Timer0 は 8bitの オーバーフロー・カウンタ if (TMR0IF == 1) { TMR0_Count++; if (TMR0_Count > 5) { TMR0_Count = 0; if (RA5 == 0) RA5 = 1; else RA5 = 0; // RA5は、動作表示用LED } TMR0IF = 0; // タイマー0割込フラグをリセット } } int main(int argc, char** argv) { unsigned int pulse_width = 5; OSCCON = 0b01110010; // 内部クロックは8MHz ANSELA = 0b00000000; // すべてをデジタルI/Oに割当 TRISA = 0b00001000; // すべてのピンは出力に割当てる(RA3は入力専用) PORTA = 0b00000000; // 出力ピンの初期化(全て'0'にする) RA5 = 0; // 動作確認用LED // Timer0  Timer0 は 8bitの オーバーフロー・カウンタ OPTION_REG = 0b00000001; // 内部クロックでTIMER0を使用、プリスケーラカウント値 1:2 // bit5:0=Fosc/4, bit3:0=PreScaler_ON, bit2-0:PreScaler TMR0 = 0; // タイマー0の初期化 (+2cycle) TMR0IF = 0; // タイマー0割込フラグを0にする TMR0_Count = 0; // 割込み発生の回数カウンターを0にする TMR0IE = 1; // タイマー0割込みを許可する GIE = 1; // 1: 全割込み処理を許可する /* PWM */ TRISA2 = 1; // RA2 出力をサスペンド TMR2IF = 0; // TMR2 フラグをクリア CCP1SEL = 0b0; // CCP1/P1Aの機能をRA2に割り当てる CCP1CON = 0x0C; // PWM モード // Period を 設定する xx ms=((PR2)+1)*4*125ns(8MHz)* PreScaler(x1-x64) PR2 = 127; // 4.096ms (プリスケーラが x64 の場合) T2CKPS0 = 0b1; // プリスケーラ 00:x1, 01:x4, 10:x16, 11:x64 T2CKPS1 = 0b1; // CCPR1L = pulse_width >> 2; // パルス幅上位8bit CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // パルは幅下位2bit TMR2ON = 1; // TMR2 カウント開始 while (TMR2IF == 0) { /** / do nothing /**/ } TRISA2 = 0; // RA2に出力を接続 while (1) { if (TMR0_Count == 0) { /**** テストパターン 1 : パルスのデューティー比を変えるテスト ****/ // パルスのデューティー比を変えるテストは、PWM設定の一回おきにCCPがPWMの出力が出ません。 なぜ? pulse_width = pulse_width + 10; if (pulse_width > 500) pulse_width = 5; /**/ /**** テストパターン 2 : パルスの周波数を変えるテスト **** / // 周波数を変えるテストはOKに見えるが、 // 1回目のPWMがHighとなるのと、割り込みの11回目、13回目あたりでPWM出力が欠落する PR2 = PR2 - 8 ; if (PR2 < 8) PR2 = 127; pulse_width = PR2 ; // Duty 25% に相当 /**/ CCPR1L = pulse_width >> 2; CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; TMR0_Count++; // 続けて PWMの設定変更をしないためのフラグ代わり } } return (EXIT_SUCCESS); }