• ベストアンサー

PIC18F2550・コンパイルできない(再掲)

初めて投稿します。 技術職(機械系)の会社員です。 マイコンプログラム作成歴:約3ヶ月のほぼド素人です。 現在、会社の技術研修でPIC18F2550を使ったライントレーサの動作プログラムを作成しています。先日までPIC16F84A&88でのプログラミングを行なっており、基本は理解できているつもりです。 …が、これまで見た事のないエラーコードが出てしまい、理由がわからず困っています。 エラーコードは、[1101]lvalue required と[1105]symbol '○○○' has not been defined というもので、コンパイラのユーザーガイドを見ると、変数(GIE,LATA0等)の認識ができない?エラーのようです。ヘッダーファイルのインクルードもしており、これまでの84A&88では出なかったエラーです。 webも調べましたが、わかりませんでした。 作成環境はMPLAB V8.36、MPLAB C18コンパイラV3.33 です。 エラーメッセージ画面添付、ソースコード掲載しますので、PICプログラムに精通されている方、間違い部分をご教授頂けないでしょうか? 何卒ご協力のほどよろしくお願いします。 --【以下、コード抜粋】-- //●使用マイコン:PIC18F2550 //===《初期設定》=== //---<ヘッダーファイル>--- #include<p18f2550.h> #include"delays.h" //---<コンフィグレーション>--- #pragma config PLLDIV = 5 #pragma config CPUDIV = OSC1_PLL2 #pragma config USBDIV = 2 #pragma config FOSC = HSPLL_HS #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config PWRT = ON #pragma config BOR = OFF #pragma config BORV = 3 #pragma config VREGEN = OFF #pragma config WDT = OFF #pragma config WDTPS = 1 #pragma config MCLRE = ON #pragma config LPT1OSC = OFF #pragma config PBADEN = OFF #pragma config CCP2MX = ON #pragma config STVREN = OFF #pragma config LVP = OFF #pragma config XINST = OFF #pragma config DEBUG = OFF #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF #pragma config CPB = OFF, CPD = OFF #pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF #pragma config EBTRB = OFF //---<関数宣言>--- void ioport(void); void interr(void); void pwm_settei(void); void move_A(void); void move_B(void); void delay_ms(long); //---<変数宣言>--- int c_flg = 0; //変数「c_flg」を宣言 //------------------------------------------------------------ //===《動作プログラム》=== //---<メイン関数>--- void main() { ioport(); interr(); pwm_settei(); while(1) { move_A(); } } //---<サブルーチン>--- void ioport(void) //[入出力ポート初期設定] { ADCON1 = 0b00001111; //A/D設定:全ポートデジタル TRISA = 0b00000000; //ポートA・I/O設定 TRISB = 0b11111111; //ポートB・I/O設定 TRISC = 0b00110000; //ポートC・I/O設定 } void interr(void) //[割り込み初期設定] { GIE = 1; //グローバル割り込み設定:許可 TMR2IE = 1; //タイマ2割り込み設定:許可 } --【途中省略】-- void move_A(void) //[動作A(直線&曲線走行モード)] { switch(PORTB) { case 0b01000000 : //センサB(内左)認識 CCPR1L = 100; //CCP1 Duty値設定 CCPR2L = 30; //CCP2 Duty値設定 LATC7 = 1; //モータR1:正転 LATA0 = 1; //モータL1:正転 LATC6 = 1; //モータR2:ON LATA1 = 1; //モータL2:ON break; --【以下続く】--

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

  • ベストアンサー
noname#144013
noname#144013
回答No.4

