PIC16F19155を使ってみる(その1)

今回はPICの記事です。
実は、電子ペーパーを動かす記事の続きなんですが、しばらくはPICを動かしてみることをやっていくのでタイトルを変えています。
前回の記事はこちら。
alasixosaka.hatenablog.com

PICは久しぶりなので、まずは基本のLチカです。
選んだPICはPIC16F19155という品番になります。こちらは、PIC16F1シリーズの一つで、液晶ドライバ搭載のタイプですが、今回は液晶は駆動しません。
選んだ理由はリアルタイムクロックモジュール(RTCC)が搭載されているからです。もっと高級な18Fや24Fには割と搭載されていますが、16F1シリーズだと、液晶ドライバの積んである16F191xxという品番のものしかありません。察するに、液晶ドライバ搭載ですので、時計用のチップなのではと思われます。液晶は使いませんが電子ペーパーを使って時計を作る予定なので、一応用途的にはピッタリというところでしょか?

基本のLチカではまる。

さて、PICですが、Arduinoのようにお手軽には使えません。開発環境はMicrochip社提供のMPLAB XIDEというのを使います。Cで開発するためにはXC8コンパイラというのをさらにインストールする必要があります。ちなみにXC8の8は8ビットのことで、Microchip社の8ビットマイコン用のコンパイラになります。16ビットのマイコンを使う場合にはXC16をインストールする必要があります。32ビット用のXC32というのもあります。まあ、ここまでくるとホビーの領域を超えているような気もしますが。とりあえず、8ビットで十分なのでそいつを使います。
MPLAB XIDEのバージョンは6.0、XC8のバージョンは2.4です。
PICは最初のコンフィグレーションビットの設定をしてやったり、ピンの設定を1からやったりと、初期設定が面倒なのでArduinoに比べるとハードルが高いのですが、前の記事にも書いたように消費電力で選べばPICということになります。今回の16F19155というチップには更に低消費電力の16LF19155というのもあります。F品番は電源電圧が2.8-5.5Vなのに対し、LF品番は電源電圧が1.8-3.6Vと低電圧駆動で電池で駆動する用途に向いていますし、より低消費電力なので本当はそちらを使いたかったのですが、秋月で入手できるのがこちらだったので今回はF品番を使います。
さて、マイコンで手始めにやる定番と言えばLチカです。早速やってみました。
配線はこちら。

Lチカ用の配線

左上のピンヘッダはPICKit接続用です。一番左が1番ピンです。MCLRを1kΩでプルアップ。RA0に330Ωの抵抗とLEDを接続しています。VCCとVSSの間に0.1μFのコンデンサを入れていますが、一応念のためくらいです。
テストなので、給電はPICKitから行っています。
プログラムです。LEDが1秒間隔で一瞬チカっと光って消えるを繰り返す単純なプログラムです。

// CONFIG1
#pragma config FEXTOSC = OFF    // 外部オシレータを無効にする
#pragma config RSTOSC = HFINT1  // COSCを HFINTOSC (1MHz)に設定する。COSCを0x110に設定したの同じ。クロック周波数は1MHzになる
#pragma config CLKOUTEN = OFF   // クロック信号を外部端子に出力しない
#pragma config VBATEN = OFF     // VBATピンを無効にする
#pragma config LCDPEN = OFF     // LCD チャージポンプを無効にする
#pragma config CSWEN = ON       // クロックモード変換を有効にする
#pragma config FCMEN = ON       // フェイルセーフクロックモニターを有効にする

// CONFIG2
#pragma config MCLRE = ON       // MCLR ピンを有効にする
#pragma config PWRTE = OFF      // パワーアップタイマーを無効にする
#pragma config LPBOREN = OFF    // Low-Power BORは無効
#pragma config BOREN = ON       // ブラウンアウトリセットを有効にする
#pragma config BORV = LO        // ブラウンアウトリセットの電圧設定を低にする 1.9V 
#pragma config ZCD = OFF        // ゼロクロスディテクトを無効にする
#pragma config PPS1WAY = ON     // PPSの設定変更を許可しない(一度設定したら変更不可)
#pragma config STVREN = OFF     // スタックオーバーフローリセットは無効

// CONFIG3
#pragma config WDTCPS = WDTCPS_31// ウォッチドックタイマーの周期設定 1:65536; 
#pragma config WDTE = OFF       // ウォッチドックタイマーを無効にする
#pragma config WDTCWS = WDTCWS_7// ウォッチドックタイマーのウィンドウは常にオープン
#pragma config WDTCCS = SC      // ウォッチドックタイマーのインプットはソフトで選択

// CONFIG4
#pragma config BBSIZE = 512     // ブートブロックのサイズは512ワード
#pragma config BBEN = OFF       // ブートブロックは無効
#pragma config SAFEN = OFF      // SAFイネーブルビットは無効
#pragma config WRTAPP = OFF     // アプリケーションのライトプロテクトは無効
#pragma config WRTB = OFF       // ブートブロックのライトプロテクトは無効
#pragma config WRTC = OFF       // コンフィグレーションレジスタのライトプロテクトは無効
#pragma config WRTD = OFF       // EEPROMのライトプロテクトは無効
#pragma config WRTSAF = OFF     // ストレージエリアのライトプロテクトは無効
#pragma config LVP = OFF        // ローボルテージプログラミングは無効

// CONFIG5
#pragma config CP = OFF         // UserNVMプログラムメモリのプロテクトは無効


// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>


#define _XTAL_FREQ 1000000

void main(void) {

    ANSELA = 0b00000000;  // ポートAをすべてデジタル
    TRISA  = 0b00001000;  // RA3以外は入力

    RA0 = 0;
    
    while(1){
        RA0 = 0;
        __delay_ms(950);            
        RA0 = 1;
        __delay_ms(50);
    }
    return;
}

このプログラムでバッチリ動くのですが、実は最初は出力ポートをRA0でなく、RA5で試していました。別に大した理由はなく、参考にしたサイトの記事がRA5を使っていたのでそうしただけなのですが、LEDが光らず結構悩みました。とりあえず、テスターで電圧値を計ってみると、ゆっくりと電圧が上昇していき、0Vに戻るを繰り返しています。とても1秒間隔には見えず明らかに変な挙動です。データシートを見ると、RA5はVBATという表示があります。VBATは何かというと、リアルタイムクロックをバックアップするためのバックアップ電源をつなぐ端子です。しかし、VBATはコンフィグレーションビットで無効にしているはずなので通常のデジタル端子として動作するはずなのですが、どうもそうなっていない様子。そこで、プログラムを書き換え、LEDをRA0に繋ぎ変えると普通に動きました。データシートを見ても、RA5端子に関する特別な設定が見当たらず、よくわかりませんでした。なので、RA5は使わずに別の端子を使う方が良いのではという結論になりました。ちょっと引っかかるものがありますが。
次回はリアルタイムクロック(RTCC)を使ってみたいと思います。