Странный эффект AVR C на последовательную связь USB

Недавно я решил изучить прямое управление портами вместо встроенных подпрограмм Arduino.

Сначала я попробовал этот фрагмент кода

void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
Serial.println("on");
delay(500);                  
digitalWrite(LED_BUILTIN, LOW);   
Serial.println("off");
delay(500);                       
} 

Эта программа при запуске мгновенно установила соединение с последовательным монитором в моей IDE Arduino.

Но когда я пробую этот код

int main(void)
{
Serial.begin(9600);
DDRB = B11111111;
while(1)
{
PORTB = PORTB | 0x20;
Serial.println("off");
_delay_ms(500);
PORTB = PORTB & 0xDF;
Serial.println("on");
_delay_ms(500);
}
}

Но этой программе требуется некоторое время, около 5-10 секунд, чтобы установить последовательное соединение. Также delay() тоже не работает. Когда я использую delay() вместо _delay_ms(), вся плата arduino зависает, как компьютер, и светодиод перестает мигать, а вместо этого полностью горит.

Я попробовал это в нескольких программах, пока "настройка цикла" программа подключается мгновенно, программы AVR C - нет.

почему это происходит?

, 👍0

Обсуждение

Потому что обычно main() инициализирует все необходимое оборудование и таймеры. Вы обходите это своим собственным main(), так что Ardunioy ничего не работает., @Majenko

Я был бы очень признателен, если бы вы могли уточнить это в ответе., @ASWIN VENU

пожалуйста, сделайте правильный отступ в своем коде .... новичкам, которые могут просматривать вопросы, должен быть предоставлен правильно отформатированный код, независимо от того, насколько прост листинг кода., @jsotola


1 ответ


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

2

Определяя свой собственный main(), вы обходите процедуры запуска Arduino.

Обычно с кодом Arduino main() сначала запускает функцию init() перед setup() и (неоднократно) loop (). Эта функция init(), среди прочего, настроит таймер для millis() и delay().

Это обычный main() для базовой платы на основе AVR:

int main(void)
{
    init();

    initVariant();

#if defined(USBCON)
    USBDevice.attach();
#endif
    
    setup();
    
    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }   
     
    return 0;
}

Сначала инициализируются общие функции, затем специфические для платы (обычно ничего) и, если применимо, интерфейс USB (для плат на базе ATMega32U4, таких как Leonardo).

Только после этого он запускает ваш скетч.

Если вы хотите использовать как свои собственные функции main(), так и функции Arduino, такие как delay(), вам придется вызывать эти процедуры инициализации перед запуском остальных ваших функций. код.

,

Не могли бы вы объяснить значение «serialEventRun»?, @ASWIN VENU

Если вы не определили функцию serialEvent(), то она вообще не имеет значения. Если вы определили его, он запускает его., @Majenko

Какова цель initVariant()?, @ASWIN VENU

Это тот момент, когда я говорю «затем специфичные для платы (обычно ничего)»., @Majenko

Я только что переписал свой код, чтобы включить только init() и ничего больше, теперь работает последовательная связь, чтение и запись. Итак, мой вопрос: USBDevice.attach() необходимый?, @ASWIN VENU

Только если вы используете ATMega32U4 или аналогичный чип, где USB является настоящим USB-соединением, а не соединением UART через мостовой чип USB., @Majenko

Давайте [продолжим это обсуждение в чате](https://chat.stackexchange.com/rooms/111596/discussion-between-aswin-venu-and-majenko)., @ASWIN VENU