こんにちは。 #3です。 > ちなみに、以前PIC16F84A&88でプログラムを記述した際には、上記対応 > (共用体名を付ける)は不要でしたが、マイコンの機種毎に違うのでしょうか? > 前と同じ、簡潔な記述で済む方法がありましたら紹介頂けますと幸いです。 その構造体名(及び共用体名)が不要であった変数というのは、実際に構造体 (あるいは共用体)のメンバとして定義されたものだったのでしょうか? 構造体ではなく単体の変数として定義されていた可能性はなかったのでしょうか? もし構造体メンバだったとして、その現象の違いは、マイコン(CPU)の違いに よるものではなく、コンパイラ及びその周辺(開発環境)の設定の違いによるもの だと思われます。 通常なら構造体メンバへのアクセスは、   {構造体変数名}.{メンバ名}       または、   {構造体変数名}->{メンバ名}  //←変数が構造体へのポインタの場合 のような記述にしないといけないと思いますが、 もしメンバ名のみの記述でコンパイルエラーがでなかったとしたのなら、 その考えられる要因の一つとして、以下のように #define 定義等でメンバ名が 「別名定義」されていたのではないでしょうか?   //※別名定義の例(構造体メンバへのアクセス簡易化)   #define GIE    INTCONbits.GIE   #define TMR2IE  PIE1bits.TMR2IE   #define LATA0  LATAbits.LATA0   #define LATA1  LATAbits.LATA1   #define LATC7  LATCbits.LATC7   #define LATC6  LATCbits.LATC6 上記のように別名定義しておけば、   GIE = 1;   TMR2IE = 1;   LATC7 = 1;   LATA0 = 1;   LATC6 = 1;   LATA1 = 1; のように記述した箇所は、コンパイル時にコンパイラーが、   INTCONbits.GIE = 1;   PIE1bits.TMR2IE = 1;   LATCbits.LATC7 = 1;   LATAbits.LATA0 = 1;   LATCbits.LATC6 = 1;   LATAbits.LATA1 = 1; のように展開しますので問題なくコンパイルされると思いますj。 これ以外にもメンバー名を簡略化する方法があるかもしれませんが、 今のところ思い付いたものはこれだけです。 以上。参考になれば幸いです。

annie-t
質問者

お礼

親切丁寧なアドバイス、ありがとうございました。 下名、プログラミングを始めてまだ3カ月の者で、特に初期設定関連の知識が全く無く、今回のような事態になると完全なフリーズ状態となってしまう状態にありました。 同僚にもPICに精通した者がおらず、web検索してもなかなか情報が得られない中でしたので、今回頂いた情報には本当に助けられました。 本当にありがとうございました。

annie-t
質問者

補足

情報提供ありがとうございます。 PIC16F84Aのデータシートで確認したところ、例えばGIEはINTCONレジスタの中の1変数のように見て取れます。 以前(PIC16F84A&88時)、プログラム中では特に#define定義等せずにGIE,RB0,T0IE…等、構造体変数のメンバと思われる変数をプログラム中に記述しましたが、今回のようなエラーは出ませんでした。 その際に参考にした勉強用テキストにも、特にそのような処理は書かれておらず、普通に「GIE = 1;」のような記述で書かれており、その通り記述して全く問題なく動作しました。 PIC16F84A&88から今回のPIC18F2550に変更するにあたってコンパイラを変更しているため、その設定が違うのかも知れませんね。 今後は、アドバイス頂いた#define定義を使わせてもらおうと思います。 貴重な情報、ありがとうございました。

その他の回答 (5)

回答No.6

 MPLAB C16 付属の pic1684.h の一部です。 /* INTCON bits */ volatile bit GIE @ (unsigned)&INTCON*8+7;  どうやらこのコンパイラではバイトの特定ビットに 名前が付けられるようです。  アドレス空間が数KBなら、わからなくもないです。  ただし、将来の互換性を考えると害も有るかと思います。  実際これを使って混乱した人がいるわけですから..........

annie-t
質問者

お礼

情報提供、ありがとうございます。 とりあえず、今後のプログラム作成では事前に定義をして記述したいと思います(そのままでは記述が面倒なので)が、将来的にプログラムを業務で作成するようなシチュエーションになった際には、互換性等を考慮する必要もありそうですね。 大変参考になりました! アドバイスありがとうございました。

noname#144013
noname#144013
回答No.5

