Что позволяет этой библиотеке работать исключительно с платами Atmega328P?

Я искал библиотеки, считывающие сигналы CPPM, которые я могу использовать на своем Arduino Pro Micro, и это выглядело многообещающе (github.com/jmparatte/CPPM), пока не прочитал, что он работает только на чипах Atmega328P. Конечно же, я попробовал, и на Pro Micro он работает не так, как на моем Arduino Uno. Почему это так, то есть, что есть такого, чего нет у Atmega32u4?

Реализация

Эта библиотека работает только с реализацией Arduino UNO ATmega328, Дуемилланове и ему подобные, а также Леонардо. Он использует 16-битный таймер1. Так Аналоговая запись PWM() на контактах 9 и 10 недоступна. Библиотека Серво несовместим, поскольку также использует Timer1.

Я пытался провести небольшое исследование самостоятельно, но безрезультатно:

  • Таймер1 не относится к 328P , в 32u4 есть
  • Насколько я могу судить, нет никакой разницы в возможностях прерываний 32u4...
  • ICR1 и TCNT — это опять же функции, которыми обладает 32u4
  • Мой сигнал подключен к выводу OC1A, который используется как источник CPPM (контакт 9, PB5)

Я новичок в подобных вещах и совершенно не понимаю, в чем здесь может быть проблема.

, 👍0


1 ответ


Лучший ответ:

1

Эта библиотека в основном использует Таймер 1 и, как вы уже заметили, Таймер 1 ATmega32U4 очень похож, если не идентичен, на тот из 328P. По крайней мере, достаточно похоже, чтобы ожидать, что библиотека работают одинаково.

Я просмотрел обе таблицы данных и вижу единственную разницу: Возможно, на библиотеку может повлиять распиновка. Контакты, относящиеся к библиотека:

       328P  32U4
ICP1 =  PB0   PD4
OC1A =  PB1   PB5

Распиновка 328P жестко запрограммирована в библиотеке. CPPM.h содержит эти строки:

#define CPPM_ICP1 8 // Входной контакт захвата Arduino UNO — это контакт 8 — ICP1 (Atmega328 PB0)
#define CPPM_OC1A 9 // Вывод сравнения выходов Arduino UNO — это вывод 9 — OC1A (Atmega328 PB1)

CPPM.cpp имеет два экземпляра (здесь и здесь) из этого:

if ((PINB & _BV(PINB1))) // нарастающий фронт ?

Если вы измените код в этих трех местах, чтобы он соответствовал распиновке 32U4, я надеюсь, что библиотека вам подойдет.

Вы также можете изменить это условно, как

#ifdef __AVR_ATmega32U4__
    ...
#else // предположим, что это ATmega328P
    ...
#endif

чтобы сделать библиотеку совместимой с обоими микроконтроллерами, а затем отправить запрос на включение исходному автору.

,

Отлично, когда я доберусь до этого сегодня, я попробую внести это изменение. Спасибо за теорию!, @ifconfig

Подождите, а чем мне заменить часть «PINB»?, @ifconfig

@ifconfig: PINB & _BV(PINB1) проверяет состояние контакта PB1, который на 328P совпадает с состоянием OC1A. На 32U4 вы должны использовать OC1A = PB5 для той же цели. Затем тест становится PINB & _BV(PINB5)., @Edgar Bonet