3. プログラムをつくろう
3.4 ソースファイルの作成と編集
以下の手順でソースファイルを作成してください。C言語プログラム、アセンブラ言語プログラムの各ファイル は、作成後にプロジェクトに登録する必要があります。
①
① ファイルの新規作成と保存
PM plus の新規作成アイコン をクリックするか、「ファイル」メニューより「新規作成」をクリックして ください。新しいファイルがエディタによって開きます。
保存は保存アイコン をクリックするか、「ファイル」メニューより「名前を付けて保存」をクリックし、ファ イル名を指定して保存してください。アセンブラ言語のプログラムは拡張子「.asm」、C 言語のプログラム は拡張子「.c」を付けてください。
新規作成アイコン、保存アイコン
②
① ファイルのプロジェクトへの登録
作成したファイルや、あらかじめコピーしておいたファイルはプロジェクトに登録する必要があります。
「ProjectWindow」の「ソース・ファイル」を右クリックして「ソース・ファイルの追加」をクリックして 作成したソースファイルを登録します。
+をクリックすると登録されたファイル名、関数が表示されます
図3-12 PM plus : プロジェクトへの登録
■option.asm
78K0/Kx2
マイコンは、リセット解除後にフラッシュメモリの0080H-0084H
を読み出して、マイコン動作の基 本となる機能の初期設定を行います。この初期値を格納する領域を「オプション・バイト領域」といいます。オプ ション・バイト領域の参照の後にリセットベクタに設定されたアドレスからプログラムを実行します。以下に各アドレスに設定される内容を示します。
①
① 0080H
・低速内蔵発振器の動作
→「ソフトウェアにより停止可能」に設定します
・ウォッチドッグタイマのオーバーフロー時間の設定
→「オーバーフロー時間= 3.88ms」に設定します(ウォッチドッグタイマは停止設定のため関係ない)
・ウォッチドッグタイマのカウンタの動作の設定 →「ウォッチドッグタイマ動作=停止」に設定します
・ウォッチドッグタイマのウインドウ・オープン期間の設定
→「ウィンドウ・オープン時間= 25%」に設定します(ウォッチドッグタイマは停止設定のため関係ない)
②
① 0081H
・POC モードの選択
→「1.59V POC モード(デフォルト)」に設定します
③
① 0082H-0083H
・予約領域(必ず 00H を設定してください)
④
① 0084H
・オンチップデバッグ動作制御
→「オンチップデバッグ動作=動作禁止」に設定します
option.asm
(オプション・バイトの設定)OPT_SET CSEG AT 80H
OPTION: DB 00000000B ;オプション・バイトの設定
; ||||||||
; |||||||+---低速内蔵発振器はソフトウェアで停止可能
; ||||+++---ウォッチドッグタイマのオーバーフロー時間は3.88ms
; |||+---ウォッチドッグタイマのカウンタ動作禁止
; |++---ウォッチドッグタイマのウインドウオープン時間は25%
; +---0固定(予約領域)
DB 00000000B ;POCモードの選択設定
; ||||||||
; |||||||+---1.59V POCモード(デフォルト)
; +++++++---0固定(予約領域)
DB 00000000B ;00H固定(予約領域)
DB 00000000B ;00H固定(予約領域)
ONC_SET CSEG AT 84H
ONCHIP: DB 00000000B ;オンチップデバッグ動作制御
; ||||||||
; ||||||++---動作禁止
; ++++++---0固定(予約領域)
①
②
③
④
■initial.c
標準のスタートアップルーチンに合わせて、hdwinit 関数を作成します。ここではファイル名は initial.c とします。
hdwinit 関数ではメモリサイズの切り替え、クロック、ポート、タイマの設定を行います。
①
① メモリサイズの切り替え
使用するマイコンに合わせて「メモリ・サイズ切り替えレジスタ(IMS)」と「内部拡張 RAM サイズ切り替 えレジスタ(IXS)」を設定します。使用するマイコンの ROM 容量と内部拡張 RAM 容量にしたがって設定 してください。(必ず IMS を設定したあとに、IXS を設定してください。)
②
① クロックの設定
メインシステムクロックを高速システムクロック回路の X1(外付けセラミック発振子)をプリスケーラに よる分周なし(20MHz)にする設定を行います。(78K0/Kx2 マイコンは、リセット解除後は高速内蔵発振 回路(8MHz TYP.)がメインシステムクロックとなります。)
また、サブシステムクロックは XT1(外付け水晶発振子(32.768KHz))を使用する設定とします。
③
① ポートの設定
LED に接続するポートのレジスタに初期値を設定し、方向レジスタに出力ポートとする設定をします。
入出力ポートを出力に設定する前に、必ずポートのレジスタには所定の値を設定し、出力に設定したときに 不定な値がマイコンから出力されないようにします。
④
① タイマの設定
タイマは、16 ビットタイマ 00 を使って 200m 秒を計測することとします。タイマのソースクロックは、シ ステムクロックを 256 分周(78.125KHz:1 分周 =0.0000128 秒)したものを供給し、15625 回カウントして 200m 秒を計測することとします(0.2 ÷ 0.0000128 = 15625)。
また、タイマ割り込み機能は使用しないで、割り込み要求フラグを検知することで計測します。
タイマを開始する設定は、全ての初期設定の一番最後にします。(メインプログラム中で行ってもかまいま せん。)
initial.c
(初期化処理)-1
* ファイル名 :initial.c
* プロジェクト名 :LED_PICOPICO
* ターゲットマイコン :78K0/KE2(μPD78F0537) * ターゲットボード :ReferSTAR78K(CT-781)
* 仕様 :マイコンリソースの初期化を行う
---*/
前処理指令(#pragma指令)
---*/
#pragma SFR /* 特殊機能レジスタ(SFR)名を記述可能にする */
プロトタイプ宣言
---*/
void clock_init(void); /* クロック設定の初期化 */
void port_init(void); /* ポート設定の初期化 */
void timer00_init(void); /* タイマ00設定の初期化 */
* 関数名 :hdwinit
* 機能 :初期化処理(標準スタートアップルーチンから呼びだされる)
* 引数 :なし * 返り値 :なし * 注意事項 :なし
---*/
void hdwinit(void) {
IMS = 0xCC; /* メモリサイズを128kByteに設定 */
IXS = 0x00; /* 内部拡張RAMサイズを6kByteに設定 */
clock_init(); /* クロック設定の初期化 */
port_init(); /* ポート設定の初期化 */
timer00_init(); /* タイマ00設定の初期化 */
}
①
リスト3-3 : 初期化設定ルーチン -1
マイコンのSFRのシンボル名について
コンパイラ CC78K0 の拡張機能 #pragma SFR を設定することで、78K0S/Kx2 マイコンの各機能のレジスタなどのシンボル 名をプログラム中に記述することができます。PM plus のテキスト・エディタでシンボル名を入力すると、文字色が SFR のシン ボルを表す色になります(デフォルトで青色)。
各シンボル名は、「78K0S/Kx2 ユーザーズマニュアル」(NEC エレクトロニクス社発行)に記述されている略号と同じです。
例:16 ビット・タイマ・モード・コントロール・レジスタ 00(TMC00)のフォーマット図
0 0 0 0 TMC003 TMC002 TMC001 OVF00
7 6 5 4 3 2 1 0 TMC00
略号
アドレス:FFBAH リセット時:00H R/W
initial.c
(初期化処理)-2* 関数名 :clock_init
* 機能 :クロック設定の初期化
* 引数 :なし
* 返り値 :なし
* 注意事項 :なし
---*/
void clock_init(void) {
unsigned char temp_ostc;
/* メインクロックの設定 */
OSTS = 0x05; /* 発振安定時間を3.27ms(fx=20MHz)に設定 */
OSCCTL = 0x41; /* クロック動作モードをX1発振モード、10〜20MHz動作に設定 */
MSTOP = 0; /* 高速システムクロックの動作制御:X1発振回路動作 */
do { /* 発振安定時間の経過を確認する */
temp_ostc = OSTC; /* 発振安定時間カウント(OSTC)を取得 */
temp_ostc &= 0x1F; /* カウント値以外のBitを除去 */
} while (temp_ostc != 0x1F); /* 発振安定時間は未経過? */
MCM = 0x05; /* メイン&周辺クロックを高速システムクロックに設定 */
RSTOP = 1; /* 高速内蔵発振器を停止に設定 */
/* サブクロックの設定 */
OSCCTL |= 0x10; /* クロック動作モードをXT1発振モードに設定 */
XTSTART = 0; /* XT1発振回路動作 */
PCC &= ~0x17; /* CPUクロックの選択(fxpに設定) */
LSRSTOP = 1; /* 低速内蔵発振回路停止 */
}
* 関数名 :port_init
* 機能 :ポート設定の初期化
* 引数 :なし
* 返り値 :なし
* 注意事項 :なし
---*/
void port_init(void) {
P0 = 0b00000010; /* 初期値をP00,P01に初期値を設定 */
PM0 = 0b11111100; /* P00,P01を出力に設定 */
}
* 関数名 :timer00_init
* 機能 :タイマ00設定の初期化
* 引数 :なし
* 返り値 :なし
* 注意事項 :なし
---*/
void timer00_init(void) {
TMC00 = 0b00000000; /* タイマ0を機能停止に設定 */
TMMK000 = 1; /* 割り込み処理の禁止(1)を設定 */
TMIF000 = 0; /* 割り込み要求フラグをクリア(0:要求無し) */
PRM00 = 0b00000010; /* システムクロック20MHzを256分周したものをカウントクロックとする */
CRC00 = 0b00000000; /* コンペアレジスタCR000をコンペアレジスタとして使用する */
②
③
④
■main.c
標準のスタートアップルーチンに合わせて、main関数を作成します。main関数では、タイマ
00
の割り込み要 求フラグ(TMIF000)を検知し、200m秒を5
回カウントして1
秒ごとにポートの値を反転します。main.c
(メイン関数)-1
* ファイル名 :main.c
* プロジェクト名 :LED_PICOPICO
* ターゲットマイコン :78K0/KE2(μPD78F0537) * ターゲットボード :ReferSTAR78K(CT-781)
* 仕様 :LEDを1秒ごとに交互に点滅させる
---*/
前処理指令(#pragma指令)
---*/
#pragma SFR /* 特殊機能レジスタ(SFR)名を記述可能にする */
#pragma EI /* EI命令を記述可能にする */
マクロ名定義
---*/
#define LED1 (P0.0) /* ポート0の0ビット目を定義 */
#define LED2 (P0.1) /* ポート0の1ビット目を定義 */
#define TRUE (1)
#define FALSE (0)
プロトタイプ宣言
---*/
static char count_1sec(void); /* タイマ00の割り込み要求フラグをポーリングで検知して1秒を計測する */
static void led_blink(void); /* ポートの状態を反転して出力する関数 */
* 関数名 :main
* 機能 :1秒毎にLEDを点滅させる
* 引数 :なし
* 返り値 :なし
* 注意事項 :なし
---*/
void main(void){
EI(); /* ベクタ割り込み許可 */
while(1){ /* 無限ループ */
if (count_1sec() == TRUE){ /* 1秒経過? */
led_blink(); /* ポートレジスタの値を反転(LED点滅) */
} } }
リスト3-5 : メインルーチン-1
main.c
(メイン関数)-2* 関数名 :count_1sec
* 機能 :タイマ00割り込み要求フラグをポーリングして1秒経てばTRUEを返す
* 引数 :なし
* 返り値 :TRUE,FALSE
* 注意事項 :なし
---*/
static char count_1sec(void){
static unsigned char counter_1sec = 0; /* 1秒計測用カウンタ */
if (TMIF000 == 1){ /* タイマ00割り込み要求フラグが1か?(200ms経過)*/
TMIF000 = 0; /* タイマ00割り込み要求フラグをクリア */
counter_1sec ++; /* 1秒計測タイマをインクリメント */
if (counter_1sec >= 5){ /* 1秒計測タイマが5以上か?(200ms×5=1秒) */
counter_1sec = 0; /* 1秒計測タイマをクリア */
return (TRUE); /* 1秒経過を通知(真を返す) */
} }
return (FALSE); /* 1秒見経過を通知(偽を返す) */
}
* 関数名 :led_blink
* 機能 :LEDを点灯⇔消灯させる
* 引数 :なし
* 返り値 :なし
* 注意事項 :なし
---*/
static void led_blink(void){
LED1 = ~LED1; /* LED1の出力を反転 */
LED2 = ~LED2; /* LED2の出力を反転 */
}
リスト3-6 : メインルーチン-2