こんにちは。 FarEyesです。 追加情報です。 「PIC16F84A&88」の時に使用されていたコンパイラは何をお使いでしたか? 当方でPIC用のフリーのCコンパイラ「SDCC」をダウンロードして、インストール フォルダ内にあるヘッダファイルの中身を確認したところ、下記のような記述 箇所がありました。 ■ヘッダファイルの中身  "pic16f88.h"より一部抜粋したものです。  ヘッダファイルの場所: (SDCCのインストールフォルダ)\include\pic ============================     :     : // ----- INTCON bits -------------------- typedef union {  struct {   unsigned char RBIF:1;   unsigned char INTF:1;   unsigned char TMR0IF:1;   unsigned char RBIE:1;   unsigned char INTE:1;   unsigned char TMR0IE:1;   unsigned char PEIE:1;   unsigned char GIE:1;  }; } __INTCON_bits_t; extern volatile __INTCON_bits_t __at(INTCON_ADDR) INTCON_bits; #ifndef NO_BIT_DEFINES #define RBIF         INTCON_bits.RBIF #define INTF         INTCON_bits.INTF #define TMR0IF        INTCON_bits.TMR0IF #define RBIE         INTCON_bits.RBIE #define INTE         INTCON_bits.INTE #define TMR0IE        INTCON_bits.TMR0IE #define PEIE         INTCON_bits.PEIE #define GIE         INTCON_bits.GIE #endif /* NO_BIT_DEFINES */     :     :     : // ----- PIE1 bits -------------------- typedef union {  struct {   unsigned char TMR1IE:1;   unsigned char TMR2IE:1;   unsigned char CCP1IE:1;   unsigned char SSPIE:1;   unsigned char TXIE:1;   unsigned char RCIE:1;   unsigned char ADIE:1;   unsigned char :1;  }; } __PIE1_bits_t; extern volatile __PIE1_bits_t __at(PIE1_ADDR) PIE1_bits; #ifndef NO_BIT_DEFINES #define TMR1IE        PIE1_bits.TMR1IE #define TMR2IE        PIE1_bits.TMR2IE #define CCP1IE        PIE1_bits.CCP1IE #define SSPIE        PIE1_bits.SSPIE #define TXIE         PIE1_bits.TXIE #define RCIE         PIE1_bits.RCIE #define ADIE         PIE1_bits.ADIE #endif /* NO_BIT_DEFINES */     :     : ============================ これを見ると、やはり#defineにより構造体メンバ名が別名で定義してある ものがあることが判ります。 質問者さんの以前お使いになっていたコンパイラも、このような定義がして あったのではないでしょうか? ■参考サイト(SDCC関連) フリーのCコンパイラ(SDCC)でPIC(PIC16F88)を動かす方法 http://www.welcome.mech.nagasaki-u.ac.jp/gs400e/pic_sdcc/index.htm SDCC - Small Device C Compiler http://sdcc.sourceforge.net/ 以上です。

annie-t
質問者

お礼

追加情報ありがとうございます。 当方でPIC16F84A&88時に使用のコンパイラは、教材に同梱されていた「HI-TECH C PRO for the PIC 10/12/16 MCU Family」というものです。 ヘッダーファイルを見てみたところ、 /* Definitions for INTCON register */ volatile bit RBIF @ ((unsigned)&INTCON*8)+0; volatile bit INT0IF @ ((unsigned)&INTCON*8)+1; volatile bit TMR0IF @ ((unsigned)&INTCON*8)+2; volatile bit RBIE @ ((unsigned)&INTCON*8)+3; bit INT0IE @ ((unsigned)&INTCON*8)+4; volatile bit TMR0IE @ ((unsigned)&INTCON*8)+5; volatile bit PEIE @ ((unsigned)&INTCON*8)+6; volatile bit GIE @ ((unsigned)&INTCON*8)+7; となっていました。 やはり、ヘッダーファイルで事前定義がしてあったようです。 情報提供、ありがとうございました。

noname#144013
noname#144013
回答No.3

こんにちは。 私はPICのプログラミングの経験はありませんので、以下はWEBで調べた結果のみ での回答となります。 従って、間違っている部分があるかもしれませんので、ご了承下さい。 また、間違っていた場合はすみません。 まず、#1さん回答への補足に書かれている、ヘッダーソースの後半部分が途中で 途切れていますので、extern定義のunion(共用体)変数の全容が判りません。 ですのでWEBで調査した結果、コンパイルでエラーで表示されている識別名は、 構造体(及び共用体)のメンバ名のようだと判断しました。 結論としては、#2さんの回答と同じになりますが、 ソース上でこれらのメンバにアクセスするための記述としては、   <変更前>       :     GIE = 1; //グローバル割り込み設定:許可     TMR2IE = 1; //タイマ2割り込み設定:許可       :       :     LATC7 = 1; //モータR1:正転     LATA0 = 1; //モータL1:正転     LATC6 = 1; //モータR2:ON     LATA1 = 1; //モータL2:ON       :   <変更後>       :     INTCONbits.GIE = 1; //グローバル割り込み設定:許可     PIE1bits.TMR2IE = 1; //タイマ2割り込み設定:許可       :       :     LATCbits.LATC7 = 1; //モータR1:正転     LATAbits.LATA0 = 1; //モータL1:正転     LATCbits.LATC6 = 1; //モータR2:ON     LATAbits.LATA1 = 1; //モータL2:ON       : のように構造体(及び共用体)の変数名を付けて記述する必要があると思います。 以上です。的外れな回答でしたらすみません。 参考になれば幸いです。

