Сигнал SQW на модуле RTC DS3231 застрял на частоте 1 Гц (нужна 1024 Гц)

Я хочу использовать DS3231 RTC (ZS-042) для точного измерения времени на моем Arduino Uno. Мне нужно измерять миллисекунды, обычных функций времени различных RTC libs недостаточно.

После поиска в Google и расспросов я обнаружил, что мне нужно использовать вывод SQW DS3231 и подключить его к прерыванию или таймеру. При использовании соответствующей скорости я мог бы выполнять измерения времени.

Поэтому я попытался подключить SQW к контакту 5 на моем Arduino Uno (который является входом T1) и настроить T1 для использования внешнего источника. Я использовал некоторую библиотеку RTC, чтобы включить вывод SQW и установить его на 1024 Гц. Затем я подключил ISR для подсчета тиков и переполнений.

Все это, кажется, в основном работает, однако сигнал SQW, кажется, зависает на частоте 1 Гц, независимо от того, что я делаю.

Вот мой код:

#include <Wire.h>       //I2C library
#include <RtcDS3231.h>  //RTC library

RtcDS3231 <TwoWire> rtcObject(Wire);

static volatile unsigned long overflows = 0;


void setup() {
  Serial.begin(9600);

  rtcObject.Begin(); //Starts I2C
  rtcObject.SetSquareWavePin(DS3231SquareWavePin_ModeClock); //Sets pin mode
  rtcObject.SetSquareWavePinClockFrequency(DS3231SquareWaveClock_1kHz); //Sets frequency

  noInterrupts(); // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;

  OCR1A = 32000;
  TCCR1B |= (1 << WGM12); // CTC mode
  TCCR1B |= (1 << CS11); // external source / no prescaler
  TCCR1B |= (1 << CS12); // external source / no prescaler

//  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts(); // enable all interrupts
}

ISR(TIMER1_OVF_vect)
{
  TCNT1 = 0;
  overflows++;
}


void loop() {
  delay(1024);
  Serial.println("loop");
  Serial.println(TCNT1);
}

который напечатает что-то вроде:

loop
1
loop
2
loop
3

Что не так/отсутствует в моем коде?


person user826955    schedule 03.02.2019    source источник
comment
что вы хотите измерить и почему функции millis() или micros() Arduino недостаточно хороши?   -  person Juraj    schedule 03.02.2019
comment
В течение более длительного периода измерения недостаточно точны по сравнению с точными часами.   -  person user826955    schedule 04.02.2019
comment
Вы хотите измерять длительные периоды с большой точностью?   -  person Juraj    schedule 04.02.2019
comment
Я хочу измерить продолжительность ‹ 1 часа с точностью до миллисекунды. Использование встроенных часов отличается от измерений реальными часами примерно на 0,3 мин за 1 мин.   -  person user826955    schedule 04.02.2019
comment
18 секунд в минуту? это не может быть правдой. 18 микросекунд?   -  person Juraj    schedule 04.02.2019


Ответы (1)


Если ваш модуль имеет чип DS3231M, то, согласно техническому описанию, эта модификация может генерировать сигнал только 1 Гц на контакте INT/SQW (3) и 32768 Гц на контакте 32 кГц (1). У меня есть несколько DS3231M, проверил.

Если в вашем модуле есть чип DS3231SN: недавно у меня была похожая проблема. Получил 10 шт DS3231SN с али. Припаял одну микросхему к моей плате и обнаружил эту проблему. К счастью, у меня был переходник ZIF SO16 на DIP, я собрал тестовую плату, подключил ее к осциллографу и протестировал их все. Только 4 шт из 10 смогли генерировать разные сигналы (1024Гц, 4096Гц и т.д.) на выводе SQW согласно даташиту. Также они генерировали стабильный сигнал 32768 Гц на контакте 32 кГц (контакт 1).

Другие 6 (также помеченные как DS3231SN) давали сигнал только 1 Гц на выводе SQW, все они давали сигнал на выводе 32 кГц (один IC генерировал около 35 кГц), один IC генерировал сигнал с плавающей частотой на выводе SQW (около 1500 Гц и изменить нельзя). Я думаю, что это низкокачественная подделка IC.

person Paul    schedule 02.04.2019
comment
Спасибо за подсказку. Тем временем я смог выяснить то же самое. Действительно, у меня был один чип, привязанный к частоте 1 Гц, в то время как другие модули могли обеспечивать частоту 1 кГц (с тем же кодом). - person user826955; 02.04.2019