2020年8月30日日曜日

ATmega328PBを外付けの発振子(16MHz MEMS)で動かしてみた


背景

以前ATmega328PBを水晶振動子で動かそうとしましたが、ATmega328Pと違いフルスイングの振動子駆動回路を内蔵していないためか、ATmega328Pを動かしていた水晶振動子では動かせませんでした。
外付けの発振子で動くことを確認したかったので、秋月電子で売られていた16MHZの発振子を利用して動かしてみました。

備忘録を兼ねて取り組んだ内容を記事として残します。

なお、ATmega328PBを使っているPololuのA-Star 328PB回路図を見ると水晶振動子で動かしていることが分かったので、まだどれか分かっていませんがATmega328PBを動かせる水晶振動子はあるようです。(この記事を書いているときに分かりました。)
どの水晶振動子なら動かせるのかご存知な方、コメントなどで教えていただけると嬉しいです。

使ったもの


この記事では間違って使っていませんが、MEMSが3.3V駆動なのでMEMSの電源として3.3Vのレギュレーターが必要です。(これとかが使えます -> 3.3V 0.5Aレギュレータ
この記事を参考に回路を組む方は、MEMSを壊さないためにレギュレーターも回路に追加するのが良いです。

回路

Arduino as ISP

ATmega328PB-bread-boardとArduino as ISPを書き込んだProMicroは、ProMicroからの信号でプログラムを書き換えられるように下記のように接続します。

ProMicro ATmega328PB
16 (MOSI) PB3/D11
14 (MISO) PB4/D12
15 (SCK) PB5/D13
10 (Reset) PC6/D22/RST
VCC VCC
GND GND

16MHz MEMS

MEMSの発振子は変換基板とピンヘッダでブレッドボードに付けれる状態にします。


MEMSのデータシート通り0.1ufと15pfのコンデンサをそれぞれ電源と発信子の線に接続します。
ATega328PBの外部発信子用端子 EXTCLK は XTAL1/PB6/D20 なので、その端子に発信子の信号を接続します。
(データシートにはEXTCLKがXTAL1だという記載を見つけられませんでしたが、stack overflowの回答で言及されており、回路を組んだらそれで動きました。)

使ったものの紹介でも言及しましたが、MEMSは3.3V駆動なので、ここのVCCには3.3Vを供給してください


LED

動作速度とXTAL2(PB7/D21)が使えることを確認するために、LEDと抵抗をそのピンに繋ぎます。
今回は配線の都合でGNDを引き出すのが手間だったので、LEDのアノード(+)側をVCCに接続し、カソード側を抵抗を通してXTAL2に接続しました。

全てを接続した様子

ProMicro、MEMS、LEDを全て繋げるとこのようになりました。

使ったものの紹介でも言及しましたが、MEMSは3.3V駆動なので、MEMSの電源用に3.3Vのレギュレータも追加してください


プログラム

1秒毎にLEDの点灯と消灯を繰り返すプログラムを書き込みます。
PlatformIOのプロジェクトのsrc/main.cppに下記の処理を記述します。
#include <Arduino.h>
#define PIN_OUT 21

void setup() {
pinMode(PIN_OUT, OUTPUT);
}

void loop() {
static bool ledState = false;
digitalWrite(PIN_OUT, ledState);
ledState = !ledState;
delay(1000);
}

書き込み設定

ATmega328PBのデータシートによると、Low FuseのCKSELを0にすれば外部の発振子を利用する状態になるようです。



0-3のCKSELは0とし、7ビット目のDivice clock by 8 は1にしてクロックを8で割ることを止めれば、外部の16MHzの発信子の信号によって16MHzで動きます。
その他のビットは標準で良いのでLow Fuzeに0xE0を書き込みます

ということで、PlatformIOのプロジェクトのplatformio.iniを下記の設定にしてArduino as ISP経由でATmega328PBにプログラムを書き込みます。
(upload_portはUbuntuで認識しているポート名なので、Windowsなど他の環境で実行する場合は、認識しているポート名を割り当ててください。)

[env:ATmega328PB]
platform = atmelavr
board = ATmega328PB
framework = arduino
upload_protocol = stk500v1
upload_port = /dev/ttyACM0
upload_speed = 19200
upload_flags =
-b$UPLOAD_SPEED
-P$UPLOAD_PORT
; use external (16MHz) and not divide it by 8
; 0xe0: 11100000
-Ulfuse:w:0xE0:m

ProMicroをPCに接続して下記のコマンドを実行するとプログラムを書き込めます。
Arduino ISP経由での書き込みは、-tで指定するタスクがuploadではなくprogramなので、間違うとエラーが出て書き込めないので注意してください。
pio run -t program

動作確認

LEDが1秒毎に点いたり消えたりします。



発信子の線を切り離すと動作を停止するため、発信子の情報を期待通りに参照しているようでした。


まとめ

16MHzの外部発信子を利用してATmega328PBを16MHzで動かせました。
外部発信子を利用するためのEXTCLKはXTAL1であり、外部発信子の信号入力は1ピンで済むため、XTAL2が割当たっているPB7/D21はGPIOとして利用できました。

更新履歴

2020.10.03
記事を見直していたらMEMSが3.3V駆動だと分かったので、3.3Vのレギュレータが必要な旨を記事に追加しました。

0 件のコメント :