2014/07/05

時計もどきの試作(AVRマイコン)

AVRマイコンとLCDを使った時計もどきを試作しました。なぜ「時計もどき」かと言うと、時刻合わせを行う機能がないからです。

用意するもの


1秒の作り方


マイコン内蔵クロックは精度が悪いため時計には使わないほうが良いでしょう。マイコンボードには20MHzのX'talが搭載されているのでこれを使います。20MHzクロックはマイコン内部で1/8(=2.5MHz)にされ、CPU Coreの動作クロック、およびタイマ/カウンタの動作クロックとして使われます。タイマ/カウンタは20mS周期(=50Hz)でタイマ割り込みを発生させます。プログラムはタイマ割込50回で秒針を1進めるようになっています。


図1 クロック構成

回路図


今回使用したLCDモジュールはマイコンとI2Cバスで接続します。図2に回路図を示します。


図2 回路図

I2Cバスのアクセス方法


マイコン内蔵のTWI機能を使ってI2Cバスにアクセスします。TWIの使い方は面倒そうだったのでAVR315付属のサンプルコードを使いました。ただし、avr-libcで使う場合は割り込み関係のソースを少し修正する必要があります。以下に修正ポイントを示します。

リスト1 TWI_Master.cの冒頭

1
2
3
4
5
6
7
#if defined(__GNUC__)  // GNU Compiler
  #include <avr/io.h>
  #include <avr/interrupt.h>
#else                  // IAR C Compiler
  #include "ioavr.h"
  #include "inavr.h"
#endif /* __GNUC__ */
修正ポイント:1~4行目、7行目を追加

リスト2 TWI_Master.cの割込みルーチン

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ********** Interrupt Handlers ********** //
/****************************************************************************
This function is the Interrupt Service Routine (ISR), and called when the TWI i\
nterrupt is triggered;
that is whenever a TWI event has occurred. This function should not be called d\
irectly from the main
application.
****************************************************************************/
#if defined(__GNUC__)           // GNU Compiler
ISR(TWI_vect)
#else                           // IAR C Compiler
#pragma vector=TWI_vect
__interrupt void TWI_ISR(void)
#endif
{
  static unsigned char TWI_bufPtr;
修正ポイント:9~11行目、14行目を追加

完成


こんな感じで動きます。 電源入れたまま10日ほど放っておいたら10秒遅れました。月差に換算すると30秒ぐらいなのでまあまあの精度です。

マンデルブロ集合の彩色方法(5)

06.knit 1 発散判定式を変更する mandelbrot() 内の発散判定式 |zn|>2 を変更する...