• ベストアンサー

H8マイコン制御

H8マイコンを使って目覚まし時計を作りたいのですが、どうすればよいのかわかりません。 どなたかお詳しいかた教教えていただけませんか?? 時刻表示・時刻設定・アラーム設定をやりたいのです。。

質問者が選んだベストアンサー

  • ベストアンサー
  • LCR707
  • ベストアンサー率70% (95/135)
回答No.5

 ボタンで設定したいとのことなので、作り方を書きます。でもプログラムは自分で書いて下さいね。    4個のボタンを、「モード」「アップ」「ダウン」「セット」として用います。 まず、ボタンが押されたことを検出する関数を書きます。その関数は例えば mode_pb_check() という名前にし、さらにグローバル変数として、mode_pb_flg,mode_pb_old を用意します。 mode_pb_check() の中では、「モード」ボタンの状態を読みます。押されているとき1であるとします。 ボタンが1で、かつ、mode_pb_old が0のとき、mode_pb_flg を1にします。 次に、ボタンの状態を、mode_pb_old に入れます。 この関数を、int_imia0()の中から呼びます。これで、10mS毎にボタンの状態をチェックし、オフからオンになったときフラグを立てる機能ができました。  同様に、「アップ」「ダウン」「セット」ボタンについても、検出する関数を作成します。大抵の場合、4個のボタンは1個の8ビットポートの中に並んでいると思うので、4ビットまとめて上記の処理をすることもできます。もしそれが分かるのならそのように作成してもかまいません。しかし、「アップ」や「ダウン」ボタンを押し続けるとアップやダウンを早送りするような機能を将来追加したくなると思うので、できれば別々に作っておいたほうが良いでしょう。  次に、mode というグローバル変数と、セットタイム、アラームタイムを表す変数を用意して下さい。現在の hour,min,sec という変数は、言わばカレントタイムになります。これらの変数は、初期値として0を入れておいたほうが良いでしょう。そして、現在 main()の中でカレントタイムを液晶に表示している部分を書き換えます。かなり大きくなるので、 main()から取り出して別の関数、例えば display() とでもしたほうが良いでしょう。そして、 mode が0のときは、カレントタイムを表示し、 mode が1のときはセットタイム、2のときはアラームタイムを表示するようにします。このdisplay() を main() の中の無限ループの中からコールします。  次に、「モード」ボタンが押されたときの実際の処理を行う部分を作ります。関数名は、mode_flg_exec() とでもします。この関数の中では、   mode_pb_flg が0であれば、何もせずに終わります。   1であれば、mode_pb_flg を0にクリアし、mode をインクリメントします。もしmode が3になれば0にクリアします。 この関数を、 main()の中の無限ループの中からコールします。 これで、「モード」ボタンを押すたびに、mode が、0→1→2→0→1→2・・・と切り替わります。  ここまで出来たら、一度コンパイル、転送して動作確認して下さい。実際に「モード」ボタンを押す度に液晶の表示が変わると思います。  次に、「アップ」ボタンの処理部、up_flg_exec()を作ります。基本的な構造は mode_flg_exec()と同じですが、modeをインクリメントする代わりに、modeが1であればセットタイムを、modeが2であればアラームタイムをインクリメントします。mode が0のときは、up_pb_flg をクリアするだけで、他には何もしません。modeが1の場合を具体的に書けば、セットタイムの秒をインクリメントし、それが60になれば0にすると同時に、分をインクリメントします。もしそれが60になったら0にクリアし、時をインクリメントします。もしそれが24になったら0にクリアします。  この、up_flg_exec()を、main()の中の無限ループの中からコールします。  「ダウン」ボタンの処理、down_flg_exec()も、「アップ」と同様であることは分かりますよね。インクリメントの代わりにデクリメントします。  「セット」ボタンの処理部、set_flg_exec()もその構造は同じですが、処理は、セットタイムをカレントタイムにごっそりコピーすることです。  これで、時刻設定やアラーム設定の部分は完成です。実際はこれ以外にも、カレントタイムとアラームタイムを比較し、一致すればアラーム出力をオンにする部分とか、オンになったアラーム出力をオフにする機能が必要ですね。アラームをオフにするボタンが足りないのですが、例えば mode が0以外になったらオフにするのでも良いし、あるいは、「アップ」を押したら止まるのでも良いでしょう。いろいろ工夫して下さい。

その他の回答 (4)

  • LCR707
  • ベストアンサー率70% (95/135)
