PICマイコン(PIC12F675)のI/Oポート設定と使い方

組み込みエンジニア

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

マイコンのソフト開発を行うと必ずと言っていいほどI/Oポートの制御を行います。I/Oポートを操作して外部機器にONしたりLEDを点灯させて通知したり警報を鳴らしたりと用途は様々です。マイコン開発の基礎ともいえるI/Oポートの操作について説明します。

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

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

PICマイコン(PIC12F675)の初期化

PICマイコンの開発環境であるMPLAB X IDEがインストールされていることを前提に進めていきます。初めにCONFIG設定を行います。MPLAB X IDEのインストールの方法は下記記事にまとめています。

MPLAB X IDEによるPICマイコンの開発環境作りの手順

この設定はPICマイコンを使う上で重要な設定を行う個所になります。マイコンが動くために必要なクロックを外部から供給するか内部のクロックを使用するかなど各項目を見ながら設定していきます。

Configuration Bitsの設定

ConfigurationBitsの設定
ConfigurationBitsの設定

main.cを作成するとmain関数のみの画面になります。始めに「Configuration Bits」の設定を行います。エディターの上面ツールのProductionから「Set Configuration Bits」をクリックするとエディターの下に設定できる内容が表示されます。今回設定しておきたい内容は、FOSC・MCLREです。

FOSCは内部のクロックを使用しGP4をI/Oとして使用したいのでINTRCIOを選択します。MCLREは入力専用ピンですが、ONにするとリセット端子になるためOFFのままにします。OFFにするとGP3(DI)として使用できます。

この設定が完了したら選択項目欄の下に「Generate Source Code to Output」をクリックするとソースが作成されます。これをすべてmain関数の上に貼り付けます。次はmain関数の中で各種機能の初期化を行っていきます。

各種機能の初期化

PIC12F675の各種機能の初期化を行っていきます。今回はGPIO端子はLEDを点灯させるのみなのでI/Oポートの設定のみとなります。

マイコンはクロックを逓倍して分周して動作クロックを選択するものもありますが、今回はPIC12F675の内部のクロックを使用するため4MHz固定となります。

動作クロックはミドルレンジのPICマイコンの仕様から内部クロックが4パルスで1命令となるので1MHz(1us)で動作します。

設定しない場合でもソースに記述しておくと意図して設定していないことが明確になり、あとで使用したいときに設定を変えるだけでよいので必要に応じてソースを記述しておくことをお勧めします。

初期化する際の値は0x00というように16進数での表現にしています。2進数での表記は0b00001000になりますが、組み込みエンジニアは16進数でコーディングすることがメインになりますので16進数での表記とします。

I/Oポートの設定

#include <xc.h>
//--------------定数定義----------------------------
#define _XTAL_FREQ 4000000 //delay関数を使用するときに必要 4MHz