annie-t
質問者

補足

アドバイスありがとうございます。 ご指摘の通り記述してみたところ、GIE/TMR2IE等についてもエラーが消えました! 「構造体(共用体)の変数名を付けて記述」する必要があるという事ですね。初めて知りました。 ちなみに、以前PIC16F84A&88でプログラムを記述した際には、上記対応(共用体名を付ける)は不要でしたが、マイコンの機種毎に違うのでしょうか? 前と同じ、簡潔な記述で済む方法がありましたら紹介頂けますと幸いです。 ありがとうございました。

回答No.2

 回答1の補足です。  ヘッダはインクリュードされている前提で  LATAbits.LTAT0 = 1;  にしたらLATA0 は通りませんか。?  なお、MPLIB C18は詳しくないのでLATAbitsにどうやって アドレスを与えているかは不明です。

annie-t
質問者

お礼

貴重な情報、ありがとうございました。 今回頂いた情報により、初期設定関連についても少しずつ理解ができてきました。 本当にありがとうございました。

annie-t
質問者

補足

連絡ありがとうございます。 アドバイス頂いた記述に変更してみたところ、LAT変数のエラーは消えました!(LAT変数については、記述のしかたが悪かったようです) あと、割り込み関連の変数(GIE,TMR2IE他)が残っています。 通常、このままでいけそう(PICでよく使う変数のはずなので)な気がするのですが、何か書き方がマズいのでしょうか? それとも、p18f2550.h以外にインクルードするファイル(ライブラリファイル等?)が必要なのでしょうか? 些細な情報でも構いませんので、アドバイスよろしくお願いします。

回答No.1

 PIC18はCCS Cで使った事が有ります。  ところで p18f2550.h ファイルにGIE,LATA0の単語は出て来るんでしょうか。?

annie-t
質問者

補足

