ATmega328Pに用意されているTOSC1は、外部32.768kHzの水晶振動子(クリスタル)を接続するためのピンで、TOSC1とTOSC2のピンの2つが存在します。これらは主に、リアルタイムクロック(RTC)機能やタイマー/カウンターの低速外部クロックソースとして利用されま、これらのピンを通じて接続された低周波数のクリスタルは、非常に正確な時間計測を可能にします。
TOSCを使った2つの機能の具体的な方法
- リアルタイムクロック(RTC):
ATmega328Pは直接的なRTCモジュールを内蔵していませんが、外部32.768kHzクリスタルをTOSCピンに接続することで、ソフトウェアベースのRTCを実装することが可能です。32.768kHzは2の15乗(32768)であり、1秒ごとのタイミングを生成するのに適した周波数です。 - タイマー/カウンターのクロックソース
特定のアプリケーションでは、マイクロコントローラの内部クロックよりも低速でより精確なタイミングが求められることがあります。このような場合、TOSCピンに接続されたクリスタルをタイマー/カウンターのクロックソースとして使用できます。
電気的仕様と接続方法
TOSC1およびTOSC2のピンは、PDIP、TQFP、およびQFNパッケージのATmega328Pで利用可能です。これらのピンは、通常、ピン配置の端に位置しています。外部クリスタルは、TOSC1とTOSC2の間に接続し、適切なロードキャパシタもクリスタルの両側に接続します。これはクリスタルの仕様に基づいて選択されますが、これらのキャパシタは、クリスタルの起動時間を最適化し、周波数の安定性を高めるために重要な要素になります。
必要な部品
- 32.768kHzのクリスタルオシレータ
- 2つのロードキャパシタ(通常、22pFまたはクリスタルのデータシートに推奨されている値)
具体的な接続方法
クリスタルの配置は、 32.768kHzのクリスタルをTOSC1ピンとTOSC2ピンの間に接続します。たとえば、ATmega328PのPDIP-28パッケージでは、これらはピン9(TOSC1)とピン10(TOSC2)に相当します。次に、ロードキャパシタの接続:は、クリスタルの両端に接続します。各キャパシタの一方の端子はクリスタルの各端子に接続し、もう一方の端子はグラウンド(GND)に接続します。これらのキャパシタは、クリスタルの正確な振動を保証し、安定したクロック信号を生成するために必要です。
・イメージ図
使用上の注意
- クリスタルの接続距離はできるだけ短く保つことが重要です。長いリード線やトレースは、クリスタルの振動に影響を与え、周波数の安定性を損なう可能性があります。
- 推奨されるロードキャパシタの値はクリスタルによって異なるため、クリスタルのデータシートを確認して適切な値を選択してください。
- クリスタルとマイクロコントローラの間には、他の信号線やノイズ源がないように配慮してください。これにより、クリスタルの性能に悪影響を及ぼす可能性があるノイズの影響を最小限に抑えることができます。
ソフトウエア実装例
1.1秒間隔でLEDを光らせる
Arduinoの環境でRTCを使用するためには、タイマー2を非同期モードで動作させ、外部クリスタルからのクロックを使用する設定が必要です。以下に、RTCを設定し、特定の時間間隔でLEDを点滅させるサンプルコードを示します。
#include <avr/sleep.h>
#include <avr/power.h>
// LED接続ピン
const int ledPin = 13;
void setup() {
pinMode(ledPin, OUTPUT);
// タイマー2を非同期モードに設定
ASSR |= (1 << AS2); // 外部クリスタルをタイマー2のクロックソースとして使用
// タイマー2の設定
TCCR2A = 0; // 通常モード
TCCR2B = (1 << CS22) | (1 << CS20); // プリスケーラを128に設定
// タイマー2の割り込みを有効化
TIMSK2 |= (1 << TOIE2); // オーバーフロー割り込みを有効化
// 割り込みが安定するまで待つ
while (ASSR & ((1<<TCN2UB) | (1<<TCR2AUB) | (1<<TCR2BUB)));
// 割り込みが設定されたらスリープモードを設定
set_sleep_mode(SLEEP_MODE_PWR_SAVE);
sleep_enable();
}
ISR(TIMER2_OVF_vect) {
static int ledState = LOW;
static unsigned long ticks = 0;
// 1秒ごとにLEDの状態を切り替え
if (++ticks >= 16) {
ledState = !ledState;
digitalWrite(ledPin, ledState);
ticks = 0;
}
}
void loop() {
sleep_mode(); // 割り込みまでCPUをスリープさせる
}
コードの解説
- タイマー設定: タイマー2をアシンクロナスモードに設定し、外部32.768 kHzクリスタルからクロックを供給します。プリスケーラを1024に設定して、オーバーフロー割り込みの発生頻度を下げ、24時間ごとのカウントを可能にします。
- 割り込みハンドラ: タイマー2のオーバーフローで発生する割り込みを捕捉し、指定した時間が経過したらLEDを点灯させます。
- スリープモード: デバイスの電力消費を最小限に抑えるために、割り込みが発生するまでCPUをスリープ状態にします。
この設定により、Arduino Unoは非常に正確な24時間周期で動作するタイマーとして機能し、指定した時間になったらLEDを点灯させることができます。
3.LCDを接続した時計サンプル
Arduino UnoとLCD(液晶ディスプレイ)を使用して、外部32.768 kHzクリスタルを用いたリアルタイムクロック(RTC)機能で時計を作るプロジェクトの構築について説明します。このプロジェクトでは、ArduinoにLCDを接続して現在の時刻を表示します。
説明
- LCDの設定: 16×2のI2Cインターフェース付きLCDディスプレイを使用しています。
LiquidCrystal_I2C
ライブラリを使って初期化し、時刻を表示します。 - タイマー2の設定: タイマー2をアシンクロナスモードで設定し、1秒ごとに割り込みを発生させて時刻を更新します。
コメント