PIC18と、PIC12/16とは、構成が違っているようで、コンパイラも別であった。HITECH-Cなら、for C18を新たにダウンロードする。また、PICkit3もファームウェアダウンロードが必要(これはIDEが自動でやる)。PIC18を使ったりPIC16を使ったりすると、毎回ダウンロードが発生する。そんなに時間がかからないから別に良いんだけど。
Configuration bitsの設定は、IDEの中で可能だが、プログラムの中に記述する事も出来る。PIC12F675などは __CONFIG( の一文ですんでいたのだが、PIC18Fでは、一つ一つ設定が必要らしい。
#pragma config OSC = INTIO2 //内蔵オシレータ RA6,RA7=I/Oポートとして使用 #pragma config FSCM = OFF //Fail-Safe Clock Monitor #pragma config IESO = OFF //内部、外部の切り替え無し #pragma config PWRT = ON //パワーアップタイマーON #pragma config BOR = ON //ブラウンアウトON #pragma config BORV = 42 //ブラウンアウト電圧4.5V #pragma config WDT = OFF //ウォッチドッグOFF #pragma config WDTPS = 32768 //ウォッチドッグポストスケーラ(:32768) #pragma config MCLRE = ON //マスタークリアON #pragma config STVR = OFF //Stack Full&Overflow Reset=OFF #pragma config LVP = OFF //低電圧書込OFF #pragma config DEBUG = ON //BackgroundデバッガON #pragma config CP0 = OFF //Code Protection bit Block 0 #pragma config CP1 = OFF //Code Protection bit Block 1 #pragma config CPB = OFF //Boot Block Code Protection Bit #pragma config CPD = OFF //Data EEPROM Code Protectio Bit #pragma config WRT0 = OFF //Write Protection bit Block 0 #pragma config WRT1 = OFF //Write Protection bit Block 1 #pragma config WRTB = OFF //Boot Block Write Protection #pragma config WRTC = OFF //Configuration Register Write Protection #pragma config WRTD = OFF //Data EEPROM Write Protection #pragma config EBTR0 = OFF //Table Read Protection Block 0 #pragma config EBTR1 = OFF //Table Read Protection Block 1 #pragma config EBTRB = OFF //Boot Block Table Read Protection
INTIO2のような定数は、どこにも定義が無いのだが、IDEの中のヘルプに書かれており認識するようである。それぞれの持つ意味は、PICのデータシートから紐解くしか無い。いまいちよくわかっとらん。
サンプルで用意されていたDelay関数が無くなっちゃった。あるのか知れんけど。よくわからんから重宝してたのですが、で、includeフォルダをみたら、delays.hと言うのがあった。わたしも、あんまりよくわかってないので、行き当たりばったりでよくないんですが。
/* C18 cycle-count delay routines. */ /* Passing 0 (zero) results in a delay of 2560 cycles. */ void Delay10TCYx(unsigned char); /* Passing 0 (zero) results in a delay of 25,600 cycles.*/ void Delay100TCYx(unsigned char); /* Delay1KTCYx * Passing 0 (zero) results in a delay of 256,000 cycles. */ void Delay1KTCYx(unsigned char); /* Passing 0 (zero) results in a delay of 2,560,000 cycles. */ void Delay10KTCYx(unsigned char);
で、なんがしか時間待ちするようであるので、オシロの波形で確認したところ、PIC18F1320で8MHz内蔵タイマで下表の結果だった。
Function | Results | 期待値 |
---|---|---|
Delay1KTCYx(1) | 510us | 500us |
Delay10KTCYx(1) | 5.1ms | 5ms |
Delay100TCYx(1) | 66us | 50us |
Delay100TCYx(10) | 550us | 500us |
Delay100TCYx(100) | 5.2ms | 5ms |
Delay10TCYx(1) | 19.2us | 5us |
Delay10TCYx(10) | 79us | 50us |
Delay10TCYx(20) | 146us | 100us |
Delay10TCYx(100) | 670us | 500us |
計測にPort出力のH/Lと、反転するのにif文を使っているので、その処理分追加されているので、よくわからない(条件分岐せずにポートの出力をすると670nsぐらい)けど、小さい時間は誤差が大きいようだ。内蔵タイマを4MHz設定にすると、時間は半分だった。
以上から、1TCYx=510ns(@8MHz)と思われる。8MHzは周期125nsから、TCY=4/Fosc というのがデータシートに書かれていたので、本来1TCYx=500nsとなるのかな。
なので、引数がcharなので
/* 1ms - 1275ms */ void DelayMs(int t){ if(t<128){ Delay1KTCYx(t*2); } else if(t<1275){ Delay10KTCYx(t/5); } else { Delay10KTCYx(255); } }
これで、いいでしょうか。
参考書とかでは、ポートの出力、例えばポートAのビット0は、RA0=1 などの記述で1出力できたのだが、PIC18Fでは大量のWarningが出る。そのままでも動作に問題は無いのだが、気持ち悪い。RA0の記述が非推奨のようである。
ヘッダファイルを見ると、PORTAbits.RA0と記載するのかな。でも長いなぁ
extern volatile union { struct { unsigned RB0 :1; unsigned RB1 :1; unsigned RB2 :1; unsigned RB3 :1; unsigned RB4 :1; unsigned RB5 :1; unsigned RB6 :1; unsigned RB7 :1; }; struct { unsigned RB :8; } PORTBbits @ 0xF81;
よくわからないんだけど、共用体の中に、構造体があるから、PORTBbits.RB0とPORTBbits.RBは同じメモリになるけど、PORTBbits.RB0とPORTBbits.RB1は異なるメモリにあり独立しているという意味だと思うんだけど、bitが他のbitに影響を与えるようだ。
ADCONの設定をしていないせいでした。とほほ。一部のポートはADCONがデフォルトになっていると言う事もある。