内容
LED 8個を点灯させます。マイコン制御の基礎中の基礎です。
ワークスペース
「開発環境を整える」ページからダウンロードしてください。
回路
回路を下図に示します。
ブレッドボード実装図
ブレッドボードの実装を下図に示します。
実習中のブレッドボード
プログラムを開く
ワークスペース「r8cm12a_breadboard」のプロジェクト「01led」をアクティブ(有効)にします。「01led」が太字になっていない場合は、右画面のように、「アクティブプロジェクトに設定」してください。 |
|
プロジェクト「01led」を有効にする |
「led.c」をダブルクリックして、プログラムリストを開きます。
「ビルド→ビルド」して、MOTファイルを作成、「ツール→R8C Writer」でプログラムを書き込んで、実行してください。 |
|
|
実行中の動画
プログラムの説明
ポートの入出力設定
R8C/M12Aには、17個の入出力端子があります(ただし、PA_0端子はリセット端子と兼用なので、電源立ち上げ時はリセット端子である必要があります)。R8C/M12Aのピン名を、下記に示します。
Px_yは、『ポートxのbity』という意味です。R8C/M12Aには、ポート1,3,4,Aがあります。
プログラムの初めに、これらの端子を入力用として使用するか、出力用として使用するかを設定します。リセット後は、入力端子になっています。
考え方は、次のとおりです。
@ディップスイッチなど、外部からの信号をマイコンへ入力する場合、端子を「入力」にします。
ALEDなど、マイコンから外部へ信号を出力する場合、端子を「出力」にします。
※PA_0端子は、リセット後はリセット端子です。通常のポートにするには、プログラムで切り替える必要があります。
入出力方向の設定は、「ポートP○方向レジスタ」で行い、レジスタ名は「PD○」となります。○にはポート番号である、1、3、4、Aが入ります。
ポートP○方向レジスタの設定内容を下記に示します。
■ポートP1方向レジスタ(PD1)の設定
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
P1_7 |
P1_6 |
P1_5 |
P1_4 |
P1_3 |
P1_2 |
P1_1 |
P1_0 |
設定 内容 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
1端子 で設定 するとき の名称 |
pd1_7 |
pd1_6 |
pd1_5 |
pd1_4 |
pd1_3 |
pd1_2 |
pd1_1 |
pd1_0 |
|
設定内容は、表のとおり、
@出力にしたい端子のbitには"1"を設定します。
A入力にしたい端子のbitには"0"を設定します。
また、未接続や端子が無い場合は、
B未接続の端子は、出力にしておきます。
C端子が無い場合は、"1"にしておきます。
プログラム例を、下記に示します。
// P1_7を入力、その他を出力にしたい場合(0111 1111を設定)
pd1 = 0x7f; // 0x○○で、16進数
※プログラムでは、レジスタ名を小文字にします。大文字だとエラーになります。
R8Cのコンパイラは、「0b○○○○○○○○」とすると、2進数で指定することもできます(C言語の正式な表記ではありません)。
// P1_3〜P1_0を入力、その他を出力にしたい場合(1111 0000を設定)
pd1 = 0b11110000; // 0b○○○○○○で、2進数
■ポートP3方向レジスタ(PD3)の設定
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
P3_7 |
- |
P3_5 |
P3_4 |
P3_3 |
- |
- |
- |
設定 内容 |
1:出力 0:入力 |
- |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
- |
- |
- |
1端子 で設定 するとき の名称 |
pd3_7 |
- |
pd3_5 |
pd3_4 |
pd3_3 |
- |
- |
- |
|
■ポートP4方向レジスタ(PD4)の設定
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
P4_7 |
P4_6 |
P4_5 |
- |
- |
P4_2 |
- |
- |
設定 内容 |
1:出力 0:入力 |
1:出力 0:入力 |
1:出力 0:入力 |
- |
- |
1:出力 0:入力 |
- |
- |
1端子 で設定 するとき の名称 |
pd4_7 |
pd4_6 |
pd4_5 |
- |
- |
pd4_2 |
- |
- |
|
■ポートPA方向レジスタ(PDA)の設定
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
- |
- |
- |
- |
- |
- |
- |
PA_0 |
設定 内容 |
- |
- |
- |
- |
- |
- |
- |
1:出力 0:入力 |
1端子 で設定 するとき の名称 |
- |
- |
- |
- |
- |
- |
- |
pda_0 |
|
ポートの入出力設定は、init関数(initialize(初期化)の略)で設定しています。今回の入出力設定を下記に示します。
48 : void init( void )
49 : {
50 : /* ポートの入出力設定 */
51 : pd1 = 0xff; /* ポート1の入出力設定 */
52 : pd3 = 0xff; /* ポート3の入出力設定 */
53 : pd4 = 0xff; /* ポート4の入出力設定 */
54 : pda = 0xff; /* ポートAの入出力設定 */
55 : }
■1端子毎に入出力設定する
ポートごとの設定では、複数の端子をいっしょに設定する必要があります。1端子毎に入出力設定することもできます。この場合、「pdx_y=0(入力) or 1(出力) (x=ポート、y=端子)」と指定すると、1端子毎に設定することが出来ます。
// P1_3端子を入力に設定
pd1_3 = 0;
出力端子から"0"(0V)または"1"(5V)を出力
電圧の出力は、「ポートP○レジスタ」で行い、レジスタ名は「P○」となります。○にはポート番号である、1、3、4、Aが入ります。
ポートP○レジスタの設定内容を下記に示します。
@端子から"1"(5V)を出力したい場合は、"1"を設定します。
A端子から"0"(0V)を出力したい場合は、"0"を設定します。
B入力端子は、"0"、"1"のどちらを設定しても構いません。
C端子が無い場合は、"0"を設定します。
■ポートP1レジスタ(P1)の詳細
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
P1_7 |
P1_6 |
P1_5 |
P1_4 |
P1_3 |
P1_2 |
P1_1 |
P1_0 |
設定 内容 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1端子 で設定 するとき の名称 |
p1_7 |
p1_6 |
p1_5 |
p1_4 |
p1_3 |
p1_2 |
p1_1 |
p1_0 |
|
例えば、P1から次の電圧を出力することとします(PD1=0xffの状態とします)。
bit |
P1_7 |
P1_6 |
P1_5 |
P1_4 |
P1_3 |
P1_2 |
P1_1 |
P1_0 |
出力値 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
|
このとき、下記のプログラムを実行します。
p1 = 0xa5; // P1に0xa5(0b10100101)を出力する
■ポートP3レジスタ(P3)の詳細
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
P3_7 |
- |
P3_5 |
P3_4 |
P3_3 |
- |
- |
- |
設定 内容 |
1:5V出力 0:0V出力 |
- |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
- |
- |
- |
1端子 で設定 するとき の名称 |
p3_7 |
- |
p3_5 |
p3_4 |
p3_3 |
- |
- |
- |
|
■ポートP4レジスタ(P4)の詳細
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
P4_7 |
P4_6 |
P4_5 |
- |
- |
P4_2 |
- |
- |
設定 内容 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
1:5V出力 0:0V出力 |
- |
- |
1:5V出力 0:0V出力 |
- |
- |
1端子 で設定 するとき の名称 |
p4_7 |
p4_6 |
p4_5 |
- |
- |
p4_2 |
- |
- |
|
■ポートPAレジスタ(PA)の詳細
bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
端子 |
- |
- |
- |
- |
- |
- |
- |
PA_0 |
設定 内容 |
- |
- |
- |
- |
- |
- |
- |
1:5V出力 0:0V出力 |
1端子 で設定 するとき の名称 |
- |
- |
- |
- |
- |
- |
- |
pa_0 |
|
■1端子毎に電圧を出力する
1端子毎に電圧を出力することもできます。この場合、「px_y=1(5V出力) or 0(0V出力) (x=ポート、y=端子)」と指定すると、1端子毎に状態を出力することができます。
p3_7 = 1; // P3_7端子から5Vを出力
入力端子の入力電圧(0Vか5Vか)を確認する
ポートの入出力設定で入力に設定した端子の電圧(0Vが入力されているのか、5Vが入力されているのか)を確認するには、、「ポートP○レジスタ」で行い、レジスタ名は「P○」となります。○にはポート番号である、1、3、4、Aが入ります(出力と同様です)。
ポートP○レジスタから読み出される値を下記に示します。
@端子に5Vが入力されているなら、"1"が読み込まれます。
A端子に0Vが入力されているなら、"0"が読み込まれます。
B出力端子を読み込むと、現在出力している状態が読み込まれます。
C端子が無い場合は、不定("0"か"1"か分からない状態)が読み込まれます。
例えば、P1には次の電圧が入力されているとします(PD1=0x0fの状態とします)。
bit |
P1_7 |
P1_6 |
P1_5 |
P1_4 |
P1_3 |
P1_2 |
P1_1 |
P1_0 |
入出力 |
5Vが 入力 |
5Vが 入力 |
0Vが 入力 |
0Vが 入力 |
0Vを 出力 |
0Vを 出力 |
5Vを 出力 |
5Vを 出力 |
読み込んだときの値 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
|
このとき、下記のプログラムを実行したとします。
unsigned char c;
中略
// P1の状態を読み込み
c = p1; // cには0xc3(0b11000011)が代入される
※プログラムでは、レジスタ名を小文字にします。大文字だとエラーになります。
■端子毎に状態を入力する
端子毎に入力状態を確認することもできます。この場合、「px_y (x=ポート、y=端子)」と指定すると、端子毎に設定することが出来ます。
// P4_3端子の状態を確認
c = p4_3; // 0Vが入力されていたら、c=0
// 5Vが入力されていたら、c=1
タイマ
下記のプログラムを実行したとします。
while( 1 ) {
p1 = 0xff; // ←実行時間:数us
p1 = 0x00; // ←実行時間:数us
}
0xff(P1のbit7〜0のLED点灯)と、0x00(P1のbit7〜0のLED消灯)を繰り返すはず・・・ ですが、ずっとLEDが点灯しているように見えます。実際には、点灯、消灯を繰り返しているのですが、1行の実行時間は数μsなので、人間には速すぎて見えないのです。よって、「p1 = 0xff;」を実行した後と、「p1 = 0x00;」を実行した後に、実行を一時停止するタイマを入れます(ここでは例として1秒で説明します)。プログラムの考え方を下記に示します。
while( 1 ) {
p1 = 0xff; // ←実行時間:数us
1秒間、この行で停止
p1 = 0x00; // ←実行時間:数us
1秒間、この行で停止
}
この、「○秒間、この行で停止」を実現するのがtimer関数です。timer関数を下記に示します。
61 : void timer( unsigned long timer_set )
62 : {
63 : int i;
64 :
65 : do {
66 : for( i=0; i<871; i++ ); ←これで1ms間の時間稼ぎ
67 : } while( timer_set-- ); ←66行をtimer_set回、繰り返す
68 : }
timer関数は、何もしないことを繰り返して、時間稼ぎをします。使い方は「timer( 時間 );」で、時間はミリ秒単位で指定します。1秒なら、「timer( 1000 );」とします。
メインプログラム
led.cのmain関数のプログラムを、下記に示します。
31 : void main( void )
32 : {
33 : init(); /* 初期化 */
34 :
35 : while( 1 ) {
36 : p1 = 0b00001111; ←LEDに出力
37 : timer( 1000 ); ←1000msの時間稼ぎ
38 : p1 = 0b11110000; ←LEDに出力
39 : timer( 1000 ); ←1000msの時間稼ぎ
40 : p1 = 0b00000000; ←LED 全消灯
41 : timer( 1000 ); ←1000msの時間稼ぎ
42 : }
43 : }
ポート1に接続されているLED 8個を1秒間「0000 1111」で点灯、1秒間「1111 0000」で点灯、1秒間全消灯」、これを無限ループで繰り返します。
課題
1.次のパターンで点灯するプログラムを書きなさい。(1…点灯 0…消灯)
@ 「1000 0001」を0.5秒点灯
A 「1100 0011」を0.5秒点灯
B 「1110 0111」を0.5秒点灯
C 「1111 1111」を0.5秒点灯
D 「0000 0000」を1秒点灯
E @に戻って繰り返す
2.次のパターンで点灯するプログラムを書きなさい。(1…点灯 0…消灯)
@ 「0000 0001」を0.2秒点灯
A 「0000 0010」を0.2秒点灯
B 「0000 0100」を0.2秒点灯
:
G 「1000 0000」を0.2秒点灯
H @に戻って繰り返す
3.for文を使って、0〜255をカウントするループを作り、カウント値をLEDに出力するプログラムを作りなさい。出力する間隔は、0.2秒とする。また、255の次は0に戻って、出力し続けるものとする。
4.for文を使って、2番目の課題と同じ動作をするようにプログラムを作りなさい。
ヒント:10進数にすると点灯する値は、1、2、4、8・・・ となる
課題の回答例
1.の回答例
→ led_answer_1.c
2.の回答例
→ led_answer_2.c
3.の回答例
→ led_answer_3.c
4.の回答例
→ led_answer_4.c
|