Интерфейс без виртуализации2

Коль @ЕвгенийП что то морозится, продолжу здесь.

Когда я слышу подобное, всегда прошу свидетелей чистого и кошерного повторить на нём вот такую задачу (типичная, кстати, задача для микроконтроллеров). Почему-то никто ни разу не сподобился.

Может, Вы проведёте мастер-класс?

P.S. Кстати, тот код живёт и используется, периодически немного меняется. Живёт он, на сегодня, здесь.
Я никого не защищаю, но в чём проблема эту задачу решить препроцессору, который присутствует что в Си, что в С++. Пример.

#define DEBUG         1
#define FREQ2         1000
#define FREQ1         500

// Prescaler TCCR2B:
enum { T2_OFF, T2_DIV1, T2_DIV8, T2_DIV32, T2_DIV64, T2_DIV128, T2_DIV256, T2_DIV1024 };
#if F_CPU / 256 / 1 < FREQ2
  #define T2_PRE      T2_DIV1
  #define T2_DIV      1
#elif F_CPU / 256 / 8 < FREQ2
  #define T2_PRE      T2_DIV8
  #define T2_DIV      8
#elif F_CPU / 256 / 32 < FREQ2
  #define T2_PRE      T2_DIV32
  #define T2_DIV      32
#elif F_CPU / 256 / 64 < FREQ2
  #define T2_PRE      T2_DIV64
  #define T2_DIV      64
#elif F_CPU / 256 / 128 < FREQ2
  #define T2_PRE      T2_DIV128
  #define T2_DIV      128
#elif F_CPU / 256 / 256 < FREQ2
  #define T2_PRE      T2_DIV256
  #define T2_DIV      256
#elif F_CPU / 256 / 1024 < FREQ2
  #define T2_PRE      T2_DIV1024
  #define T2_DIV      1024
#endif

// Prescaler TCCR1B:
enum { T1_OFF, T1_DIV1, T1_DIV8, T1_DIV64, T1_DIV256, T1_DIV1024};
#if F_CPU / 65536 / 1 < 500
  #define T1_PRE      T1_DIV1
  #define T1_DIV      1
#elif F_CPU / 65536 / 8 < FREQ1
  #define T1_PRE      T1_DIV8
  #define T1_DIV      8
#elif F_CPU / 65536 / 64 < FREQ1
  #define T1_PRE      T1_DIV64
  #define T1_DIV      64
#elif F_CPU / 65536 / 256 < FREQ1
  #define T1_PRE      T1_DIV256
  #define T1_DIV      256
#elif F_CPU / 65536 / 1024 < FREQ1
  #define T1_PRE      T1_DIV1024
  #define T1_DIV      1024
#endif

void setup() {
  #if DEBUG
  Serial.begin(9600);
  Serial.println("Calc Prescaler T2, T1 " __DATE__ " " __TIME__);
  TCCR2A = TCCR2B = 0;
  TCCR1A = TCCR1B = 0;
  #endif

  TCCR2B = T2_PRE;
  OCR2A = F_CPU / T2_DIV / FREQ2;

  TCCR1B = T1_PRE;
  OCR1B = F_CPU / T1_DIV / FREQ1;

  #if DEBUG
  Serial.print("T2_DIV: "); Serial.println(T2_DIV);
  Serial.print("TCCR2B: "); Serial.println(TCCR2B);
  Serial.print("OCR2A: ");  Serial.println(OCR2A);
  Serial.print("T1_DIV: "); Serial.println(T1_DIV);
  Serial.print("TCCR1B: "); Serial.println(T1_PRE);
  Serial.print("OCR1B: ");  Serial.println(OCR1B);
  #endif
}

void loop() {}
2 лайка

Делитель на 2 потерял
От тиков 1 забыл отнять

вторая серия, вчера все баном закончилось.

Я ж аппаратно не дрыгаю.

Согласен. Но и ЕвгенийП тоже не отнимает.)

Там не совсем бан. Тема просто не видна.

ну ты у @flexprint-а спроси))
у меня пока видна))


Так и у меня видна, если зайти с чёрного хода.

1 лайк

Попробуйте частоту 100Гц для первого таймера (и, заодно, ответьте, что делает константа 500 в строке №32?)

Нет, ну с точностью до ошибок, ход мысли понятен. Только, к чему это? Сказать-то Вы что хотели?

В 32 ошибка копи-паста.
Для невозможности получения заданной частоты ставится ещё один #else с предупреждением.
К чему? Ну так вы же считаете что только на плюсах всё делается. С подколами.

Я? Вы меня с кем-то перепутали.

Смотрим оригинальное сообщение, там про реализацию на Си прямо сказано: «я вовсе не говорю, что это невозможно. Возможно, конечно (я – точно смогу ) »

Никогда я не говорил, что это возможно только на плюсе.

Я говорил, что из тех, кто громко кричит, что плюсы не нужны и некошерны, никто этой задачи ещё пока не сделал. Так Вы это и не опровергли – Вы ничего такого не кричали :slight_smile:

Кстати, я бы делал по-другому, я бы делал макросы примерно как у Вас, но через тернарные операции выдавал бы сразу голимое число для его присваивания куда надо. Т.е. в итоге бы писал типа

TCCR1B |= T1_PRESCALER(100) // делитель для 100Гц

Вы понимаете о чём я?

Завтра можно продолжить, сегодня я уже сваливаю :frowning:

да вроде все верно считает

T1_DIV: 8
TCCR1B: 2
OCR1B: 20000

Там в 32-й строке надо

#if F_CPU / 65536 / 1 < FREQ1

Это уже причёс, идея та же.
ПС. Как я понимаю, тут и без препроцессора, сам оптимизатор может привести к такому же виду?

это я, конечно же, поправил

Я не очень понял, что именно имел в виду Евгений, говоря про 100 Гц - явно не эту ошибку, а что-то другое

100 Гц для Таймера 2, очевидно.

Это если исправить ошибку в 32-ой строке, Вы её наверное исправили. А в стартовом посте там 500 вместо FREQ1 и ничего, в итоге, не верно – выдаётся предупреждение и считается чё попало.

Но, это Бог с ним, исправится, подход-то правильный.

Это да. Просто в таком виде, если надо посчитать две разных частоты, там нужны дополнительные телодвижения, а если всё оформить функциональным макросом, то можно сколько угодно считать.

Да, нет, всё классно. Никто никогда не говорил, что это невозможно. На плюсе проще и естественнее (а с шаблонами, так и вообще, “само ложится”), но и здесь можно. Только не так, как в той теме поциент в бреду нёс. Вот как только человек презирает один язык и молится на другой – сто пудов не знает ни того, ни другого. Помнится один ярый фанат “святого асма” убеждал меня, что в нём нет никаких структур. Ткнул носом прямо в ключевое слово struct – стандартный ответ “это другое”.

О… Пятница начинается в понедельник.

Не видел ни одного человека, про которого нельзя было сказать “мнение про него так себе”. Только с делу это отношения не имеет.

3 лайка