Линии пульсируют недостаточно быстро (?))

Должен ли этот код подавать импульсы на контакты PB3 и PB4 (MOSI и MISO Arduino Uno) с интервалом 2 мс?

#include <avr/io.h>

int main(void) 
{

//  for (byte i = 0; i < 32; i++)
//    pinMode(i, INPUT);

  DDRB |= (1 << PB4);       
  DDRB |= (1 << PB3);       
//  pinMode(PB4, OUTPUT);
  while (1)
  {
    PORTB &= ~(1 << PB4);        
    PORTB &= ~(1 << PB3);        
  //  digitalWrite(PB4, LOW);
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//      __asm__ __volatile__("nop");
//    delayMicroseconds(10000);
    delay(1);
    PORTB |= (1 << PB4);        
    PORTB |= (1 << PB3);        
  //  digitalWrite(PB4, LOW);
//    delayMicroseconds(10000);
    delay(1);

  }
}

Если используется для SPI, MOSI вполне может работать на частоте 1 МГц — так говорит мой логический анализатор. MISO не будет работать при использовании SPI. MISO работает и в другом сценарии, отличном от SPI: я могу использовать Arduino для внутрисистемного программирования других плат AVR.

Но приведенный выше код не передает импульсы ни MISO, ни MOSI, как указано тем же логическим анализатором в той же настройке. Должно ли это быть?

обновление

Произошла проблема с доской. Изменил его, и теперь все работает нормально, независимо от использования только int main() или вызова init() в соответствии с ответом @Majенко

, 👍0

Обсуждение

Код выглядит нормально. Вы уверены, что порты чем-то не закорочены и не загнаны откуда-то извне?, @smajli

@smajli, наверное, так и было. Не стесняйтесь превратить комментарий в ответ, @kellogs


1 ответ


2

Код content отлично работает, когда он скомпилирован как программа Arduino, то есть с использованием правильной структуры setup() и loop(). :

void setup() {
    DDRB |= (1 << PB4);       
    DDRB |= (1 << PB3);       
    while (1) {
        PORTB &= ~(1 << PB4);        
        PORTB &= ~(1 << PB3);        
        delay(1);
        PORTB |= (1 << PB4);        
        PORTB |= (1 << PB3);        
        delay(1);
    }
}

void loop() {
}

Однако тот же код не будет работать при использовании его в main(). Это просто потому, что delay() никогда не будет работать. Обычно main() вызывает init(), который затем настраивает TIMER0 для генерации millis() и micros() счетчик, используемый для функций delay().

Поэтому либо используйте setup() и loop() вместо main(), либо вызовите в своей программе init( ) прежде всего:

int main() {

    init();

    DDRB |= (1 << PB4);       
    DDRB |= (1 << PB3);       
    while (1) {
        PORTB &= ~(1 << PB4);        
        PORTB &= ~(1 << PB3);        
        delay(1);
        PORTB |= (1 << PB4);        
        PORTB |= (1 << PB3);        
        delay(1); 
    }
    return 0;
}
,

Имеет смысл. Но это не имело значения. Пробовал и вызов init(), и переключение на setup(). В качестве примечания: когда я уменьшаю задержки, до десятков/сотен микросекунд, в линии MISO начинают появляться сбои. Переход к еще меньшим задержкам приводит к появлению некоторых (меньших) сбоев в MOSI., @kellogs

Тогда ваша плата, вероятно, сломана или что-то в этом роде, потому что этот код *действительно* работает. Я проверил это. Это сработало., @Majenko

Да что-то подобное. Интересно, почему линии работают нормально, когда они используются в качестве интернет-провайдера на скорости 19200 бод, но не при импульсной передаче с такой же скоростью вручную. Я отправляюсь на новые расследования., @kellogs