Skip to content

Instantly share code, notes, and snippets.

@erutuf
Created February 16, 2011 15:55
Show Gist options
  • Save erutuf/829601 to your computer and use it in GitHub Desktop.
Save erutuf/829601 to your computer and use it in GitHub Desktop.
\documentclass{jarticle}
%\usepackage[dvips]{graphicx}
\setlength{\textwidth}{150mm}
\setlength{\textheight}{232mm}
\setlength{\oddsidemargin}{5mm}
\setlength{\topmargin}{5mm}
\begin{document}
\section{目的}
H8マイコンの割り込みについて理解を深め、割り込み制御をC言語で記述する方法を学ぶ。
\section{原理}
一般に、マイコンに接続される機器の状態は、マイコンの処理とは無関係に変化する。
また、接続される機器の状態変化は、マイコンの処理速度に比べてかなり遅い。
そのため、マイコンを使って機器を制御するためには、機器の状態を常に監視しながら、
それに応じた処理を行うことになる。このような制御方法は、マイコンが行う処理の
ほとんどが監視に費されるため、他の処理ができなくなってしまう欠点がある。
制御する対象がひとつだけなら問題は少ないが、一般にマイコンが制御する対象はむしろ
複数の場合が多いため、別の方法を考える必要がある。
割り込み処理は、このようなマイコンの処理とは無関係にいつ起こるか分からない外部の
状態変化に対する処理を効率よく行うための仕組みであり、例外処理ということもある。
マイコン(CPU)には割り込みを検知するための信号線があり、外部に接続される機器は
処理の要求を割り込み信号線でCPUに通知する。CPUが割り込み許可状態にあって割り込みを
検知すると、その時点で実行している命令の終了後にプログラムカウンタなどをスタックに
退避して、割り込み処理用のプログラムへ実行を移す。この時点で、多重に割り込みがかか
らないように自動的にCPUは割り込み禁止状態となる。このため、割り込み処理後にも
引き続き割り込み処理を行うためには、改めて割り込み許可命令によってCPUを割り込み
許可状態にする必要がある。なお、割り込み処理用のプログラムは割り込みハンドラとも
呼ばれ、予め準備しておかなければならない。
実験で使用するマイコンのCPU(H8/3052)では、CPUが割り込み許可状態にあって割り込みを
検知すると、その時点で実行している命令の終了後にプログラムカウンタ(PC)と
コンディションコードレジスタ(CCR)をスタックに退避して、割り込みの種類に応じた
割り込みハンドラを呼び出す。
呼び出される割り込みハンドラは、割り込み原因ごとに決められたアドレスに、対応する
割り込みハンドラ(C言語では関数)のスタートアドレスをセットすることで決まる。
これらのスタートアドレス群のことを、割り込みベクタという。
これらの割り込みベクタの中には、RESETやNMIなどの割り込み禁止ができないものが
含まれているため、プログラム実行前に設定されている必要がある。故に、割り込みベクタ
はROM領域に起かれることが多く、H8マイコンでもROM領域に起かれている。
特に、RESETはマイコンの起動時に参照される割り込みベクタであり、正しく設定されて
いないとプログラムの実行を始めることさえできない。実験に用いるマイコンボードでは、
RESETベクタはSフォーマットローダの開始アドレスにセットされている。
割り込みハンドラは、一般的な関数とほぼ同じように書くことができるが、その関数名の
直前にコンパイラ指令である {\tt\#pragma interrupt} の一行を追加しておく必要がある。
これは、一般的なサブルーチンコールで呼び出されてRTS命令で復帰するのに対して、
割り込みで呼び出される場合はRTI命令で復帰する必要があるためである。
さらに、割り込み処理をする場合には、割り込みベクタの設定が有効となるように、
プログラムの最初で必ずエミュレーションを有効にしなければならない。これは、前述した
ように割り込みベクタがROM領域に置かれているため、後からダウンロードしたプログラムで
必要となる割り込みベクタを書き込むことができない問題を解決するための方策であり、
H8マイコン特有の仕組みである。
\section{使用機器}
\begin{itemize}
\item H8マイコン
\item USBケーブル
\item パーソナルコンピュータ
\end{itemize}
\section{実験方法}
割り込み実験では、内蔵されているタイマを割り込み発生源として使用する、タイマ割り込み
について実験を行う。タイマ割り込みは、システム時間の計時やプロセス時間の経過を調べる
ために用いられる基本的な割り込みである。H8/3052には5つの独立したタイマがあり、各々
を異なる目的に使用することが可能である。
実験では、予め準備されているtimer.c に書かれている関数を使って、タイマの設定を行う。
また、割り込みの許可と禁止の操作は特殊な命令を実行する必要があるので、Cプログラミング
では ENINT(); と DISINT(); を使用する。更に、割り込みベクタの書き換えのために、ROM
エミュレーションを有効にするためには ROMEMU(); をプログラムの最初で実行すること。
\subsection{課題1 LED点滅実験}
1秒感覚で赤色LED(D1)と緑色LED(D2)を交互に点滅させるプログラムを作成せよ。但し、タイマ
0を使用して1msごとに割り込みをかけるものとし、割り込みハンドラでは呼び出されるたびに、
大域変数 sec\_time を0から1ずつ増やすこと。それ以外の機能は、全てメインルーチン内で実装
すること。なお、タイマ0による割り込みハンドラの関数は
{\tt void int\_imia0(void)}
とすること。また、雛形にはこれらが全て含まれた構造が与えられているので参考にすること。
\subsection{課題2 時計表示実験}
実験2を参考に、LCDに時間を表示するプログラムを作成せよ。タイマ割り込み関連は課題1で作成した
ものを利用してよい。
\begin{itemize}
\item 課題2-1
 プログラム実行からの秒数を表示するプログラムを作成せよ。但し、秒数が変化したときだけに
表示を更新するものとする。
\item 課題2-2
 プログラム実行からの時分秒を表示するプログラムを作成せよ。時計表示の範囲は、00:00:00から
23:59:59とし、プログラムの動作確認のために23:59:45から計時を開始すること。
\item 課題2-3
 1/100秒まで表示できるようにして、ストップウォッチの機能を実現せよ。0キーでリセットされて
00:00:00.00で計時スタート、\#キーで計時ストップとする。
\item 課題2-4
 課題2-2で作成した時計に、キー入力によって時刻を合わせる機能を付加せよ。時刻合わせの
方法は各自に任せるが、少なくとも時と分の単位で任意の時刻に設定できるようにすること。
\end{itemize}
\section{実験結果}
各々のプログラムソースは後に添付する。
\subsection{課題1 LED点滅実験}
1秒間隔で赤色LEDと緑色LEDを交互に点滅させるプログラムを作成できた。
\subsection{課題2 時計表示実験}
\begin{itemize}
\item 課題2-1
 プログラム実行からの秒数を表示するプログラムを作成できた。
\item 課題2-2
 時分秒を表示するプログラムを作成できた。
\end{itemize}
\section{検討課題}
\begin{itemize}
\item 検討課題1
 sys\_time を0にリセットしないとすると、計時を始めてからいつまで計時可能か。時分秒で答えよ。
但し、使用するコンパイラでは、整数型は32ビット表現である。
unsigned型で表せる最大値は$2^{32}-1$となり、sys\_timeは4294967295ミリ秒まで測ることができる。
これを時分秒に直すと1193時間2分47秒295となる。
\item 検討課題2
 割り込みハンドラとしての関数が、引数も戻り値もとれない理由について考えてみよ。
割り込みハンドラはプログラムの流れとは無関係に呼び出され、引数をセットすることができず、
戻り値も意味をなさないから。
\end{itemize}
\end{document}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment