PICマイコン(PIC12F675)のリセットとプロテクト

組み込みエンジニア

こんにちは、ENGかぴです。

マイコンのソフトを開発しているとマイコンをリセットやプログラムを保護するかを検討することがあります。PIC12F675のプログラムの保護やリセットに関する設定があり、何らかの要因でソフトウェアがリセットした場合に切り分けることができます。

ホットスタート(電源ONのままリセットによってリスタート)した場合とコールドスタート(電源OFFからスタート)した場合の考え方についてはマイコンを問わず参考になると思います。

PIC12F675を使ってマイコンの動きを勉強するためにPIC12F675の機能でできることについてまとめています。

PICマイコン(PIC12F675)で実現できる機能と解説リンクまとめ

PIC12F675のリセットとプロテクト

PIC12F675においてはCONFIGレジスタでリセットとプロテクトの設定行います。リセットの状況はSTATUSレジスタで確認することができます。

リセットのステータスなどを組み合わせることでシステムがコールドスタートしたかホットスタートしたかを区別して動作開始することができます。

コールドスタートとホットスタートの意味

コールドスタートとホットスタートの説明
コールドスタートとホットスタートの説明

マイコンが動作していて電源を切っていないにもかかわらずリセットがかかることがあります。通常の動きでリセットなら問題ありませんが、何かしらの原因によるリスタートであれば不良動作の可能性もあり得ます。リセットした時にステータスを確認して動作を切り分けることができます。

CONFIGレジスタ

MPLAB X IDEを使用するとConfiguration Bitsの設定をアシストする機能が実装されているためONとOFFをコード上で書き換えると実装できます。

引用:PIC12F675のデータシート(CONFIGレジスタ)
引用:PIC12F675のデータシート(CONFIGレジスタ)

MPLAB X IDEの表記で説明します。#pragmaでアドレス指定された変数が定義してありON/OFFを切り替えることで1または0が選択できるようになっています。

bit2-0はクロックの選択です。内部クロックを使用するのでFOSCはINTRCIOを選択します。

bit3はWDTの選択です。使用する場合はWDTEをONにし、使用しない場合はOFFにします。

bit4はパワーアップタイマーの選択です。使用する場合はPWRTEをONにし、使用しない場合はOFFにします。ブラウンアウトリセットと関連がある設定です。

bit5はリセットピンを使用するかの選択です。使用する場合はMCLREをONにし、使用しない場合はOFFにします。

bit6はブラウンアウトリセットの選択です。使用する場合はBORENをONにし、使用しない場合はOFFにします。

bit7はプログラムをプロテクトするかの選択です。使用する場合はCPをONにし、使用しない場合はOFFにします。

bit8はEEPROMをプロテクトするかの選択です。使用する場合はCPDをONにし、使用しない場合はOFFにします。

bit13-9は設定なし。bit13-12はメーカーが初期時に設定するために使用するものでユーザーが操作する必要はありません。

STATUSレジスタとPCONレジスタ

リセットの状態を確認できるレジスタです。

引用:PIC12F675のデータシート(STATUSレジスタ)
引用:PIC12F675のデータシート(STATUSレジスタ)

bit2-0は命令ビットであり基本的には使用しません。C言語でコードを書いていれば意識する必要はありません。

bit3はパワーダウンを確認するためにビットです。SLEEP命令を実行すると0になります。CLRWDTの実行や起動時のパワーアップなどで1になります。

bit4はWDTがタイムオーバーフローした時に0になります。CLRWDTを実行するかSLEEPを実行すると1になります。

bit7-5は特に設定する必要はありません。

引用:PIC12F675のデータシート(PCONレジスタ)
引用:PIC12F675のデータシート(PCONレジスタ)

bit0はブラウンアウトリセットが行われると0になります。使う場合はユーザーで1をセットしておく必要があります。

bit1はパワーオンリセットが行われると0になります。使う場合はユーザーで1にしておく必要があります。

リセットの動作を確認する

引用:PIC12F675のデータシート(リセットタイミング)
引用:PIC12F675のデータシート(リセットタイミング)

