ものづくりブログ

ゼロからスタートして何かを作って世に出すまでのことを書くブログです.

プログラムを使ったLチカの解説(C言語)

 

こんにちは.

 

前回の記事C言語によるプログラミングを使用したLチカを行いました.

 

その際にプログラムの中身について全く解説を行っておりませんでしたので,今回はそのあたりの解説をしようと思います.

 

はじめにちょこちょこと出てくる専門用語の解説です.

 

ソースコード: プログラム言語で書かれたプログラムそのもののことを指します.コンパイル(前回の記事参照)前のファイルのことです.

定数: 値の定まった数字のこと."1"とか"5.3"とかそういう数字です.対義語は変数です.

変数: 値の定まっていない数字のことで,あとから定数を代入して使用します.例えばセンサの値を入れる変数を作っておいて,センサの値を取ったらそこに代入するなんて使い方をします.

 

さて,では早速ソースコードの解読に進みます.

以下は前回書いたソースコードです.

 

#include <wiringPi.h>

 

#define LED_PORT 4  /* GPIO4 */

 

int main(void){

     int i;

 

     //initialize

     if(wiringPiSetupGpio() ==  -1) return 1;

     pinMode(LED_PORT, OUTPUT);

 

 

     for(i=0; i<10; i++){

          //LED ON

          digitalWrite(LED_PORT, 1);

          delay(500);

 

          //LED OFF

          digitalWrite(LED_PORT, 0);

          delay(500);

          }

 

     return 0;

}

 

これを1行ずつ解説していきます.

 

 

#include <wiringPi.h>

以前の記事でインストールしたwiringPiで実行することを宣言しています.WiringPiに含まれている機能を使うため,それが記述されているwiringPi.hというファイルを取り込んでいます.この.hで終わるファイルをヘッダファイルと呼びますが,ヘッダファイルを取り組むことをincludeすると言います.ここらへんはまだ「ふーん,そうなんだ.」くらいでOKです.

 

#define LED_PORT 4  /* GPIO4 */

ここではLED_PORTという文字列は4という意味だと定義(define)しています.あとでこのLED_PORTというのはソースコード内に出てきますが,そこでLED_PORTのかわりに4という整数を入力しても同じことです.ただ,例えば接続するポートが変更されたときに,ソースコード内の数字を1か所ずつ全て変更するのは面倒なので,ソースの冒頭であらかじめ定義しておいて,そこだけ変更すれば良いようにしておく目的でdefineが使われています.

ちなみに/*と*/で囲んだ箇所はコメントといって,プログラムを実行する際には読まれません.あとで人間が読んだ時にその行が何のためにあるのかなどを理解するために用意されたメモ機能です.

 

int main(void){

C言語ではこのint main(void){}の中身が最初に実行されます.このような{}でくくられた部分を関数と呼ぶのですが,今はまだそこまで理解しなくてOKです.関数の話をするとオブジェクト指向の概念を説明する必要が出てくるのですが,それはまた別の機会に記事を書きます.

 

     int i;

"i"という変数を定義しています.定義するとは,作るというような意味です.変数はいきなり使用することはできず,使う前にこのプログラムではこの変数を使うよ,ということを事前に宣言する必要があります.これが定義です.

また,intは整数を意味しています.C言語では変数を定義するときにその変数がどのような型の変数かを指定する必要があるのですが,ここでは整数型のiという名前の変数として定義されています.まだ定数は代入されていないので入れ物だけで空っぽの変数と言うことになります.

 

     //initialize

     if(wiringPiSetupGpio() ==  -1) return 1;

     pinMode(LED_PORT, OUTPUT);

先ほど/*と*/で囲まれた範囲がコメントだと説明しましたが,//で始まる行もコメント扱いになります.違う点は,/*は複数行にまたがって範囲を指定できるのに対し,//はその行のみであるという点です.ここではイニシャライズ,すなわちGPIOの初期化に関する処理であることを示しています.

そしてのその次の行ですが,ifというのはその直後の()内が真のとき,その次に書かれている処理を実行するという意味の命令です.真とは,合っているというような意味エス.ここでは,wiringPiSetupGpioという初期化コマンドを実行して,その時返される値が-1だった場合異常なのでプログラムを終了します(1という値を返す),ということを表しています(ここは少しわかりづらいと思いますが,今はスルーしてください.この行はおまじないだと思っておいていただいて結構です).

また,その次の行はLED_PORT PINのモードを出力にする命令です.LED_PORTは最初にdefineしたので,4という数字と同じ意味でしたね.

 

     for(i=0; i<10; i++){

先ほどifという命令が出てきましたが,それと並ぶくらいよく使うのがこのforです.forは,その後の()内の条件に従って{}内の処理を繰り返すという命令です.

最初のi=0は変数iの値の初期化,次のi<10はいつまで繰り返しを続けるかという継続条件,最後のi++は1回{}内の処理が終わるごとにどのような処理をするかということを表現しています.i++はiに1加える,という意味です.

実際にどのような処理になるかを順を追ってみてみましょう.

まず、初期化条件に従って変数iに0を代入します.C言語では,=は同じという意味ではなく,左辺に右辺を代入するという意味です.ちなみに同じという意味を表現する時は,上記のifのところでも出てきていますが,=を2個重ねて,==と書きます.

次に,継続条件を見ると,iはこのとき0なので10より小さいため,i<10です.よって{}内が実行されます.

実行した後はi++なのでiに1加えて,iは1になります.

再度i<10の条件に照らすと,やはりi<10なので{}内が実行されます.

以降これを繰り返して,i = 10になった時,すなわち{}内の処理が10回実行されたときに繰り返しが終了されます.

          //LED ON

          digitalWrite(LED_PORT, 1);

          delay(500);

次にforで繰り返す中身を見てみます.digitalWriteという命令により,LED_PORT番目のポートの値が1に書き換えられています.そしてその後delayという命令により括弧内の500ミリ秒(ミリは1000分の1)待っています.

LED_PORTは4とdefineされているので,ここではPORT 4の値を1にして,0.5秒間待つという処理が行われています.

          //LED OFF

          digitalWrite(LED_PORT, 0);

          delay(500);

          }

次は逆にPORT 4の値が0に書き換えられています.そしてその後また0.5秒待つようになっています.

つまり,このforで繰り返されている部分で行われている処理は,4番ポートの値を0.5秒間1にして(LEDを点灯させて),0.5秒間値を0にする(消灯する)というものです.これを10回繰り返すので,LEDを10回点滅させるプログラムなのです.

     return 0;

}

return 0;はint main (void)が正常に終了したことを表すものです.ここも今のところはおまじないだと思っておいてください.

最後に}でくくってint main (void)が終了します.int main (void)の終了が,そのプログラムの終了を意味します.

 

いかがでしたか?一応最初から最後まで全て説明してみましたが,なかなか最初はとっつきにくいかもしれません.でもこれから何度も書いているうちに少しずつ感覚が掴めて慣れてくると思いますので,地道にやっていきましょう.

 

 

参考文献

特になし