Shiftout обрабатывает только один сдвиговый регистр за раз

Я делаю светодиодную матрицу 7x10, и у меня возникли проблемы с функцией сдвига. Он может показать мне вывод только в одном сдвиговом регистре за раз. Как я могу это исправить?

Например:

void setup(){
    // PORTB в качестве вывода.
    // Контакт 13: Часы 74HC595
    // Контакт 12: защелка
    // Контакт 11: Данные
    // Контакт 10: сброс
    // Пин 9: Часы CD4017
    DDRB = 0b111111;
    // Проверяем, что значение 4017 равно 0.
    PORTB = 0b100;
    delayMicroseconds(5);
    PORTB = 0;
}

void loop(){
  shiftOut(11, 13, LSBFIRST, 0b1000111101);
  PORTB = 0b10000;
  delayMicroseconds(800);
  PORTB = 0;
  delay(10000);
}

Вот что он выдает:

Но с числами 8 бит или меньше выходные данные отображаются правильно.

shiftOut(11, 13, LSBFIRST, 0b10001111);

, 👍0


2 ответа


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

1

shiftOut работает с байтами. Чтобы сделать более одного байта, вам нужно сделать более одного shiftOut. Также вы должны принять к сведению порядок битов. Вы должны сначала сдвинуть самый значащий бит, а не последний.

Например, это:

  shiftOut(11, 13, LSBFIRST, 0b1000111101);

должно быть:

  shiftOut(11, 13, MSBFIRST, 0b10);
  shiftOut(11, 13, MSBFIRST, 0b00111101);
,

Происходит то же самое, в данном случае загорается только шестой светодиод первого ряда., @Lucio Mazzini

Что бы это могло быть? :(, @Lucio Mazzini

Я думаю, что это неправильный порядок битов. Использовать MSBFIRST, а не LSBFIRST?, @Majenko

Он все равно работает некорректно, в данном случае на светодиодах выдается 1011110000. Может это симулятор?, @Lucio Mazzini

Я только что закончил делать свою плату, я загрузил программу с двумя сдвигами, и вывод отобразился правильно, это проблема симулятора. Спасибо за помощь., @Lucio Mazzini


2

Посмотрите на реализацию shiftOut() (ее можно найти там, где вы установили среду разработки Arduino, в файле hardware/arduino/avr/cores/arduino/wiring_shift.c). ):

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
  uint8_t i;

  for (i = 0; i < 8; i++)  {
    if (bitOrder == LSBFIRST) {
      digitalWrite(dataPin, val & 1);
      val >>= 1;
    } else {
      digitalWrite(dataPin, (val & 128) != 0);
      val <<= 1;
    }

    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
}

Вы видите, что значение (параметр val) имеет тип uint8_t, то есть всего 1 байт? И вы видите, что цикл for считает только до 8 (одна итерация для каждого бита в байте)? Это означает, что функция shiftOut() обрабатывает только один байт за раз. Если вы хотите сдвинуть больше битов, чем 8, вам нужно вызывать его повторно.

В первом примере код ведет себя соответствующим образом. Предоставленные данные преобразуются в uint8_t, отрезая 2 старших бита.

,

Я пытался отправить два shiftout, но все равно происходит то же самое :/, @Lucio Mazzini

Может это симулятор?, @Lucio Mazzini

Да, возможно, симулятор не обрабатывает вывод дополнительных сдвиговых данных в следующий сдвиговый регистр. Хотя это то, на что вам может ответить только создатель программного обеспечения симулятора., @chrisl

Я только что закончил делать свою плату, я загрузил программу с двумя сдвигами, и вывод отобразился правильно, это проблема симулятора. Спасибо за помощь., @Lucio Mazzini