回答No.4

 タイマー割り込みを使って、時刻を表示するところまでは動作しているようですね。でも、時刻設定やアラーム設定は、人とのインターフェースが必要なのですが、どのように行うつもりなのですか。  基板に押しボタン入力がいくつかあれば、それを使って、時刻表示モードから時刻設定モードやアラーム設定モードに切り替え、別のボタンで設定時刻のアップダウンを行い、セットボタンで設定する、というような方法が可能です。  あるいは、基板がRS232Cなどでパソコンとつながっているのなら、パソコンから  SET HH:MM:SS<CR><LF> とか  ALM HH:MM:SS<CR><LF> のような文字列を送り、基板側はこれを解析して現在時刻やアラーム時刻を設定する、という方法もあります。 プログラムとしては、こちらの方がずっと簡単です。    結局のところ、どのようなハードウエアが使用可能で、どのような使い方をするかを、あなた自身が決めないとインターフェース部分の設計はできませんね。

sawamaru
質問者

補足

基盤にボタンが4つあります あとRS232Cでつながっています。 ボタンを押したら時刻設定やアラーム設定をできるようにしたいのですが・・・

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

時間あわせといっても、cnt、sec、min、hourを設定するだけではないのですか? それとも、ユーザーインタフェースの作り方がわからないのでしょうか? 何がしたいのか、何がわからないのかが、どうもつかめません。

sawamaru
質問者

補足

わ、私もわからないんです;;

  • techa
  • ベストアンサー率60% (41/68)
回答No.2

RTCとはリアルタイムクロックの意味です。 要は時間を取得したいわけですから、普通に考えればRTCを 外部において、H8ではその状態を適宜取得すればよいだけですね。マイコン内部のクロックは1秒を取得するにはうまく割り切れない場合が多く、長時間の時間計測には不向きなのです。ただ、おもちゃ程度の時間計測ならマイコン内部のタイマーを使って実装できます。 3052は使ったことがないのでなんとも言い難いのですが、たとえばタイマの割り込み周期を10msぐらいにセットして、100回割り込みがかかったら1秒として時間変数をインクリメント。60秒までカウントしたら分カウンタをインクリメントして秒カウンタをクリア という風に実装すればよいのではないですか?

sawamaru
質問者

補足

カウントはしてくれるのですが、時間合わせとかができないんですよ。 頭が悪すぎてどういう仕組みなのかがわかりません↓ でもどうしてもやらなければならないんです;; 見捨てないでください。。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

RTCには何を使うのですか?

sawamaru
質問者

補足

すみません、RTCがどのようなものかわかりません;; 本当にわからずにやっている状態なので・・・ でも見捨てないでください!! AKI-H8/3052でやってるんですが・・・ /*タイマ*/ #include "lcdctl.h" #define TCNT0 (*(volatile unsigned int *)0xffff68) #define GRA0 (*(volatile unsigned int *)0xffff6a) #define GRB0 (*(volatile unsigned int *)0xffff6c) #define TCR0 (*(volatile unsigned char *)0xffff64) #define TIOR0 (*(volatile unsigned char *)0xffff65) #define TIER0 (*(volatile unsigned char *)0xffff66) #define TSR0 (*(volatile unsigned char *)0xffff67) #define TSTR (*(volatile unsigned char *)0xffff60) #define ITU_CLOCK8 3 #define ITU_CLEAR_GRA 32 #define ITU_IE_IMFA 1 #define DI asm( "orc.b #0xc0,ccr" ) #define EI asm( "andc.b #0x3f,ccr" ) void start_itu0(); void int_imia0(void) __attribute__ ((interrupt_handler)); int cnt = 0, sec = 0, min = 0, hour = 0; char str[] = "timer 00:00:00"; /*メイン関数*/ int main(void) { lcd_init(); lcd_puts(str); start_itu0(); EI; for(;;) { if (cnt >=100) { cnt = 0; sec++; if (sec >=60) { sec = 0; min++; if (min >= 60) { min = 0; hour++; if (hour >= 24) hour = 0; } str[6] = '0' + hour /10; str[7] = '0' + hour %10; str[9] = '0' + min /10; str[10] = '0' + min %10; str[12] = '0' + sec /10; str[13] = '0' + sec %10; lcd_home(); lcd_puts(str); } } } return 0; } /*ITUOの初期設定*/ void start_itu0(void) { TCR0 = ITU_CLEAR_GRA + ITU_CLOCK8; TIOR0 = 0; GRA0 = 31250; TIER0 = ITU_IE_IMFA; TSTR = 1; } /*IMIA0割り込み処理関数*/ void int_imia0(void) { DI; /*割り込み禁止*/ TSR0 &=0xfe; cnt++; EI; /*割り込み許可*/ }

関連するQ&A