H8サンプルプログラム-その1
CPUボード:RY3048Fone を使って、制御対象回路として「ものづくり kumamoto Ver.01」を制御するサンプルプログラムを作ります。
LED3~LED10の点灯、スイッチ入力を制御します。小さなテーマの集まりですが、対象としているハードウェアの接続(ケーブル、回路内のすべて)を確認しながら進めてください。その一つひとつがプログラムの力になります。
■テーマ概要
・制御のヒント
PA.DR.BYTE → 0xff or ~0x00 = LED3~LED10の点灯
PA.DR.BIT.B0 → LED3 = 0:点灯、1:消灯
PA.DR.BIT.B1 → LED4 = 0:点灯、1:消灯
PA.DR.BIT.B2 → LED5 = 0:点灯、1:消灯
PA.DR.BIT.B3 → LED6 = 0:点灯、1:消灯
PA.DR.BIT.B4 → LED7 = 0:点灯、1:消灯
PA.DR.BIT.B5 → LED8 = 0:点灯、1:消灯
PA.DR.BIT.B6 → LED9 = 0:点灯、1:消灯
PA.DR.BIT.B7 → LED10 = 0:点灯、1:消灯
・テーマは、次の通りです。
1)全LEDを点灯する。
2)全LEDを消灯する。
3)LED3だけを点灯する。
4)LED4だけを点灯する。
5)LED5だけを点灯する。
6)LED6だけを点灯する。
7)LED7だけを点灯する。
8)LED8だけを点灯する。
9)LED9だけを点灯する。
10)LED10だけを点灯する。
11)SW1(トグルスイッチ)で全LEDを点灯~消灯する。
レバー上向きでオン~LED点灯、下向きでオフ~LED消灯とする。
12)SW2(プッシュスイッチ)で全LEDを点灯~消灯する。
押してオン~LED点灯、放してオフ~LED消灯とする。
13)SW3(透過センサー)で全LEDを点灯~消灯する。
透過でオン~LED点灯、遮光でオフ~LED消灯とする。
14)SW2(プッシュスイッチ)でLEDの点灯をシフトする。
15)SW3(透過センサー)でLEDの点灯をシフトする。
注:この時、7セグメントLEDは全消灯とする。
■接続
制御対象回路 CPUボード:RY3048Fone
CN1 → J2
CN2 → J3
J1 → トグルスイッチ、プッシュスイッチ、透過センサー
■開発環境
ルネサスエレクトロニクス社 High-performance Embedded Workshop を使います。
最新版をルネサスエレクトロニクス社のホームページよりダウンロードしてセットアップしてください。
■準備-その1
ヘッダファイルを用意します。
ファイル名:ry3048fone.h
フォルダー:自分の開発環境に合わせる。
ヘッダファイルの内容は、次の通り。
---この次から---
void InitializeIO(void);
int GetSW1(void);
int GetSW2(void);
int GetSW3(void);
#define LED_AL_OFF 0xff
#define LED_AL_ON 0x00
#define OE_ENABLE 0
#define OE_DISABLE 1
#define LED7SEG_ALL PA.DR.BYTE
#define OE_7SEG PB.DR.BIT.B7
#define OE_LED PB.DR.BIT.B6
#define SW1 P7.DR.BIT.B1
#define SW2 P7.DR.BIT.B3
#define SW3 P7.DR.BIT.B5
#define SW_ON 0
#define SW_OFF 1
void InitializeIO(void)
{
/* 入出力端子の定義 */
PA.DR.BYTE = 0;
PA.DDR = 0xff;
PA.DR.BYTE = LED_AL_OFF;
PB.DR.BYTE = 0;
PB.DDR = 0xff;
}
int GetSW1(void)
{
return( SW1 );
}
int GetSW2(void)
{
return( SW2 );
}
int GetSW3(void)
{
return( SW3 );
}
---この前まで---
■準備-その2
サンプル用のスタータプログラム(アセンブラ)を用意します。
ファイル名:demo01start.src
フォルダー:プロジェクト指定のフォルダー
---この次から---
.CPU 300HA:20
STACK_BASE: .EQU H'FFFF10 ; スタック基底アドレス(モード7)
.IMPORT _main ; 外部参照(main関数)
.SECTION V ; H'000000
.DATA.L RESET_START
.SECTION P ; H'000100
RESET_START:
MOV.L #STACK_BASE,ER7 ; スタックの設定
JSR @_main ; C言語のmain()関数へジャンプ
OWARI:
BRA OWARI
.END
---この前まで---
注:このファイル(拡張子が「src」)は、これまで作成してきた中に入っています。それをそのまま、ファイル名を変えて利用されても構いません。
■準備-その3
サンプル用のソースプログラムファイル(C言語)を用意します。
ファイル名:demo01.c
フォルダー:プロジェクト指定のフォルダー
注:この時、7セグメントLEDは全消灯とする。
---この次から---
#include "3048f.h"
#include "ry3048fone.h"
void main(void);
void main(void)
{
/* ローカル変数の定義 */
unsigned char LedShifted;
int DuringON;
/* 処理 */
InitializeIO();
OE_7SEG = OE_DISABLE;
OE_LED = OE_ENABLE;
/*ここにサンプルプログラムを書く*/
}
---この前まで---
それでは、次に「/*ここにサンプルプログラムを書く*/」のところに、実際にプログラムを書いてみましょう。
■サンプルプログラムの作成
1)全LEDを点灯する。
LED7SEG_ALL = LED_AL_ON;
これで全LEDが点灯(し続け)ます。
2)全LEDを消灯する。
LED7SEG_ALL = LED_AL_OFF;
全LED消灯(し続け)ます。
3)LED3だけを点灯する。
LED7SEG_ALL = ~0x01;
PA.DR.BIT.B0だけを「0」にして、LED3を点灯(し続け)ます。
LED3だけを消灯させたい時は、チルダ「~」を外します。
4)LED4だけを点灯する。
LED7SEG_ALL = ~0x02;
PA.DR.BIT.B1だけを「0」にして、LED4を点灯(し続け)ます。
LED4だけを消灯させたい時は、チルダ「~」を外します。
5)LED5だけを点灯する。
LED7SEG_ALL = ~0x04;
PA.DR.BIT.B2だけを「0」にして、LED5を点灯(し続け)ます。
LED5だけを消灯させたい時は、チルダ「~」を外します。
6)LED6だけを点灯する。
LED7SEG_ALL = ~0x08;
PA.DR.BIT.B3だけを「0」にして、LED6を点灯(し続け)ます。
LED6だけを消灯させたい時は、チルダ「~」を外します。
7)LED7だけを点灯する。
LED7SEG_ALL = ~0x10;
PA.DR.BIT.B4だけを「0」にして、LED7を点灯(し続け)ます。
LED7だけを消灯させたい時は、チルダ「~」を外します。
8)LED8だけを点灯する。
LED7SEG_ALL = ~0x20;
PA.DR.BIT.B5だけを「0」にして、LED8を点灯(し続け)ます。
LED8だけを消灯させたい時は、チルダ「~」を外します。
9)LED9だけを点灯する。
LED7SEG_ALL = ~0x40;
PA.DR.BIT.B6だけを「0」にして、LED9を点灯(し続け)ます。
LED9だけを消灯させたい時は、チルダ「~」を外します。
10)LED10だけを点灯する。
LED7SEG_ALL = ~0x80;
PA.DR.BIT.B7だけを「0」にして、LED10を点灯(し続け)ます。
LED10だけを消灯させたい時は、チルダ「~」を外します。
11)SW1(トグルスイッチ)で全LEDを点灯~消灯する。
レバー上向きでオン~LED点灯、下向きでオフ~LED消灯とする。
for(;;){
if( GetSW1() == SW_ON ) LED7SEG_ALL = LED_AL_ON;
else LED7SEG_ALL = LED_AL_OFF;
}
12)SW2(プッシュスイッチ)で全LEDを点灯~消灯する。
押してオン~LED点灯、放してオフ~LED消灯とする。
for(;;){
if( GetSW3() == SW_ON ) LED7SEG_ALL = LED_AL_ON;
else LED7SEG_ALL = LED_AL_OFF;
}
13)SW3(透過センサー)で全LEDを点灯~消灯する。
透過でオン~LED点灯、遮光でオフ~LED消灯とする。
for(;;){
if( GetSW3() == SW_ON ) LED7SEG_ALL = LED_AL_ON;
else LED7SEG_ALL = LED_AL_OFF;
}
14)SW2(プッシュスイッチ)でLEDの点灯をシフトする。
初期状態がSW1がオンの時、LED3のみが点灯し、SW2を一回押下すると次にLED4が点灯する。
SW2を押下する毎に以後、一つずつLEDの点灯が(左)シフトする。
LED10迄到達したら、次の押下でLED3に戻り、以後これを繰り返す。
初期状態がSW1がオフの時、LED10のみが点灯し、SW2を一回押下すると次にLED9が点灯する。
SW2を押下する毎に以後、一つずつLEDの点灯が(右)シフトする。
LED3迄到達したら、次の押下でLED10に戻り、以後これを繰り返す。
処理途中で、SW1のオン、オフを切り替えると、
オンの時は、SW2の操作でLEDの点灯が左シフトし、
オフの時は、SW2の操作でLEDの点灯が右シフトする。
注:この処理では、スイッチのチャタリングが影響し、LEDのシフト点灯が旨くいかない時がある。
オン状態を確実にするため、フラグ「DuringON」を使ったが、もう少し工夫が必要と思われる。
if( GetSW1() == SW_ON ) LedShifted = 0x01;
else LedShifted = 0x08;
DuringON = False;
for(;;){
if( GetSW2() == SW_ON && DuringON == False ){
DuringON = True;
if( GetSW1() == SW_ON ){
if( LedShifted == 0x80 ) LedShifted = 0x01;
else LedShifted = LedShifted << 1;
} else {
if( LedShifted == 0x01 ) LedShifted = 0x80;
else LedShifted = LedShifted >> 1;
}
}
if( GetSW2() != SW_ON ) DuringON = False;
LED7SEG_ALL = ~LedShifted;
}
15)SW3(透過センサー)でLEDの点灯をシフトする。
初期状態がSW1がオンの時、LED3のみが点灯し、SW3を一回遮光すると次にLED4が点灯する。
SW3を遮光する毎に以後、一つずつLEDの点灯が(左)シフトする。
LED10迄到達したら、次の遮光でLED3に戻り、以後これを繰り返す。
初期状態がSW1がオフの時、LED10のみが点灯し、SW3を一回遮光すると次にLED9が点灯する。
SW3を遮光する毎に以後、一つずつLEDの点灯が(右)シフトする。
LED3迄到達したら、次の遮光でLED10に戻り、以後これを繰り返す。
処理途中で、SW1のオン、オフを切り替えると、
オンの時は、SW3の操作でLEDの点灯が左シフトし、
オフの時は、SW3の操作でLEDの点灯が右シフトする。
注:透過センサーでは、プッシュスイッチの様なチャタリングがないので、LEDのシフト点灯は、この処
理で問題なく動作する。只、スイッチの操作で初期状態として、遮光(オフ状態)から入るか、透過
(オン状態)から入るかを決めないといけない。
SW2の時の初期状態と同様に、(SW1をオン状態のままとした時) LedShifted を 0x01 として、
透過(オン状態)から入ると、電源投入時、シフト処理が一回入る為、LED4から点灯開始となる。こ
れを回避するには、LedShifted を 0x80 から始めるとよい。初期状態が透過(オン状態)なので、
その最初のシフト処理を通り、LedShifted が 0x80→0x01 となって、最初の点灯がLED3となる。
if( GetSW1() == SW_ON ) LedShifted = 0x80;
else LedShifted = 0x01;
DuringON = False;
for(;;){
if( GetSW3() == SW_ON && DuringON == False ){
DuringON = True;
if( GetSW1() == SW_ON ){
if( LedShifted == 0x80 ) LedShifted = 0x01;
else LedShifted = LedShifted << 1;
} else {
if( LedShifted == 0x01 ) LedShifted = 0x80;
else LedShifted = LedShifted >> 1;
}
}
if( GetSW3() != SW_ON ) DuringON = False;
LED7SEG_ALL = ~LedShifted;
}