計画しているシャッター速度計測装置の測定データに時間なども記録しておくため、液晶ディスプレイにRTCモジュールも追加してみた。
STM32をマスターとしRTCモジュールと液晶ディスプレイをスレーブとしたI2C通信を試した。SDA・SCLの信号線はプルアップして使うのが正しいようだが、プルアップなしに接続した。
STM32とI2Cデバイスの接続は、液晶ディスプレイ・RTC両モジュールのSDA端子をSTM32のB6へ、両モジュールのSDA端子をSTM32のB7へ接続する。
両モジュールにはそれぞれI2Cのアドレスが設定されており、インクルードしたライブラリは、このアドレスで複数のモジュールを識別して通信する。
スケッチをアップロードすると時間合わせをシリアルモニタ経由で行うようになっている。時間が数秒単位でずれた場合はボタンで時間合わせができる。ボタンを押したとき、秒数が30秒未満では秒数だけリセットし、30秒以上では秒をリセットするとともに分数を1分進めるようにした。
スケッチは次のとおり。
#include <LiquidCrystal_I2C.h>
#include <DS3231_Simple.h>
LiquidCrystal_I2C lcd(0x27,16,2); // I2Cアドレス:0x27 桁数:16 行数:2
DS3231_Simple Clock;
volatile int flag=0;
void setup()
{
}
void loop()
{
pinMode(PA0,INPUT_PULLUP); // PA1 プルアップ入力
attachInterrupt(PA0, TimeADJ, CHANGE); // LOWで割込発生
Clock.begin();
char *wk; // 曜日
lcd.init(); // 初期化
lcd.backlight(); // バックライト
int MyTemp;
while(1)
{
DateTime MyTime = Clock.read(); // 時間読取り
if (flag == 1){
if (MyTime.Second &gt;= 30) {
++MyTime.Minute;
}
MyTime.Second = 0;
Clock.write(MyTime); // 修正時間書き込み
flag = 0;
}
lcd.setCursor(0,0); // カーソル位置 桁0,行0
lcd.print("20"); // 年(上2桁)
lcd_Print(MyTime.Year); // 年(下2桁)
lcd.print("/");
lcd_Print(MyTime.Month); // 月
lcd.print("/");
lcd_Print(MyTime.Day); // 日
switch(MyTime.Dow){
case 1:wk = "Mon"; break;
case 2:wk = "Tue"; break;
case 3:wk = "Wed"; break;
case 4:wk = "Thu"; break;
case 5:wk = "Fri"; break;
case 6:wk = "Sat"; break;
case 7:wk = "Sun";
}
lcd.setCursor(12,0);
lcd.print(wk); // 曜日
lcd.setCursor(0,1); // カーソル位置 桁0,行1
lcd_Print(MyTime.Hour); // 時
lcd.print(":");
lcd_Print(MyTime.Minute);// 分
lcd.print(":");
lcd_Print(MyTime.Second);// 秒
MyTemp = Clock.getTemperatureFloat(); //温度読取り
lcd.setCursor(12,1); // カーソル位置 桁12,行1
lcd.print(MyTemp); // 温度
lcd.print((char)223); // ゚C 表示
delay(100);
}
}
void lcd_Print(int val)
{
if(val &lt; 10){
lcd.print("0");
}
lcd.print(val);
}
void TimeADJ() {
flag=1;
}