8bit の PIC でやってみました。時間が空きましたが、MPLAB Snap で使えるデバイスを秋月で見つけましたので、やってみました。
以前にやったデバイスでは高電圧プログラミングが必要だったため、Snap で用いることができませんでした。
今回使用したデバイスは、秋月で見つけた 64kByte の ROM を持つものです。
接続
データシートにある以下の図を参考にします。
また、その下の表を見ると、以下のような配線にすればいいと分かります。
Snap 側ピン番号 | PIC18 側ピン番号 | ピン名 | 備考 |
---|---|---|---|
1 | 1 | MCLR# | |
2 | 20 | VDD | 3.3V, 5Vのお好きな方と接続 |
3 | 8, 19 | GND | |
4 | 28 | PGD | |
5 | 27 | PGC |
本デバイスは幅広い電圧範囲に対応していますので、5V も 3.3V も対応しています。いいですね〜〜〜
せっかくなので、システムクロックを 64MHz にして、1秒ごとにLEDをチカチカさせるようにしてみましょう。
Configuration Bits
内蔵クロックは 16MHz です。これをソフトウェア側で PLL に通すので、それを考えて設定を行います。
クロック設定
まずは内蔵クロックで動かすことを考えて、FOSC
を INTIO67
に、そして PLL をつかうので PLLCFG
を ON
にしておきましょう。
ウォッチドッグタイマを無効に
以上のコードを生成して、ヘッダか何かにコピペすれば OK です。
ソフトウェア側の設定
あとはオシレーターブロックの図を見て、以下のように設定します。
uint32_t SystemCoreClock;
void sysclk_init(void) {
OSCCONbits.IRCF = 0b111; // 16MHz
OSCTUNEbits.PLLEN = 1; // PLL enabled
while( !OSCCON2bits.PLLRDY );
SystemCoreClock = 64e6;
}
SystemCoreClock
は ARM っぽく、後々タイマー設定で便利なように作った変数です。
1msecタイマーをTimer0で作る
初期化コードです。ビット幅が収まるように分周をしています。
#define high(x) ((x) >> 8)
#define low(x) ((x) & 0xFF)
extern uint32_t SystemCoreClock;
void timer0_init(void) { // Timer0 can only reset & interrupt on overflow.
T0CONbits.T08BIT = 0; // TIMER0 as 16bit
T0CONbits.T0CS = 0; // use clock from CLKOUT (Fosc/4)
T0CONbits.PSA = 1; // Timer0 clock bypassed the prescaler
}
実際の動作をする関数はこちら。Timer0 はカウントダウンタイマーかつオーバーフロー時にイベントが発生するので、1msec 経過毎にフラグのクリアとカウンタのリロードを行っています(割り込みを有効にしていないので、割り込みフラグは立つが、割り込み自体は起こらない)。
void ms_wait(uint16_t msec) { // using Timer0
T0CONbits.TMR0ON = 1;
for(uint16_t i=0; i<msec; i++) {
INTCONbits.TMR0IF = 0;
TMR0H = high(-(SystemCoreClock / 4000 - 1));
TMR0L = low(-(SystemCoreClock / 4000 - 1));
while(!INTCONbits.TMR0IF);
}
T0CONbits.TMR0ON = 0;
}
main関数
こんな感じでLEDをチカチカします。簡単な説明ですが、ブロック図等はデータシートをゆっくりと御覧ください。
void main(void) {
sysclk_init();
timer0_init();
TRISCbits.RC0 = 0;
while(1) {
LATCbits.LC0 ^= 1;
ms_wait(1000);
}
return;
}
〆
PIC18 であっても、LVP がメインとなるデバイスなら MPLAB Snap でも書き込み・デバッグができてしまいました!Microchip のデバイスの中でも一番慣れ親しんでいるシリーズなのでとても良かったです。