平成23年特別試験午後問題 問7

問7 組込みシステム開発

⇱問題PDF
LEDを使用したデジタル時計の設計に関する次の記述を読んで,設問1~3に答えよ。
 Z社では,6個の7セグメントLEDで年月日及び時分秒を表示するデジタル時計の設計を行っている。

〔デジタル時計の機器構成〕
 デジタル時計のブロック図を,図1に示す。このデジタル時計は,LED,MPU,クロックカウンタ,リアルタイムクロック(以下,RTCという),機械的な押しボタン式スイッチ(以下,SWという),及びプログラムで入出力を設定できるプログラマブル入出力装置(以下,PIOという)で構成される。
pm07_1.png
〔デジタル時計の動作〕
  • 電源を入れると,初期化プログラムによってRTC,クロックカウンタ,PIOにそれぞれ初期設定データを書き込み,初期化する。SWを押しているときは年月日を表示し,押していないときは時分秒を表示する。
  • RTCは年月日,時分秒データ(以下,時刻データという)を保持し,RTC自身が時刻を更新する。RTCは1秒ごとにMPUに割込みを行い,RTC割込みハンドラを起動する。RTC割込みハンドラは,RTCから時刻データを読み込む。読み込んだデータは,配列 Date に,西暦年の下2けた,月,日が格納され,配列 Time に,時,分,秒が格納される。例えば,読み込んだ時刻データが2011年4月17日,12時34分56秒ならば,Date[0]~Date[5]に1,1,0,4,1,7が,Time[0]~Time[5]に1,2,3,4,5,6が格納される。
  • クロックカウンタは,クロックをカウントし,1ミリ秒ごとにMPUに割込みを行い,クロックカウンタ割込みハンドラを起動する。
〔PIO〕
 PIOの構成を図2に示す。PIOは,それぞれ16ビットで構成される入出力制御レジスタ(以下,PIO_Rという)とデータレジスタ(以下,PIO_Dという)から成る。PIOには16個の入力又は出力の設定が可能な端子があり,それぞれPIO_Dの1ビットに割り当てられる。
  • PIO_Rは,PIO_Dの各ビットを入力にするか出力にするかを決める。PIO_RのビットRiを1にするとPIO_DのビットDiは出力に指定され,0にすると入力に指定される。
  • PIO_Dにデータを書き込むと,PIO_Rによって出力に指定されたビットのデータだけが端子から出力される。一方,PIO_Dのデータを読み込むと,PIO_Rによって入力に指定された端子のデータだけが読み込まれる。入力に指定されていないビットのデータを読み込むと不定の値となる。
    pm07_2.png
  • PIO_DのD14に割り当てられた端子には,SWが接続される。SWを押している間はオンとなり,そのときPIO_Dを読み込むとそのビットは1,SWがオフのときそのビットは0となる。PIO_Dを読み込むとそのときのD14の値がSWの状態となる。

〔ダイナミック点灯方式〕
 このデジタル時計で使用しているLEDの表示方法は,ダイナミック点灯方式である。ダイナミック点灯方式は,短時間に一つのLEDだけを点灯し,点灯するLEDを順に切り替え,あたかも全体が点灯しているかのように見せる方式である。
 図3にLEDのセグメント割当てを,図4にLED表示部の構成を示す。
  • PIO_Dの下位8ビット D0~D7 のうち,D0~D6 にはLEDのセグメントa~gを割り当て,D7には小数点dpを割り当てる。具体的には,D0をLEDのセグメントaに,D1をbに,…,D6をgに割り当てる。
  • PIO_Dの上位8ビット D8~D15 のうち,D8~D13 には,LED0~LED5 を割り当て,D14 にはSWを割り当てる(D15は使用しない)。具体的には,D13 を LED5 に,D12 を LED4 に,…,D8 を LED0 に割り当てる。
  • LEDを点灯するためには,点灯するセグメントに対応するビット D0~D7 に1を書き込み,点灯するLEDに対応するビット D8~D13 に1を書き込む。
 例えば,表示する時分秒のうち,"分"の10分台の数字は LED3,1分台の数字は LED2 である。LED3 に4を表示させるためには,PIO_Dに16進数 0866 を書き込む。
pm07_3.png
〔クロックカウンタ割込みハンドラ〕
 クロックカウンタ割込みハンドラは,ダイナミック点灯の制御及びSWの入力の判定を行う。その流れ図を図5に示す。
 配列 Pattern[0]~[9] はそれぞれ16ビットの符号なし整数で,LEDに0~9を表示するための点灯セグメントの情報を格納する。例えば,Pattern[4] はLEDに4を表示するため,16進数 0066 を格納している。
 iはLEDを示すカウンタ,cnt はSWの切替え時に状態が安定するまで待ち合わせるためのカウンタで,それぞれ16ビットの符号なし整数であり,初期値はいずれも0である。
 swState はSWの状態を表す1ビットの変数であり,prev は直前の割込み処理で検出したSWの値を表す1ビットの変数である。初期値はいずれも0である。
 work 及び,pwork は,16ビット符号なし整数であり,作業用の変数である。
 図5中の①の処理は,SWの状態が変化したときに,状態が安定するまで待ち合わせる処理である。
pm07_4.png

設問1

初期化プログラムによって,PIO_Rを初期化する設定値を16進数4けたで答えよ。ただし,PIO_Dの未使用のビットは入力として設定すること。