ご連絡ありがとうございます。 p18f2550.hファイルの中に記載があります。 下記に抜粋します。 よろしくお願いします。 --【以下、抜粋(p18f2550.h)】-- extern volatile near unsigned char LATA; extern volatile near struct { unsigned LATA0:1; unsigned LATA1:1; unsigned LATA2:1; unsigned LATA3:1; unsigned LATA4:1; unsigned LATA5:1; unsigned LATA6:1; } LATAbits; --【途中省略】-- extern volatile near unsigned char INTCON; extern volatile near union { struct { unsigned RBIF:1; unsigned INT0IF:1; unsigned TMR0IF:1; unsigned RBIE:1; unsigned INT0IE:1; unsigned TMR0IE:1; unsigned PEIE:1; unsigned GIE:1; };

関連するQ&A

  • PIC18F2550の割り込み処理について

    PIC18F2550を使って、外部入力割り込みがちゃんと入るかどうかをチェックするため非常に簡単なサンプルコードを書いてみたのですが割り込みが発生しないのでどなたかご助力お願いします。(コンパイラ : MPLAB C18) とりあえずスイッチを押せばINT2ピンに5Vが入力され、割り込みでLEDを点滅させるという主旨で以下のコードを書きこんで動作させました。 #include <p18f2550.h> #include <delays.h> #include <portb.h> #pragma config FOSC = INTOSCIO_EC, FCMEN = ON, IESO = OFF #pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF #pragma config WDT = OFF, CCP2MX = OFF #pragma config PBADEN = ON, LPT1OSC = ON, MCLRE = OFF #pragma config STVREN = ON, LVP = OFF, XINST = OFF #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF #pragma config CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF #pragma config WRT2 = OFF, WRT3 = OFF, WRTC = OFF #pragma config WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF #pragma config EBTR3 = OFF, EBTRB = OFF int i; void isr(void); #pragma code isrcode = 0x0000008 void isr_direct(void) {_asm GOTO isr _endasm} #pragma code #pragma interrupt isr void isr(void) { //外部入力割り込みの処理はここに記述 INTCON3bits.INT2IF = 0; for(i=0; i<10; i++) { LATCbits.LATC1 = 1; Delay10KTCYx(255); LATCbits.LATC1 = 0; Delay10KTCYx(255); } } void main() { OSCCON = 0b01110000; //システムクロックを8MHZに設定 TRISA = 0b1111111; //ポートAをすべて入力に設定 TRISB = 0b11111111; //ポートBをすべて TRISC = 0; //ポートCをすべて出力に設定 //ポートRB2の外部割込みON, 立上がりエッジでON, Bポートの抵抗プルアップOFF OpenRB2INT(PORTB_CHANGE_INT_ON & RISING_EDGE_INT & PORTB_PULLUPS_OFF); RCONbits.IPEN = 0; //割り込み優先制御OFF INTCON3bits.INT2IE = 1; INTCONbits.GIE = 1; //全割り込み許可 while(1); } しかし、スイッチを押しても割り込み処理に移行せず無反応のままです。 スイッチを押した時にINT2ピンに5V入力があることはテスターで確認したので、ソースコードの方に問題があるかと思います。 よろしくお願いします。

  • PIC18F2550の外部入力割込みについて

    PIC18F2550で外部入力割り込みがちゃんと入るかどうかをチェックするため非常に簡単なサンプルコードを書いてみたのですが、mainの処理を行うだけで割り込みが発生しないのでどなたかご助力お願いします。(コンパイラ : MPLAB C18) 以前ほぼ同様の質問を掲載しましたが、解決につながる回答が得られませんでした↓ 長い間解決出来ず困り果てているので、有益な回答をいただけると幸いです。 mainのwhileループではLEDを点滅させ、スイッチを押せばINT2ピンに0Vが入力され、割り込みでLEDを点灯し続けるという主旨で以下のコードを書きこんで動作させました。 #include <p18f2550.h> #include <delays.h> #pragma config FOSC = INTOSCIO_EC, FCMEN = ON, IESO = OFF #pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF #pragma config WDT = OFF, CCP2MX = OFF #pragma config PBADEN = ON, LPT1OSC = ON, MCLRE = OFF #pragma config STVREN = ON, LVP = OFF, XINST = OFF #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF #pragma config CPB = OFF, CPD = OFF, WRT0 = OFF, WRT1 = OFF #pragma config WRT2 = OFF, WRT3 = OFF, WRTC = OFF #pragma config WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF #pragma config EBTR3 = OFF, EBTRB = OFF int i; int j; void high_isr(void); // リセットベクタ #pragma code reset_vector=0x1000 extern void _startup(void); void remapped_reset(void) { _asm goto _startup _endasm } #pragma code high_vector = 0x000008 void interrupt_high_vector(void) {_asm GOTO high_isr _endasm} #pragma code #pragma interrupt high_isr void high_isr(void) { //外部入力割り込みの処理はここに記述 for(j=0; j<10; j++) { LATCbits.LATC1 = 1; Delay10KTCYx(255); } INTCON3bits.INT2IF = 0; } void main() { OSCCON = 0b01111100; //システムクロックを8MHZに設定 TRISA = 0b01111111; //ポートAをすべて入力に設定 TRISB = 0b11111111; //ポートBをすべて入力に設定 TRISC = 0b00000000; //ポートCをすべて出力に設定 RCON = 0b10000100; INTCON = 0b10010000; INTCON2 = 0b10000000; INTCON3 = 0b10011000; //INT2ピンの立下りエッジで割り込み処理に移行する     while(1) { LATCbits.LATC1 = 1; Delay10KTCYx(255); LATCbits.LATC1 = 0; Delay10KTCYx(255); } } スイッチ入力時に0VがINT2ピンに入力されていることは確認できたので、プログラムの方に問題があると思われます。 回答お待ちしております。

  • PICでダイナミック点灯 なぜかLEDがOFF

    8×8のLEDマトリクスをダイナミック点灯制御するのに PIC16F1938を使用し PORTAをX軸 PORTBをY軸 として、以下のようなコードを書きましたが、 なぜか、1秒ぐらいで全て消灯してしまいます トラブルシューティングが終わりません 分かる方、教えて頂けませんか? XC8を使用しています // PIC16F1938 #include <stdio.h> #include <stdlib.h> #include <xc.h> #include<math.h> #include<stdbool.h> #define _XTAL_FREQ 32000000 // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. // CONFIG1 #pragma config FOSC = INTOSC #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config MCLRE = OFF #pragma config CP = OFF #pragma config CPD = OFF #pragma config BOREN = OFF #pragma config CLKOUTEN = OFF #pragma config IESO = OFF #pragma config FCMEN = OFF // CONFIG2 #pragma config WRT = OFF #pragma config VCAPEN = OFF #pragma config PLLEN = ON #pragma config STVREN = OFF #pragma config BORV = LO #pragma config LVP = OFF #define true 1 #define false 0 void main(){ OSCCON = 0b11110000; TRISA = 0x00; TRISB = 0x00; TRISC = 0x00; ANSELA = 0x00; ADCON0 = 0x00; ADCON1 = 0x00; PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; unsigned char i; LATA=0b11111110; LATB=0b10000000; unsigned char b; bool a; b=0b11111110; while (true) { for(i=1;i<=8;i++){ __delay_ms(1); a=b>>7; b=b<<1; b=b|a; LATA=b; } a=LATB>>7; LATB=LATB<<1; LATB=LATB|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

  • 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

  • PIC16F1823の割り込み処理について

    PIC初心者です。よろしくお願いします。 ※HI-TECH Cコンパイラを使用しています。 最近まで、PIC16F676を使用していましたが、 今回、PIC16F1823に変更することにしました。 プルグラムをPIC16F1823用に変更し、実行したところ思ったように動いてくれません。 いろいろ調べたところ割り込み処理がうまいこと出来ていないような気がします。 割り込みルーチンに飛んだ後、なぜか戻ってこないような気がします。 下記のコードは、簡単に書き直しました。 どなたか分かる方、お願いしますm(_ _)m --------------------------------------------- #include <htc.h> __CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_ON & MCLRE_OFF & BOREN_ON & CP_OFF); unsigned int i,Time; void main(void) { OSCCON = 0b01101010; //おそらく4MHz? //ポートA ANSELA = 0x00; //全てデジタル CM1CON0 = 0b00000111; //コンパレート無効化 CM1CON1 = 0b00000111; TRISA = 0b00111110; //ポートA入力出力設定 WPUA = 0b00110110; //ポートAプルアップビット指定 PORTA = 0b00000100; //各ピンデフォルト値 IOCAP = 0b00100000; //割り込みピン指定 //ポートC ANSELC = 0x00; //全てデジタル TRISC = 0b00000000; //ポートC入力出力設定 nWPUEN = 0; //プルアップ有効化 IOCIE = 1; IOCIF = 0; GIE = 1; i = 0; while(1){  if(i){   RC5 =1;   RC0 =0;  }else{   RC5 =0;   RC0 =1;  } } } void interrupt ISR(void){ //割込み if(IOCIF && !RA5){  if(i) i=0;else i=1; } IOCIF = 0; }

  • PIC12F683を用いたCapture実験

    いま、PIC12F683を用いてCCPモジュールのCapture機能の実験をしています。一応、ビルドはできたので書き込んで動かしてみましたが、思ったとおり(スイッチを押したときにLEDを点灯させる)に動作しませんでした 動作はとしては、押しボタンスイッチを押したときにキャプチャーして LEDを点灯させるという簡単なものです。 下に使用しているプログラムを掲載しますので、どうしたらいいか教えてください。 // CaptureTest.c #include <pic.h> #include "delay.h" #include "CCP.h" __CONFIG( FCMDIS & IESODIS & BORDIS & WDTDIS & UNPROTECT & UNPROTECT & MCLRDIS & PWRTEN & INTIO); __IDLOC(0x00); unsigned char temp; ioport(); main(void) { //ポートの初期化、入出力設定など     ioport(); //Captureモード、立ち上がりエッジに設定 setCcpMode(CCP_CAPUTURE_PGE);      //フラグ(CCP1IF)を「0」にセット ResetCcpFlag();      //CCP割り込み許可 setCcpEnable(ENABLED); //TIMER1のプリスケーラを「1/8」に設定      T1CKPS1=1; T1CKPS0=1;     //外部回路を動作させない T1OSCEN=0;     //TIMER1を同期モードにセット T1SYNC=0;     //TIMER1のクロックは内部クロックを使用 TMR1CS=0;     //全割り込み、周辺割り込み許可 GIE=1; PEIE=1;      //TIMER1をリセット(0セット) ResetTMR1(); //TIMER1スタート     T1_START();      //CCP割り込みフラグが立つまでチェック while(ChkCcpFlag()==0);     //CCP割り込みフラグクリア ResetCcpFlag();     //GP3をハイレベルに設定してLEDを点灯 temp=1; GPIO3=temp; } ioport() { ANSEL=0x00; TRISIO=0x04; } //CCP.c #include <pic.h> void setCcpMode(unsigned char mode) { CCP1CON= mode; } void setPwmPeriod(unsigned char T) { PR2=(T-1); } void setPwmDuty(unsigned int duty) { DC1B0 = 0x01&duty; DC1B1 = 0x02&duty; CCPR1L = 0xFC &duty; } void setCcpEnable(unsigned char flag) { CCP1IE=flag; } void ResetCcpFlag(void) { CCP1IF=0; } unsigned char ChkCcpFlag(void) { unsigned char ret=0; if(CCP1IF==1) return ret=1; return ret; } void ResetTMR1(void) { TMR1H=0x00; TMR1L=0x00; } void T1_START(void) { TMR1ON=1; } void T1_STOP(void) { TMR1ON=0; } //CCP.h #define ENABLED 1 #define DISABLED 0 #define CCP_OFF 0x00 #define CCP_CAPUTURE_NGE 0x04 #define CCP_CAPUTURE_PGE 0x05 #define CCP_CAPUTURE_4th_PGE 0x06 #define CCP_CAPUTURE_16th_PGE 0x07 #define CCP_COMPARE_SET_ON_MATCH 0x08 #define CCP_COMPARE_CLR_ON_MATCH 0x09 #define CCP_COMPARE_INT 0x0A #define CCP_COMPARE_RESET_TIMER 0x0B #define CCP_PWM 0x0C extern void setCcpMode(unsigned char); extern void setPwmPeriod(unsigned char); extern void setPwmDuty(unsigned int); extern void setCcpEnable(unsigned char); extern void ResetCcpFlag(void); extern unsigned char ChkCcpFlag(void); extern void ResetTMR1(void); extern void T1_START(void); extern void T1_STOP(void);

  • 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 タイマー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; } } }

  • PIC 16F84A でLEDが点滅しない

    どんな事をしても、LEDが点滅しません何が原因なのかわかりません。何方か教えて頂けませんか。 環境は、Windowos8 MPLAB X IDE XC8 PICkit3  Pickit3対応ICSP書き込みアダブターです。 PICは PIC16F84A を使用しています。ソースコードは下記のようにしてあります。  #include <xc.h> // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. // CONFIG #pragma config FOSC = EXTRC // Oscillator Selection bits (RC oscillator) #pragma config WDTE = ON // Watchdog Timer (WDT enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (Power-up Timer is disabled) #pragma config CP = OFF // Code Protection bit (Code protection disabled) #define_XTAL_FREQ 20000000 void main(void) { TRISA = 0x00; PORTA = 0x031; TRISB = 0x00; PORTB = 0x00; while (1) { PORTA = 0x02; Delay_ms(1000); PORTA = 0x01; Delay_(1000); } } ------------回路  PIC16F84A      ------------   18  RA1-----1Kオーム----- (K)LED(A)----←  5V      17  RA0----- 1Kオーム-----(K)LED(A)----←  5V     16  OSC1----             セラロック20MHZ -------- GND   15  OSC2----   14 VDD---------------← 5V    4  MCLR--------------← 5V 5 VSS----------------- GND   コンパイルも、書き込みもできましたが駄目でした。いろいろ試みましたが成功しません。 コンフィギレーションに決定的な間違いがあるのではないか?疑っております。 よろしくお願いいたします。

専門家に質問してみよう