ニキシー管時計 製作レポート
ページ1……スペック/パーツ/回路図/基板
ページ2……プログラム
ページ3……試作機/コイル製作
ページ4……基板製作/ケース製作
ページ5……使用方法/動画
----- プログラム -----
HEXファイル:clock_010304.hex
ソースファイル:clock_010304.c
おまけ
コアプログラムソース:PICC-Lite_pic16f877a_core.c
プログラムはニキシー管と7セグメントLED共に同じものが使えます。
おまけで、時計のプログラムを作るにあたって最初に作ったコアプログラムのソースも掲載します。
あまり綺麗なソースではないけど、こんな感じで動いてるんだなと思っていただければ。
プログラム階層図
関数は常に下の関数が上の関数を呼ぶように作っています。
コアプログラム概要
時計のプログラムを組む前にまずはI/O処理と割り込み処理を行うためのコアプログラムを組むことにした。
ほとんど独学と思いつきと経験と思いつきと思いつきと思いつきで作っているので、本格的にプログラムをやっている人から見ると、プログラムの内容も用語の使い方もめちゃくちゃかも。
まぁ、動けばいいや。
- システム
- main()関数
PICそのものの初期化と、ループ処理を行っている。
初期化が終了したらInitDone()関数をコールしてPICの初期化終了を通知している。
ループ内でDispOut()関数とSwScan()関数をコールしてI/O処理。
DispOut()とSwScan()が終了したらLoopEvnt()をコールして、またDispOut()から順番に処理していく。
ループの中に時間稼ぎループを入れてループ周期を調整している。
#define IdleLoopCount 170 /* 時間稼ぎループ回数(0-255) */
- isr()関数
割り込みが発生したときにコールされる。
今回はタイマ2を利用して3.2768MHzを分周して1/200ごとに割り込みをかけ、IntTimer()関数をコールする。
割り込み種別毎に別々の関数をコールできるように想定して作っているが、結局タイマ2割り込みしか使用していない。
- I/O処理
- DispOut()関数
コールされるたびに一桁分づつ桁選択と数字出力を出力。
一回目にコールされたら1桁目の情報、二階目で2桁目の情報……、6桁目の次は1桁目とういう具合。
- SwScan()関数
コールされるたびにプッシュスイッチが繋がっているポートの状態を見に行く。
状態変化があった場合は、それぞれの状態を通知する関数をコールする。
呼ばれる関数は状態の変化に応じてSw#Push()、SW#Long()、SW#Contenu()、Sw#Rel()、SW#LgRel()の5つ(#はスイッチの番号が入る)
実際のところ、SW#Contenu()、Sw#Rel()は使わなかったので時計のプログラムからは削除されている。
チャタリング防止のため、数回コールされて状態が安定していることが確認されてからSw#Pushをコールするようにしている。
スイッチ押下、長押し、長押し継続と判断する回数は以下のdefine行で設定している。
ループごとにカウントしているため、長押しと判定される時間等はループ周期の設定に影響される。
#define SwPushCount 5 /* SWが押されたと認識するカウント数 */
#define SwLongCount 500 /* SWが長押しされたと認識するカウント数 */
#define SwContenuCount 90 /* SWが長押しが継続されたと認識するカウント数 */
- IntTimer()関数
タイマ2割り込み処理を行う。
1/200秒ごとに割り込みがかかり、100回カウントして0.5秒毎にHalfSec()関数で通知している。
- 通知
通知部はシステムおよびI/Oのから通知される関数。
必要に応じて関数の中身を編集する。
- InitDone()関数
PIC初期化終了を通知する。
時計のプログラムでは、時計として動くために使用する変数の初期化とEEPROMからアラーム時刻等の設定をロードする関数をコールしている。
- Sw#Push()関数
プッシュスイッチが押されたことを通知する。
- Sw#Long()関数
プッシュスイッチが押されたままの状態で、長押しだと判断されたことを通知する。
- Sw#Contenu()関数
長押しの状態が継続していること通知する。
計測されている間は一定間隔で通知され続ける。
時計のプログラムでは最初のうちは時刻設定で使用していたが、容量の関係で削った。
- Sw#Rel()関数
プッシュスイッチが開放されたことを通知する。
短押しの場合に通知されて、長押しの場合はSw#LgRel()で通知される。
- Sw#LgRel()関数
長押しの状態から開放されたことを通知する。
- HalfSec()関数
0.5秒毎にコールされる。
コールされるたびに1Hz出力のH/Lを切り替えたり、時刻更新やアラーム等の出力を行うClockProc()関数やAlmTimeOut()関数をコールしている。
アプリケーション
時計として動くためのプログラムを書いてある。
- LoadEEPROM()関数
EEPROMに保存されているアラーム時刻等の設定を読み出す。
- SaveEEPROM()関数
アラーム時刻等の設定をEEPROMに保存する。
- AddHH()関数・AddMM()関数・AddMM2関数・AddM()関数
時刻設定などで利用する共通処理。
- ClockDisp()関数・Display()関数
表示モードにしたがって、表示用メモリに表示内容を格納する。
- ClockProc()関数
時刻の更新
- AlmTimeOut()関数
設定時刻と現在時刻を比較してアラームやタイマ出力を制御。
基本的にコアプログラムはいじる必要はないが、コアプログラムから時計プログラムを作る際に容量の関係でコアプログラムの未使用な部分を削ったり、時計の機能にかかわるところで手をいれてある部分もある。
ページ1……スペック/パーツ/回路図/基板
ページ2……プログラム
ページ3……試作機/コイル製作
ページ4……基板製作/ケース製作
ページ5……使用方法/動画
戻る