001回
取りあえず簡単なプログラムから


・プログラムを組む前に

 さて、プログラムを組む前にちょっと開発環境を整えてみようか。基本的に我が部の開発環境に合わせての解説なので全く同じにする必要は無い。
我が部で使用してる言語はC言語であり、Windowsに標準搭載されているテキストエディタで「****.c」という名前で保存するだけでOKである。 ただし非常に使いにくい。そこで、フリーのテキストエディタのTeraPadを使って開発を進めることにする。 (細かい設定は自分好みで

・Let's プログラム

 C言語で開発するので、当然C言語を知らなきゃ開発できませぬ。一度に説明するのは面倒なので、必要に応じて説明していきます。

基本の形

#include <P16F873.h>
#include <Datalib.h>
#include <Delays.h>

void main (void)
{

}

 取りあえずこの形を作ってください。
 #include〜となっているのは、おまじないみたいなもんで必須。良く使う機能(ヘッダーファイルにて記述)を読み込む為のものです。特に<P16F873.h>ってやつは、使うPICの仕様書みたいなもんです。当然、使うPICによってこの部分は変えなきゃいけないですが、良く使う873で話を進めていきます。

肝心のプログラムは、

void main (void)
{

}

の{ }内に書いてください。



 さて、書いてくださいと言われて当然書けるわけも無く、そもそもPICっちゃ何?って感じです。PICとは000回で説明したマイコンの1種であり、用途によって様々な種類があります。今回使用するPic16F873もその中の一つです。そして、その16F873の構造は以下のようになっています。

PIC16F873
MCLR/Vpp/THV -| 1 28 |- RB7/PGD
RA0/AN0 -| 2 27 |- RB6/PGC
RA1/AN1 -| 3 26 |- RB5
RA2/AN2/Vref- -| 4 25 |- RB4
RA3/AN3/Vref+ -| 5 24 |- RB3/PGM
RA4/T0CKI -| 6 23 |- RB2
RA5/AN4/SS -| 7 22 |- RB1
Vss -| 8 21 |- RB0/INT
OSC1/CLKIN -| 9 20 |- Vdd
OSC2/CLKOUT -| 10 19 |- Vss
RC0/T1OSO/T1CKI -| 11 18 |- RC7/RX/DT
RC1/T1OSI/CCP2 -| 12 17 |- RC6/TX/CK
RC2/CCP1 -| 13 16 |- RC5/SDO
RC3/SCK/SCL -| 14 15 |- RC4/SDI/SDA

まぁ、いきなりこんなのを見せられても何?って感じですね。
まず、必要な部分から見てみましょう。

-基本設定-

1、20番ピン(Vpp、Vdd):電源(5V)と繋ぐ
8、19番ピン(Vss):アースへ繋ぐ
9、10番ピン(CLKIN、CLKOUT):発振子と繋ぐ

取りあえず以上が、PICを動かすのに必要最低限な装備です。ブレッドボード上で配線してみましょう。



さて、PICを動かすにあたって、取りあえず何らかの信号(出力)を出したい。そんな時に使用するのがI/Oポートである。
873においてRA0〜RA5(2〜7番ピン)、RB0〜RB7(21〜28番ピン)、RC0〜RC7(11〜18番ピン)が入出力に使用できる。ぶっちゃけ、さっき使った基本設定以外の部分は全て入出力ポートとして使うことが出来ます。ただし、2番ピンのように「RA0/AN0」と/で分けられているものは、複数の機能を持っており、どの機能を使うかはまた別途設定します。
見て分かるように、RA、RCポートは他の機能を持っているのが多いので、基本的にRBポートから使っていきます。



・取りあえず設定を

そういや、どんなプログラムにするか決めてなかったな(ヲイ
一番最初って事で、取りあえずLEDを光らせてみよう。使うポートは、RB5(26番ピン)にでもしておこうか。

そこでまず必要になるのが、ポートの設定と呼ばれる作業。各ポートは入力、出力どちらにでも使用できるため、どっちで使用するかということを決めてやらなくてはいけない。よって、以下のように記述する。

void main (void)
{

   PORTB=0xFF;      //PORTBを使用するという宣言
   TRISB=0x00;       //PORTBを出力端子として使用するという宣言
   PORTB=0x00;      //PORTBの初期出力が0であるという宣言

}

さて、ここでまた意味不明の記述である。

〜1行目〜

PORTB=0xFF;

順を追って説明するならまずは=について。

通常数学の数式において=とは左右が等しいということを表すのだが、C言語の「=」は=の右側の値を左側へ与えるといった意味を持つ。(因みに「==」という表記で数学上の「=」と等価な意味を持つ)つまり、PORTBの状態を0xFFにするという命令が一番最初の行に書かれている。それでは0xFFとは何だろうか?
0xと頭に付ける事によって、16進数表記で表すことを意味して、FFを2進数で表すと「1111 1111」となる。

10進 16進 2進 10進 16進 2進 10進 16進 2進 10進 16進 2進
0 0 0000 4 4 0100 8 8 1000 12 C 1100
1 1 0001 5 5 0101 9 9 1001 13 D 1101
2 2 0010 6 6 0110 10 A 1010 14 E 1110
3 3 0011 7 7 0111 11 B 1011 15 F 1111

まぁ、上の表のようになっている訳である。

一体全体これが何を意味するのか?先ほども書いたように「FF」(16)=「1111 1111」(2)であり、8桁である。因みにPORTBはRB0〜RB7までの8ヶである。こじ付け感があるが、2進数時の1ビットそれぞれがRB0〜7に対応している。言葉で言っても分かりにくいので、図で見てみる。

PORTB=0xA9
A 9
1 0 1 0 1 0 0 1
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0

とまぁ、こんな感じになる。1が使用する、0が使用しないという命令であり
この場合、RB7、5、3、1番ピンを使用するという命令になる。
プログラムの0xFFだと全て1となるので、PORTB全てを使用するって意味である。



〜2行目〜

TRISB=0x00

これはPORTBを入力にするか出力にするかを決める命令である。先ほどと同様に、2進数時の1ビットそれぞれがRB0〜7に対応している。
そして、この設定において0だと出力を意味し、1だと入力を意味する。



〜3行目〜

PORTB=0x00; 

まぁ、ぶっちゃけ無くてもOK
出力に指定したPORTBの初期出力が0って言うことを表してる。
設定しない場合、0が出力される筈なので問題無いのだが、気分の問題である。



・出力させるべし!!

まぁ、ここまでやれば後は簡単♪あと1行足すだけで終わる。

void main (void)
{

   PORTB=0xFF;      //PORTBを使用するという宣言
   TRISB=0x00;       //PORTBを出力端子として使用するという宣言
   PORTB=0x00;      //PORTBの初期出力が0であるという宣言

   PORTB|=0x20;      //RB5から出力

}

以上である。

と、今度は「|=」とかいうまたしても分からない記号が出てきた。今度はこれについて説明する。
まぁ、正直に言うならわざわざ「|=」と書かなくても「=」で事足りる。けれども、後々の事を考え、「|=」に慣れておくべきである。
「|=」とは、ディジタルでいうところのORにあたる。さて、ORとは何ぞや?

口で説明するのも面倒なので、表にて表す。因みに、式で書くと「OR」=「+」である

A+B
0 0 0
0 1 1
1 0 1
1 1 1
X 0 X
X 1 1

(Xは未知数)

と、こんな感じの演算である。(説明するまでもないかな〜

よって、「PORTB|=0x20」という操作は以下の通りである。

初期値 0 0 0 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
足す値
PORTB|=0x20
0 0 1 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
最終値 0 0 1 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0

となる。因みに初期値が0x00の場合「PORTB=0x20」とやっても同じ結果となる。

初期値 0 0 0 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
足す値
PORTB=0x20
0 0 1 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
最終値 0 0 1 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0

この二つの操作の違いを表すとしたら

初期値 1 1 0 0 0 0 1 1
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
最終値
PORTB|=0x20ver.
1 1 1 0 0 0 1 1
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
最終値
PORTB=0x20 ver.
0 0 1 0 0 0 0 0
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0

であり、一目瞭然である。「|=」は初期値に値を加える操作であり、「=」は新しい値を代入するのである。




・まとめ

ちょっと道が逸れてしまったけれど、最終的には以下のようなプログラムを組めばOKである。

#include <P16F873.h>
#include <Datalib.h>
#include <Delays.h>

void main (void)
{

   PORTB=0xFF;      //PORTBを使用するという宣言
   TRISB=0x00;       //PORTBを出力端子として使用するという宣言
   PORTB=0x00;      //PORTBの初期出力が0であるという宣言

   PORTB|=0x20;      //RB5から出力

}



取り合えず、基礎中の基礎のプログラムはこんな感じ。次はこれをコンパイルしよう!


[戻る]