解答例・解答の要点

3FFF

解説

RIO_Rのビットは、1にすると出力に、0にすると入力に設定されます。
図3、図4を見ると、D0~D7はLEDの各セグメントに割り当てられており、D8~D13はLED駆動回路に接続されています。この14個のビットには値を書き込むので出力(1)にする必要があります。一方、D14はSWの状態を保持するビットで、読込み専用なので入力(0)にします。D15は未使用であり、未使用のビットは入力として設定するとあるので0を設定します。

つまり、PIO_Rに設定すべきビット列は、

 0011 1111 1111 1111

これを16進数4桁で表した「3FFF」が正解となります。

∴3FFF

設問2

図5中のadについて,(1),(2)に答えよ。
  • abに入れる適切な配列名を答えよ。
  • cdに入れる適切な式を答えよ。

解答例・解答の要点

  • a:Time
    b:Date
  • c:13-i
    d:i=6 又は i>=6 又は i>5

解説

  • abについて〕
    代入先となっている変数 work は、次の処理で配列 Pattern の添字として使われています。Pattern は、LEDに表示する0~9のパターンを保持する配列であり、例えば Pattern[4] を参照すれば"4"の点灯パターンを取得することができます。つまり、変数 work にはLEDに表示したい数字を入れる必要があります。

    [a]の処理を行うか、[b]の処理を行うかは変数 swState の値によって分岐しています。swState はSWの状態を保持する変数で、swState が1(SWがON)であれば年月日を、swState がOFF(SWが0)であれば時分秒を表示します。swState = 0 がYesのときには時分秒を表示したいので、時分秒を格納する配列 Time からi番目の数字を取得し、swState = 0 がNoのときには年月日を表示したいので、年月日を格納する配列 Date からi番目の数字を取得することになります。

    したがって、[a]には「Time」が、[b]には「Date」が当てはまります。

    a=Time
     b=Date

  • cについて〕
    点灯させるLEDの位置を指定する式が入ります。
    問題文の「読み込んだ時刻データが2011年4月17日,12時34分56秒ならばDate[0]~Date[5]に1,1,0,4,1,7が,Time[0]~Time[5]に1,2,3,4,5,6が格納される」と、 [c]の少し手前の work←Date[i]/work←Time[i]の部分に着目します。

    PIO_Dは下位ビットから上位ビットに向かってLED0,LED1,…,LED5となっていますが、配列 Time 及び配列 Date は、逆に添字の小さいほうからLED5,LED4,…,LED0となっています。
    pm07_5.png
    配列の添字iが1であればPIO_DのD12を1に、配列の添え字iが2であればPIO_DのD11を1に、というようにしたいので、これをiを用いて表すと「13-i」になります。

    c=13-i

    dについて〕
    本問のデジタル時計はダイナミック点灯方式を採用していて、LED5、LED4、…、LED0という順で1ミリ秒(クロックカウンタの割込み)ごとに点灯するLEDを切り替えています。流れ図の i ← i + 1 の処理が点灯するLEDを1つ右に切り替え処理です。LED0まで行ったら次は左に戻りLED5を点灯させるので、変数 i を0にして点灯位置をLED5に戻すことになります。つまり、i ← 0 を実行するのはLED0を点灯する処理をした直後となります。LED0の点灯時、変数 i は5であり、 i ← i + 1 の処理により分岐時点では6になっていますから、変数 i を0に初期化するのは i=6 のときが適切です。i=6 で変数 i が0に初期化されれば良いので、i>=6 や i>5 という条件式でも正しく動作します。

    d=i=6 又は i>=6 又は i>5

設問3

図5中の①の処理で,SWの状態を直ちに反映しない理由を,30字以内で述べよ。

解答例・解答の要点

・スイッチオン・オフ時は不安定な状態になるので (21文字)
・SWの状態が不安定なので (12文字)
・チャタリングによって,状態が不安定なので (20文字)

解説

①で行っている処理を考えます。

クロックカウンタ割込みハンドラは1ミリ秒ごとに起動します。
①では、1ミリ秒ごとに、D14を直前のSWの値(prev)と比較します。もし異なれば、cntに10を設定し、直後にcntを1減じます。もし同じなら、cntが0になっていなければcntを1減じ、cntが0になっていればswStateに直前のSWの値(prev)を設定します。つまり、D14が直前のSWの値(prev)と異なった場合、D14が10ミリ秒連続で同じ値であったときにはじめてSWの状態がその値に安定したと判断していることがわかります。年月日と時分秒の表示が切り替わるのはSWを押して/離してから10ミリ秒後ということです。

この処理はSWの状態を確定するために行っています。なぜこのような処理を行っているのかというと、機械的スイッチではON/OFFになる瞬間(物理的に端子の金属と金属が触れたり、離れたりする瞬間)にON/OFFの状態が不安定になり、ON/OFFが繰り返される現象(チャタリング)が発生することがあるからです。非常に短い時間にswStateが1と0を行き来すると、デジタル時計は年月日と時分秒の数字が混在しているように見えてしまいます。これを防ぐために、SWの状態が安定するのを待つ処理を入れているというわけです。

∴・スイッチオン・オフ時は不安定な状態になるので
 ・SWの状態が不安定なので
 ・チャタリングによって,状態が不安定なので
模範解答

Pagetop