void main(void) {
    //各種初期化    
    ADCON0 = 0x00;  //ADC使用しない 
    ANSEL = 0x00;   //アナログモードは使用しない
    CMCON = 0x07;   //コンパレータ使用しない
    TRISIO = 0x08;  //GP3はDI・その他はDO
    GPIO = 0x00;    //ポートの設定 1:High 0:Low
    //各種初期化 END

I/Oポートの設定はADCの設定やコンパレータの設定とリンクしている部分もありますので同時にやっておくほうが良いと思います。

今回はADCとアナログモードとコンパレータは使用しないので使用しない設定にしておきます。

ADCを使用するときは、該当のTRISIOレジスタにおいて端子を入力にしなければならないとデータシートに注意書きされています。

このように各種機能とレジスタの設定がリンクしていることもあります。CMCONは使用しない場合にbit2-0に1をセットする必要がるので0x07としています。I/Oポートの設定はTRISIOレジスタで行います。

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

TRISIO0はGP0のI/Oの切り替えTRISIO1はGP1のI/Oの切り替えという具合でGP5までのI/Oの切り替えを考えていきます。PIC12F675においてはGP3はDI固定となります。

今回はGP3以外は出力になるのでTRISIO3が1(GP3は入力固定)となる以外はすべて0をセットします。

PICマイコン周辺の回路図を考える

I/Oポートの操作確認の回路図
I/Oポートの操作確認の回路図

LEDを点灯/消灯させるプログラムを作って動作を確認するためには周辺回路が必要になります。上記の回路図を参考にしてソフトを設計していきます。

この回路図は、GP2とGP0を1にしたとき点灯と消灯の関係が反対になるようにしています。LED3はSW1が押されたときのみ点灯するようにします。

PICマイコンのI/Oポートを制御する

I/Oポートの制御を行う前にmain関数内に無限ループを設けます。無限ループを組んでおかないとマイコンが動作完了してしまうためです。

無限ループはwhlie( 条件 )で実現できます。条件を満たす場合は1、満たさない場合は0となり0となったときはwhileによる繰り返しから抜けてしまいます。無限ループを作りたいため条件を常に満たすように1を入れます。

I/Oポートの制御はこのwhile(1)のループの中で行います。

    while( 1 ){
    
        GPIO0 = 1;          //Lアクティブ(LED1消灯)
        GPIO2 = 1;          //Hアクティブ(LED2点灯)
        __delay_ms(250);    //250msソフトウェアウェイト
        GPIO0 = 0;          //Lアクティブ(LED1点灯)
        GPIO2 = 0;          //Hアクティブ(LED2消灯)
        __delay_ms(250);    //250msソフトウェアウェイト
        
        if( GPIO3 == 1){    //GP3がHレベルか
            GPIO5 = 1;  //Hアクティブ(LED3点灯)
        }
        else{
            GPIO5 = 0;
        }
    }

GP0を出力するときはGPIO0に0(Low)または1(high)をセットします。GP2の場合はGPIO2に0か1をセットします。このようにして対象のDOを制御してLEDを点灯/消灯させます。

GPIO0とGPIO2に1をセットするとLED1が消灯しLED2が点灯します。__delay_ms(250)はソフトウェアウェイトで250msの間そのまま待機状態となります。アンダーバーは2つあります。

ソフトウェアウェイト後にGPIO0とGPIO2に0をセットするとLED1が点灯しLED2が消灯します。__delay_ms(250)によって250ms間ソフトウェアウェイトで待機します。

if( GPIO3 ==1)はSW1のONOFFを判定します。SWが押されていた場合GPIO3が1(ON)と判定されるのでGPIO5に1をセットしてLED3を点灯させます。0(OFF)と判定されればLED3を消灯します。

この処理を無限に繰り返すことでLEDが点灯/消灯するソフトとなります。ただし、このプログラムには欠点があります。delay関数を使用しているのでmain関数の1周にかかる時間が500ms以上となることです。

ソフトウェアウェイトで待機しているときは処理が行えないためSW1のボタンを押しても反応しないこともあります。

LEDを点灯/消灯するだけの簡単なプログラムなら問題になりませんが、処理時間の遅延が問題となるシステムではdelay関数は使用しないほうが良いでしょう。

ソースコード全体

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

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

#include <xc.h>
//--------------定数定義----------------------------
#define _XTAL_FREQ 4000000 //delay関数を使用するときに必要 4MHz

void main(void) {
    //各種初期化    
    ADCON0 = 0x00;  //ADC使用しない 
    ANSEL = 0x00;   //アナログモードは使用しない
    CMCON = 0x07;   //コンパレータ使用しない
    TRISIO = 0x08;  //GP3はDI・その他はDO
    GPIO = 0x00;    //ポートの設定 1:High 0:Low
    //各種初期化 END
    
    while( 1 ){
    
        GPIO0 = 1;          //Lアクティブ(LED1消灯)
        GPIO2 = 1;          //Hアクティブ(LED2点灯)
        __delay_ms(250);    //250msソフトウェアウェイト
        GPIO0 = 0;          //Lアクティブ(LED1点灯)
        GPIO2 = 0;          //Hアクティブ(LED2消灯)
        __delay_ms(250);    //250msソフトウェアウェイト
        
        if( GPIO3 == 1){    //GP3がHレベルか
            GPIO5 = 1;  //Hアクティブ(LED3点灯)
        }
        else{
            GPIO5 = 0;
        }
    }
}
//---------------------end file----------------------------

関連リンク

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

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

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

RUNTEQ-プログラミングで自由を手に入れる

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

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