А я про корректировку не говорил. Не нужне она мне.
а разве не так считается ?
OCR1A = 16000000 / 1024 * секунды - 1
а разве не так считается ?
Так я и сам спросил. Может и правильно. Зачем -1? Ведь 64мкс теряются вроде бы…
может вы и правы, ибо умные дядки пишут что, таймер в CTC режиме при совпадении счетчика с заданным значением он сбросит сам себя в ноль.
умные дядки пишут
Да, я к таким себя не отношу, “плаваю” во многих вопросах.
Но вариант отсчёта секунд таймером1 тоже считаю лучшим(ИМХО)
@dimax, рассуди нас плиз!
Калькулятор говорит, что будет:
Озадачили…придётся разбираться))
Первым частенько пользуюсь, второй только нашёл…
второй только нашёл…
поделитесь…
поделитесь…
long stsec=0; // счетчик секунд; unsigned long t2=0; // эта переменная используется ТОЛЬКО внутри одной функции // и нигде больше. Что она делает в глобальной области видимости? void loop() { if (millis()-t2>=1000) { stsec++; t2=t2+1000; // идея так себе - довольно дорогая } }
Вот так правильнее:
long stsec = 0; // счетчик секунд; void loop(void) { { static unsigned long t2 = 0; // момент увеличения счетчика секунд const unsigned long currentMillis = millis(); if (currentMillis - t2 >= 1000) { stsec ++; t2 = currentMillis; } } }
Это неравнозначные варианты:
первый - “в среднем через секунду”, а второй - “не менее чем через секунду”.
Ну да, OCR -1, то есть 15624. Потому что в OCR счёт с ноля. Т.е. деление на 1 получается при значении в регистре “0” Соответсвенно при записанном значении в регистре OCR 15624 мы получаем деление на 15625.
Потому что в OCR счёт с ноля. Т.е. деление на 1 получается при значении в регистре “0” Соответсвенно при записанном значении в регистре OCR 15624 мы получаем деление на 15625.
Понимаю, что именно так и правильно, но до конца пока ещё не осознаю почему…
Казалось бы, что проще - таймер стоит - в регистре 0. Прошёл один такт - в регистре 1. Прошёл другой - в регистре 2.
Видимо, чего-то ещё недопонимаю.
Сделал грубую проверку, добавив к коду от xDriver параллельно счётчик на micros()
Слова dimax полностью подтверждаются, при OCR = 15625 ошибка значительно больше
Спойлер
#include <avr/io.h>
#include <avr/interrupt.h>
volatile bool Print = false;
volatile uint32_t stsec = 0;
volatile uint32_t microsSum = 0;
volatile uint32_t lastMicros = 0;
void setup()
{
Serial.begin(9600);
// инициализация Timer1
cli(); // отключить глобальные прерывания
TCCR1A = 0; // установить регистры в 0
TCCR1B = 0;
OCR1A = 15625; // установка регистра совпадения
TCCR1B |= (1 << WGM12); // включить CTC режим
TCCR1B |= (1 << CS10); // Установить биты на коэффициент деления 1024
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << OCIE1A); // включить прерывание по совпадению таймера
sei(); // включить глобальные прерывания
}
void loop()
{
if(Print)
{
Serial.print("stsec = ");
Serial.println(stsec);
Serial.print("microsSum = ");
Serial.println(microsSum);
Print = false;
}
}
ISR(TIMER1_COMPA_vect)
{
stsec++;
microsSum += (micros() - lastMicros);
lastMicros = micros();
Print = true;
}
OCR1A = 15624
OCR1A = 15625
Эх, хожу во тьме!)))
Димакс, а я тебя вспоминал давеча.) В хорошем смысле.
Человеку нужен частотомер 10-125 000 гц. Нашрайбал. Но, его то чем то нужно проверить.
Написал генератор на таймере1 от кнопок. А после этого и вспомнил, что у тебя был похожий.)
Нашел, подшаманил. Смех и грех.) Всё класс. Благодарю!
Казалось бы, что проще - таймер стоит - в регистре 0. Прошёл один такт - в регистре 1. Прошёл другой - в регистре 2. Видимо, чего-то ещё недопонимаю.
Да, всё так и было бы, если бы таймер досчитал до 2 и встал) Но у нас цикл. А таймер обнуляется после достижения OCR только на следующий такт: К примеру что происходит при OCR=2 - Наш счётный регистр начинает по кругу совершать 3 счётных цикла
0->1
1->2
2->0
Вот почему при OCR=2 будет цикл из 3 тактов, и соответссно получаем деление на 3
А таймер обнуляется после достижения OCR только на следующий такт:
Большое спасибо за разъяснение!
По следам скетча из #1.
В строке 17 ЭТОГО скетча добавлено разовое выполнение delay(20000).
Нагонит ли stsec 20 секунд после выполнения этого delay?
long stsec = 0; // счетчик секунд;
unsigned long t2 = 0; // момент увеличения счетчика секунд
bool flag = true;
void setup()
{
}
void loop()
{
if (millis() - t2 >= 1000)
{
stsec++;
t2 = t2 + 1000;
}
if (flag)
{
delay(20000);
flag = false;
}
}
Нагонит ли stsec 20 секунд после выполнения этого delay?
Нет, не нагонит
Следующие 20 циклов stsec будет увеличиваться на 1. А затем уже каждую сек.
Нагонит ли stsec 20 секунд
нагонит