PIC12F683を使ってLEDを2進数表記させよう

今回の記事について

 12F683の出力を練習するためにLEDを使った練習です。せっかくですので、LED4つ用いて2進数表記をカウントしながら表現できるプログラムを作成していきましょう。割り込みを使って待機時間を作る方法をこれを機に学習していきましょう。

2進数とは

 人が日頃使用しているのは、10進数です。簡単に言うと0から数えて10番目に2桁に切り替わり 
   10の位が「1」 1の位が「0」
 になります。再び、1の位が「0」→「1」→「2」→・・・「8」→「9」→「0」と0から9を繰り返します。
 同様に、2進数も「0」「1」を繰り返していくため、下記のように繰り返していきます。変換表は下記に示します。10進数から2進数の変換方法については、後日記事にしようかなと思います。
 2進数は、機械語とも呼ばれます。0がOFFで1がONという意味ですね。電気で動いているもの全ては、電気が通るか通らないかでしか判断できません。C言語やJava等のプログラムもコンパイルを通して、機械語に変換されているわけですね。

2進数変換表

 2進数    10進数
   0      0
   1      1
  10      2
  11      3
 100      4
 101      5
 110      6
 111      7
1000      8

今回の作業で必要なもの

 今回の作業で必要なものを下記に示します。一度揃えたら購入しなくても良いです。今回の工作は使いまわせば0円です。

合計1,035円(前の記事:踏切信号を作成していれば0円)

PIC12F683 1個 170円(I-00801) 再利用可能
ブレッドボード 1個 200円(P-05294) 再利用可能
LED 4個 200円(I-03982)※チップLEDです。 再利用可能
コンデンサ0.1u 1個 15円(P-10147) 再利用可能
抵抗10k 1個 100円(R-25103)※100個入り 再利用可能
ジャンパワイヤ 10本 350円(P-02932)※10本入り 再利用可能

回路の作成

 今回の回路設計のポイントは特にありません。LED2を4つ使用したのは、2進数表記で4ビットにした方が表現しやすいと考えたためです。今回も、正論理の回路設計になっています。

MPLABを使ってプロジェクトを作成

MPLABを使ったプロジェクトの作成は下記の記事を参考にしてください。コンパイラの設定をC99→C90へ変更するのを忘れないようにしてください。

https://e-work-education.com/2021/12/07/project/

プログラムのポイント

 このプログラムのポイントは、割り込みプログラムを活用して0.5秒の待ちを作り出しているところになります。変数「g_flag」は、割り込みのプログラム内で、0.5秒ごとに「1」が代入されます。今回は、1~8まで2進数をLEDで表示していくカウントアップ型になります。
 「GPIO」は、マイコンの出力端子になります。注意点は、GP3が強制的に入力にっているため、GP0・GP1・GP2・GP4が出力になっているということです。よって、普通に変数「cnt」を増やしていくと、8を表示しなくなります。プログラムの「if(cnt>7)」内にある「led_data = 0b00010000;」が、その対応になります。
 忘れそうになるのが、「g_flag = 0;」の部分。これを忘れるとプログラムが動作しなくなるんだなぁ~。

//ここから動作のプログラム
    while(1){
        if(g_flag == 1){
            cnt++;
            if(cnt>7){
                cnt = 0;
                led_data = 0b00010000;
            }else{
                led_data=cnt;
            }
            g_flag = 0;
        }              
    //出力
        GPIO = led_data; 
    }//プログラムここまで

(完成)プログラム

 プログラムの行数が100行を超えました。しかし、実際の動作に関するプログラムは、10行程度になります。ここが増えてくるとプログラムを考えるときの概略図みたいなものが必要となります。

/*
 * File:   binary.c
 * Author: TM-kit
 *
 * Created on 2021/12/18, 23:19
 */
#include <xc.h>

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

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)

unsigned int g_cnt=0;
unsigned char g_flag=0;
int g_delayTime = 500;

#define _XTAL_FREQ 4000000

//スイッチを定義して今後SW1とする
#define SW1 GP5
#define Led_ON 1
#define Led_OFF 0
//割り込みのプログラム
static void interrupt time0int (void)
{
    if(INTCONbits.T0IF == 1)
    {
        /*タイマーフラグをリセット*/
        INTCONbits.T0IF = 0;
        TMR0=252;/*1m秒ごと*/
        g_cnt++;
        if(g_cnt>g_delayTime)
        {
            g_flag = 1;

            g_cnt=0;//タイマーカウントのリセット
        }       
        //WRITETIMER0(64536);
    }
    
}
//ここからメインプログラム
void main(void) {
//変数設定
    unsigned char cnt = 0;
    unsigned char led_data = 0;
    
    
    /*手順1:内部クロックの設定:4MHz*/
    /*データシート:P19,P20*/
    OSCCON=0b01101000;

    /*ポートプルアップを使いたい場合は、このオプションレジスタを0で有効にしておく*/
    /*プリスケーラ:256 */
    OPTION_REG=0b00000111;

    /*手順2:ポートデジタルに設定*/
    /*P33(P35)*/
    /*設定全てデジタル & Fosc/64*/
    ANSEL=0b01100000;

    /*手順2:ポートの入出力の設定 1;入力 0:出力*/
    /*今回の設定:GP3は入力のみなので1を立てておく。また、今回は、反省を活かし入力をGP5とします*/
    /*データシート:P36*/    
    TRISIO=0b00101000;

    /*今回の入力は、GP5なのでそこをプルアップする*/
    //WPUbits.WPU5=1;

    /*ポートのデータは何が入っているかわからないので、消灯できるように0をポートに入れておく*/
    GPIO=0b00000100;

    /*念のためにコンパレータを無効にしておく*/
    CMCON0 = 0b00000111;

    GP0=1;
    TMR0 = 252;
    INTCONbits.T0IE = 1;
    INTCONbits.GIE = 1;
    
//プログラム開始前の初期設定    
    led_data = 1;
    cnt = 0;
    g_delayTime = 500;
    g_flag = 0;
//ここから動作のプログラム
    while(1){
        if(g_flag == 1){
            cnt++;
            if(cnt>7){
                cnt = 0;
                led_data = 0b00010000;
            }else{
                led_data=cnt;
            }
            g_flag = 0;
        }              
    //出力
        GPIO = led_data; 
    }//プログラムここまで
    return;
}

まとめ

 出力は、データシート31P(PDFだとP33)のGPIOを参考にプログラムを構築します。入力と出力の制御は、組み込みマイコン制御の基本です。しっかりと学習しておくと良いと思います。

データシート 12F683のリンクはこちらー>ここをクリック

Follow me!

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です