電源が印加され0から上がっていくとPORが働きパワーアップタイマ(PWRT)がタイムアップします。オシレータスタートアップ(OST)が起動しタイムアウト後リセット解除となります。

PICマイコンを問わず電源電圧が低くなってくると動作が不安定になり不良動作の原因になることから電源電圧が低くなった時や電源が不安定なときにリセットをかけるのが一般的です。

動作確認用の回路図

リスタートの要件確認の回路図
リスタートの要件確認の回路図

コールドスタートした時にメイン関数に入る前にLED1を点灯させます。SW1を押すとメイン関数に移りLED2が点灯/消灯繰り返すようにします。

WDTタイマーオーバーフローでのリセットを確認するためにCLRWDT関数を使用せずにリセットさせた場合ホットスタートとなりWDTリセットによることを表示するためにLED4が点灯します。SW1を押すとメイン関数に移ります。

/MCLRピンの確認

/MCLRピンはLアクティブの機能になります。つまりMCLRピンがLの時はマイコンにリセット状態になります。マイコンを動作させるためにはMCLRピンをHにする必要があります。

ソースコードの#define DEBUG_MCLREのコメントアウトを外すとMCLRE=ONになります。

リセットピンとして機能が割り当てられるので回路図のSW1を押すことで/MCLRピンがHとなりリセットが解除されプログラムが動作します。メイン関数に遷移しLDE2が点灯/消灯するようにします。

ブラウンアウトリセットの確認

ブラウンアウトリセットの確認方法の説明

ブラウンアウトリセットは電源電圧がブラウンアウトリセット電圧よりも低くなった時にマイコンのリセットをかけるものです。

PIC12F675のブラウンアウトリセット電圧は約2Vになっています。

ブラウンアウトリセットは電源電圧が約100usec以上低くならないとリセットがかかりません。

ブラウンアウトリセットの確認は電源間に可変抵抗で分圧した電圧を印加することで確認します。

メイン関数で点灯消灯しているLED1が消灯するまで可変抵抗を変更し、その後可変抵抗を調整して起動電圧まで上げることでブラウンアウトリセットによるリセットであることを表示するLED3が点灯します。

リセットICを使ったほうが良い理由

ブラウンアウトリセットよりもリセットICの方が良い場合
ブラウンアウトリセットよりもリセットICの方が良い場合

ブラウンアウトリセット電圧を使用すると数百uA消費電流が増えてしまいます。系統電源が取れる場合は消費電流の増加は気になりませんが、エナジーハーベストなどの微弱な電源である場合、数百uAの消費電流は大きなものになります。

外付けのリセットICを使用して/MCLRピンをコントロールすることで2.0V付近でリセットがかかる仕組みを検討したほうが良いこともあります。例ではTPS3839G25(TI製)を使用していますが、低消費で150nA程度となるのでブラウンアウトリセットよりも低消費でリセットとなります。

プロテクトの動作を確認する

プログラムのプロテクトはCPをONするとソースコードがプロテクトされCPDをONにするとEEPROMがプロテクトされます。

プロテクトされるとIDEやIPEでリードしても0x00が読みだされるようになっておりソースコードが読み取れなくなります。プロテクトを解除するとソースコードが消去されるため内容の確認ができなくなります。

プログラムの中身が知られたくない場合は使用したほうが良い機能です。この動きについては下記記事のEEPROMを使ったソースを使って確認します。

PICマイコン(PIC12F675)のEEPROMの使い方の応用

下記ソースのコンフィグレジスタのCPとCPDをONにしたときの読み込みの違いを確認します。CPについて見てみます。

ソースコードの比較(左:プロテクトなし、右:プロテクトあり)
ソースコードの比較(左:プロテクトなし、右:プロテクトあり)

ソースコードはIDEのWindow欄のTarget memory viewsを選択すると表示できます。CPはソースコードをプロテクトする設定ですが、ONとOFF時の比較をすると分かるようにプロテクトをONすると読みだしたデータがすべて0000になっています。同様にCPDについても確認します。

EEPコードの比較(上:プロテクトなし、下:プロテクトあり)
EEPコードの比較(上:プロテクトなし、下:プロテクトあり)

CPDにおいてもプロテクトによりEEPROMの値を読み込んでもすべて0x00になっていることが分かります。

