Не работает код для сдвигового регистра

Тема в разделе "Arduino & Shields", создана пользователем Secret Cipher, 25 июл 2017.

  1. Secret Cipher

    Secret Cipher Нуб

    Написал программу для программирования сдвигового регистра без shiftOut.
    Код (C++):
    int latch = 12;
    int data = 8;
    int cloc = 4;
    int i;
    void sendBitToReg(boolean bi) {
      digitalWrite(data, bi);
      digitalWrite(cloc, HIGH);
      digitalWrite(cloc, LOW);
    }
    void sendByteToReg(String by) {
      for (i = 0; 1 < 8; i++) {
        if (by[i] == "1") {
          sendBitToReg(HIGH);
        }
        else {
          sendBitToReg(LOW);
        }
      }
    }
    void setup() {
      Serial.begin(9600);
      pinMode(data, OUTPUT);
      pinMode(latch, OUTPUT);
      pinMode(cloc, OUTPUT);
    }
    void loop() {
      for (i = 1; i < 5; i++) {
        digitalWrite(cloc, LOW);
        digitalWrite(latch, LOW);
        Serial.println(i);
        sendByteToReg("01101001");
        digitalWrite(latch, HIGH);
        delay(200);
      }
    }
    Программа загружается, но светодиоды не загораются. В монитор порта выходит лишь одна 1. Если убрать "sendByteToReg("01101001");", то в монитор идут числа.
    Во время загрузки возникает такая ошибка: (программа всё равно загружается)

    C:\Users\Timofey\Documents\Arduino\sketch_jul25f\sketch_jul25f.ino: In function 'void sendByteToReg(String)':

    C:\Users\Timofey\Documents\Arduino\sketch_jul25f\sketch_jul25f.ino:12:18: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

    if (by == "1") {

    ^

    Помогите, пожалуйста устранить ошибку в коде.
     
  2. Igor68

    Igor68 Гуру

    Простите, а что значит
    Код (C++):

    if (by[i] == "1") {
     
    Это не так! Даже не пойму с разбега... вроде как сравнение числового значения с символом из строки "1". Был бы хотя бы код символа '1' а не "1". Глубоко в примочки Arduino IDE не влазил, но в Си так нельзя. Потому как '1' = 0x31 тоесть код символа. А понятие "1" в этом смысле неприемлемо.
     
    9xA59kK нравится это.
  3. ostrov

    ostrov Гуру

    А смысл избавляться от shiftOut через digitalWrite? Так еще медленнее. Делайте через порты, тогда разница будет неслабая.
     
  4. Secret Cipher

    Secret Cipher Нуб

    Написал
    Код (C++):
    if (by[i] == 0x32)
    Ошибка компилятора исчезла, но на деле ничего не изменилось
     
  5. Secret Cipher

    Secret Cipher Нуб

    shiftOut может работать только с одним регистром, а я хотел впоследствии подключить больше.
     
  6. Igor68

    Igor68 Гуру

    Вы это что ??? я же указал что 0x31 это код единицы (можете поставить '1' вместо числового значения), а Вы применяете 0x32 - а это код символа два ('2'). Вы вроде как строку из нулей и единичек разбираете.
     
  7. Secret Cipher

    Secret Cipher Нуб

    Ой, перепутал
     
  8. Secret Cipher

    Secret Cipher Нуб

    Но в программе 0x31 стояло и не работало
     
  9. Limoney

    Limoney Гик

    сдвиговые регистры можно подключать друг к другу
     
  10. ostrov

    ostrov Гуру

    Да хоть с миллионом. Он просто запихивает байт побитно как и ваша процедура.
     
  11. Secret Cipher

    Secret Cipher Нуб

    Я пытался работать с двумя. Насколько я помню, до восьми бит - оба регистра одинаковы, более - пустые. Возможно в первом случае второй показывает то же, что первый показывал раньше.
     
  12. Limoney

    Limoney Гик

    Это нормально биты переходят с одного сдвигового регистра в второй сдвиговый регистр
     
    Igor68 нравится это.
  13. Igor68

    Igor68 Гуру

    Простите! Думаю после добавления задержек после смены уровня (не говорю, что оптимально) поможет.
    1) установили уровень данных
    2) установили уровень тактирования
    3) сброс уровня тактирования
    Между ними всё-таки время надо... порты больно шустрые для регистра и монтажа.
    Ради эксперимента попробуйте... ну или следуйте совету других (тут уже говорили)
     
  14. ostrov

    ostrov Гуру

    Сцепили регистры каскадом, открыли защелку, напихали биты паравозиком по числу регистров, закрыли защелку.
     
    Igor68 нравится это.
  15. mcureenab

    mcureenab Гуру

    Это не так. shiftOut умеет работать с октетом ( 8 бит ), но shiftOut не работает с защелкой. Эта функция не знает сколько регистров подключены каскадом. Их может быть от 0 до бесконечности.

    Можно закрыть защелку, отправить в каскад регистров сколько угодно байтов и в конце сеанса открыть защелку. Только тогда загруженные биты появятся на D выходах микросхем.
     
  16. railmisaka

    railmisaka Гик

    Честно говоря, не особо понял, что хотел сказать автор, но он прав в том, что "1" и '1' вовсе не одно и то же.

    вам на будущее, учитесь понимать выброс компилятора, он честно сказал
    Код (C++):
     ISO C++ forbids comparison between pointer and integer
    (это кстати не ошибка, а предупреждение, поэтому и собирается) - сравнение указателя и целого числа

    '1' (одинарные кавычки) это char, целочисленный тип. к которому и приводятся ваши 0x31 и который, судя по всему, и нужен.
    "1" (двойные кавычки) это char*, тип указателя. с ним сравниваться не имеет вообще никакого смысла. тем более сравнивать целочисленный тип с типом указателя.

    и, как по мне, использовать 0x31 вместо '1' не стоит, читаемость падает.
     
    Последнее редактирование: 25 июл 2017
  17. railmisaka

    railmisaka Гик

    еще ошибка в условии 1<8 -> i<8

    вот эта проблема скорее всего из-за этого - бесконечный цикл
     
    Secret Cipher нравится это.
  18. railmisaka

    railmisaka Гик

    на счет этого.. создается впечатление, что вы не понимаете, как пропихиваются значения. для объединения регистров в каскад на них есть специальный пин.
     
  19. Secret Cipher

    Secret Cipher Нуб

    Так действительно удобнее, просто я не работал в чистом c++ и лишь следовал указаниям.

    Действительно, не заметил. Именно такой помощи я ждал. Программа стала включать светодиоды, но в Serial.println вводились только единицы. Но тут уж я сам понял, что в void sendByteToReg нужна отдельная переменная i. Вот готовый вариант программы:
    Код (C++):
    int latch = 12;
    int data = 8;
    int cloc = 4;
    int i;
    void sendBitToReg(boolean bi) {
      digitalWrite(data, bi);
      digitalWrite(cloc, HIGH);
      digitalWrite(cloc, LOW);
    }
    void sendByteToReg(String by) {
      int i;
      for (i = 0; i < 8; i++) {
        if (by[i] == '1') {
          sendBitToReg(HIGH);
        }
        else {
          sendBitToReg(LOW);
        }
      }
    }
    void setup() {
      pinMode(data, OUTPUT);
      pinMode(latch, OUTPUT);
      pinMode(cloc, OUTPUT);
    }
    void loop() {
        digitalWrite(cloc, LOW);
        digitalWrite(latch, LOW);
        sendByteToReg("01101001");
        digitalWrite(latch, HIGH);
        delay(200);
    }
    А с shiftOut я ещё разберусь.
     
  20. railmisaka

    railmisaka Гик

    Это не C++, это чистый Си.

    А вот этого уже я не заметил.
    Мой вам совет, раз вы не в ладах с программированием, когда у вас есть цикл, объявляйте счетчики в той же функции.