Оповещение ATmega32U4 о том, что он подключен к компьютеру (через USB)

Мне нужна помощь в написании кода, который позволит ATmega32U4 знать, когда он подключен к USB-порту. Я действительно не знаком с ATmega32 или с его функциями в Arduino, поэтому я теряюсь в темноте на этом.

Обновление: Итак, Я. Моя схема, uC будет питаться от литий-ионных батарей. На моей печатной плате есть схема зарядки аккумулятора, которая питается от кабеля USB C. Моя цель-реализовать какую-то встроенную программу, которая может различаться, когда плата подключена к сетевой розетке и ноутбуку. Причина этого в том, что я не хочу, чтобы батареи заряжались, когда кабель USB C подключен к ноутбуку.

Второе обновление: Добавлены фотографии ATmega32 вместе с упомянутой схемой зарядки. Я буду напряжением 5 В от USBC для зарядки батарей. Я подключу линии передачи данных на кабель USB C, чтобы я мог программировать микроконтроллер через кабель USB. Моя цель здесь состоит в том, чтобы микроконтроллер распознал, когда он подключен к компьютеру. Когда это произойдет, я поговорю с микросхемой зарядки аккумулятора и скажу ей, чтобы она не заряжалась.

, 👍3

Обсуждение

Обновил свой пост, но ATmega32 будет питаться от литий-ионных батарей. Они будут изменены через разъем USB C, к которому подключены контакты для передачи данных., @Jay

вы могли бы попробовать что-то вроде этого ... если(последовательный) { ledon() } еще { ledoff() } ... посмотрите, изменяет ли состояние светодиода при подключении и отключении USB-кабеля, @jsotola

Вот ссылка на документацию к комментарию jsotolas: https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/, @chrisl

Я не уверен, что вы сможете получить лучший ответ на этот вопрос без деталей (схем и т.д.) На самой плате., @timemage

@timemage Добавил схематическую часть mC и зарядной микросхемы, @Jay

Вам следует узнать больше о вашей зарядной микросхеме (это довольно мощный чип, если он не перегружен), прочитайте техническое описание, у него более одного контакта, которые указывают, является ли источник питания USB или зарядным портом, он также имеет возможность отключить зарядку, когда зарядный ток ниже порогового значения, поэтому, как только вы это поймете, то, что вы пытаетесь сделать, может не понадобиться., @hcheung

@hcheung Проблема в том, что я не верю, что вход тока зарядки всегда будет 500 мА. При подключении к ноутбуку с портом USB C этот порт может выводить до 3A (чего я не хочу, так как не хочу, чтобы перчатки заряжались при подключении к ноутбуку). Я просто пытаюсь понять, может ли uC определить, когда он подключен к USB-порту через линии передачи данных., @Jay

вы пробовали то, что предложил джсотола?, @Juraj

@Juraj Я провел тест и обнаружил, что просто проверка того, есть ли какая-либо активность на UDFNUML, работает для моего приложения из ответа Шреяса. Если MCU отвечает, если есть активность, это нормально для моей прошивки, @Jay

разве оператор bool на последовательном не делает это лучше?, @Juraj

https://github.com/arduino/ArduinoCore-avr/blob/8f8df161ebf3d8bc595d226c3d3a9125383042a5/cores/arduino/CDC.cpp#L245, @Juraj


1 ответ


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

3

Я предполагаю (на самом деле не пробовал), что это сработает, с некоторой незначительной адаптацией в соответствии с вашей структурой кода.

//  VBUS or counting frames
//  Any frame counting?
u8 USBConnected()
{
    u8 f = UDFNUML;
    delay(3);
    return f != UDFNUML;
}

Метод считывает регистр с нижним (байтовым) номером кадра данных UDFNUML - usb, ожидает 3 миллисекунды, что было бы достаточным для получения как минимум еще 1 кадра USB, если устройство действительно было подключено к USB-хосту, снова считывает регистр и проверяет, не произошло ли какое-либо действие USB.

Лично я не большой поклонник подобных задержек в ожидании, потому что процессор можно было бы лучше использовать для выполнения чего-то полезного в этот период (3 миллисекунды на процессоре 16 МГц = 48000 часов ~= 48000 инструкций). Я бы, вероятно, использовал таймер в 1 миллисекунду для выборки регистра и отслеживания состояния USB

Альтернативой может быть использование метода bool USBDevice_::configured() . который реализуется следующим образом

bool USBDevice_::configured()
{
    return _usbConfiguration;
}

//  Endpoint 0 interrupt
ISR(USB_COM_vect)
{
  //    ... snip ...
        else if (SET_CONFIGURATION == r)
        {
            if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
            {
                InitEndpoints();
                _usbConfiguration = setup.wValueL;
            } else
                ok = false;
  // ... snip ....
}

Надеюсь, для вас сработает один из двух подходов...

,