EEPROMについてはユーザーでプロテクトしていてもユーザーのソースコード上のシーケンスを実行しての読み込みや書き込みはプロテクトの有無にかかわらず可能です。

プロテクトによってデータの読み取りができなくなるので製品化する場合など必要に応じてプロテクトすることは有効です。

ソースコード全体

以下のソースコードはコンパイルして動作確認をしております。チェックはしておりますがコメントなど細かな部分で間違っている可能性があります。参考としてお使いいただければと思います。

// CONFIG
#pragma config FOSC = INTRCIO  
//#pragma config WDTE = ON       
#pragma config PWRTE = OFF     
//#pragma config MCLRE = OFF    
#pragma config BOREN = ON    
#pragma config CP = OFF   
#pragma config CPD = OFF   

#include <xc.h>
//--------------定数定義----------------------------
#define _XTAL_FREQ	4000000
#define DEBUG_MCLRE   //コメントを外すとDEBUG_MCLREが定義される
//#define DEBUG_BOREN   //コメントを外すとDEBUG_BORENが定義される

#ifdef DEBUG_MCLRE
    #pragma config MCLRE = ON
    #pragma config WDTE = ON
#else
    #pragma config MCLRE = OFF
#ifdef DEBUG_BOREN
    #pragma config WDTE = OFF
#else
    #pragma config WDTE = ON
#endif
#endif
//---------------関数定義-----------------------------
void SystemStart( void);

void main(void) {
    //各種初期化    
    ADCON0 = 0x00;  //ADC使用しない 
    ANSEL = 0x00;   //アナログモードは使用しない
    CMCON = 0x07;   //コンパレータ使用しない
    TRISIO = 0x08;  //GP3はDI・その他はDO
    GPIO = 0x00;    //ポートの設定 1:High 0:Low
    OPTION_REG = 0x0F;  //WDTを使用プリスケーラ128
    //各種初期化 END
    
    SystemStart();  //スタート条件確認

    while( 1 ){
#ifdef DEBUG_MCLRE
        CLRWDT();
#else
#ifdef DEBUG_BOREN
        CLRWDT();
#endif 
#endif        
        GPIO2 = 1;          //Hアクティブ(LED2点灯)
        __delay_ms(250);    //250msソフトウェアウェイト
        GPIO2 = 0;          //Hアクティブ(LED2消灯)
        __delay_ms(250);    //250msソフトウェアウェイト
    }
}
//------------------リセット要因確認------------------------
void SystemStart( void){
    
#ifdef DEBUG_MCLRE
    //処理なし
#else
    if( nPOR == 0){  //コールドスタート
        //コールドスタート時に処理したい内容を入れる
        while(1){
            if( GPIO3 == 1){    //GP3がHレベルか
                break; //while(1)から抜ける
            }
            GPIO5 = 1;  //コールドスタートであることが分かるように点灯
        }
    }else{ //ホットスタート
        while(1){
            //ホットスタート時に処理したい内容を入れる
            if( GPIO3 == 1){    //GP3がHレベルか
                GPIO4 = 0;
                GPIO0 = 0;
                break;  //while(1)から抜ける
            }
            if( nBOR == 0){  //ブラウンアウトリセットでリセットされたことが分かる
                GPIO4 = 1; //ブラウンアウトリセットでリセット
            }
            
            if( nTO == 0){  //WDTでリセットされたことが分かる
                GPIO0 = 1;  //Hアクティブ(LED3点灯)
            }
        }
    }
    nPOR = 1;   //パワーオンリセットをセット(発生すると0)
    nBOR = 1;   //ブラウンアウトリセットをセット(発生すると0)
#endif     
}
//---------------------end file----------------------------

関連リンク

PICマイコンを使ってマイコンのレジスタの設定やMPLAB X IDEのプラグインであるMCCを使用して動作確認したことについてまとめています。

PICマイコン(PIC12F675)で実現できる機能と解説リンクまとめ

PICマイコン(PIC16F1827)で実現できる機能と解説リンクまとめ

TECH::CAMPプログラミング教養【無料体験会】

最後まで、読んでいただきありがとうございました。

タイトルとURLをコピーしました