H8S C言語によるプログラム開発(H8S 2345で説明)
1.ファイル構成
2345s.H H8S/2345のハードウエアに関するアドレスなど定義
vect.src リセットベクタ、割込みベクタを定義するアッセンブリファイル
init.c スタックポインタ設定、初期化、main()へジャンプ
initsct.c init.cから呼ばれる。 (変数のRAMへの配置、変数の初期化(0を書込))
main.c ユーザプログラム
linkfile.sub サブコマンドファイル:リンク時のメモリ配置を定義
makefile コンパイル・リンク手順を定義
上記ファイルを作成し、makefileを実行することで ○○○.absファイルを作成する。
2.各ファイルの説明
(1)ヘッダーファイル(2345s.H、○○.H)
1) char型は signed char となる。
コンパイラによっては,charはunsigned としているものもあるので注意する。
2) ビットフールド(bit操作命令)を用いて出力する場合、bit操作命令は一度読込みをして
から対象bitを変更し出力するので、書込みONLYのレジスタ(DDR)等には使用禁止。
(2)vect.src
1) C言語で書かれた関数名は、アッセンブラでは関数名の前に'_'(アンダースコア)を付ける。
2)割込みベクタにジャンプ先の関数名のアドレスを入れる。
(3)initsct.c
1)セクション
セクション 内 容 説 明
P (ROM) プログラム領域 コードが配置される
C (ROM) const 定数領域 値の変化しない定数
D (ROM) 初期値付変数 セクションXにコピーして用いる
B (RAM) 初期値の無い変数 初期値は0とする
X (RAM) 初期値付変数 セクションDからコピーされ配置
2)初期値付変数
H8S では初期値はROM領域にあり、プログラムでRAM領域にコピーして使用する
3)割込みマスク
set_imask_exr(0) 0番より大きい番号の割込みを受け付ける。
set_imask_exr(7) 7番より大きい番号の割込みを受け付ける。
これはNMI のみなので、割込み禁止と同意となる。
4)_secttop("D"),_sectend("D")
セクションの始まりと終わりを得る特別な関数(この場合は,"D"セクション)
初期値付変数のコピーと初期値なし変数のクリアを行う。
(4)main.c
ユーザプログラム
(5)linkfile.sub
1)リンクするオブジェクトファイル ○○.obj を列記する
2)コード、DATA領域の先頭番地を定義する。
3)初期値付変数処理のセクション名を定義する。
(6)makefile
コンパイラの手順を記述し、変更のあった部分のみを再コンパイルしリンクする。
3.割込み制御
(1)割込み手続き
1)割込みベクタの設定
VEXT.SRC にて割込みベクタに割込み関数のアドレスを指定する
Exsample:
.CPU 2000a
.IMPORT _INIT
.IMPORT _tpu3
.IMPORT _sci1err
.IMPORT _sci1
.SECTION VECT,DATA,LOCATE=H'000000
.DATA.L _INIT ;RESET VECT
.ORG H'0000C0 ;CH3
.DATA.L _tpu3 ;imia0 VECT
.ORG H'000150
.DATA.L _sci1err ;sci1 err VECT
.ORG H'000154
.DATA.L _sci1 ;sci1 receive VECT
.END
2)割込みコントローラ
割込みモードの設定 :SYSCR システムコントロールレジスタ
割込みレベル(優先順位)の指定 :IPRA~IPRKインタラプトプライオリティレジスタ
Exsample:
SYSCR.BIT.INTM=2; /* モード2 割込み */
INTC.IPRG.BIT.LOW = 3; /* tpu3 priority level 3 */
INTC.IPRK.BIT.HIGH = 5; /* sci1 priority level 5 */
3)周辺I/Oのイニシャライズ
Exsample: 10msタイマー割込み
void inittpu3(void)
{
MSTPCR.BIT.B13 = 0; /* start TPU */
TPU.TSYR.BYTE = 0; /* no sync */
TPU3.TMDR.BYTE = 0; /* nomal mode */
TPU3.TIOR.WORD = 0; /* non output */
TPU3.TCNT = 0; /* counter= 0 */
TPU3.TCR.BYTE = 0x23; /* TGRAでクリア,up count,Φ/64 */
TPU3.TGRA = 3124; /* 20e6/(64*3125)=100Hz */
TPU3.TIER.BIT.TGIEA = 1; /* enable TGFA */
TPU.TSTR.BIT.CST3= 1; /* start TPU3 */
}
Exsample:SCI受信割込み
void initsci1(void)
{ int i;
MSTPCR.BIT.B6 = 0; /* Module start SCI1 */
SCI1.SCR.BYTE = 0x00; /* stop SCI1 */
SCI1.SMR.BYTE = 0x00; /* Async 9600,8,1 */
SCI1.SCMR.BYTE = 0x00; /* LSB first */
SCI1.BRR = 64; /* 9600 */
for(i= 0i<511;i++);
SCI1.SCR.BYTE = 0x70; /* 受信割込、送受信可 */
SCI1.SSR.BIT.ORER = 0; /* オーバーランエラークリア */
SCI1.SSR.BYTE = 0x80; /* clear errer flag */
}
4)割込み関数の作成
#pragma interrupt(関数名)で割込み関数と認識する
Exsampl:10ms割込み
#pragma interrupt(tpu3)
void tpu3(void)
{ TPU3.TSR.BIT.TGFA = 0; /* clar TGFA */
Count_10m++;
if(Count_10m >= 10)
{ Count_100m++; /* 0.1s */
Count_10m = 0;
task100m(); /* 100msecごとの仕事 */
}
if(Count_100m >= 10)
{ Count_1s++; /* 1s */
Count_100m = 0;
}
timerint();
}
4.その他の留意点
(1)コンパイラオプション( makefile参照 :これから掲載)
init.obj: init.c ea0020.h
ch38 -cpu=2000a -deb -g -sh=o -op=0
cpu 2000a :H8S/2000 アドバンストモード
deb :デバッグ情報出力
g :モジュール間最適化
sh=o :リスト内容はオブジェクト情報有り
op=0 :最適化なしのオブジェクトを出力