Циклический сдвиг битов

Тема в разделе "Arduino & Shields", создана пользователем Eragon, 23 апр 2017.

  1. mcureenab

    mcureenab Гуру

    Какой у вас индикатор?
     
  2. Eragon

    Eragon Нерд

    Вот даташит http://www.platan.ru/pdf/datasheets/Kingbright/cc5621srwa.pdf сегменты подключены через сдвиговый регистр, разряды напрямую.
     
  3. Eragon

    Eragon Нерд

    Не работает(( Горят только те, которые заданы при объявлении MyVar
     
  4. mcureenab

    mcureenab Гуру

    У меня на micro это работает. Только вместо одного светодиода на шкале мигает светодиод TX LED на плате.

     
  5. mcureenab

    mcureenab Гуру

    Да вы суровый Челябинский программист!!! )))

    Этот индикатор нужно регулярно обновлять. Никаких задержек не может быть.
     
  6. Eragon

    Eragon Нерд

    Не совсем челябинский, но очень близко)) Это же семисегментник и индикация динамическая! И всё же скеч написан и он работает:) Ещё собираюсь установку времени и будильника добавлять...
     
  7. Eragon

    Eragon Нерд

    Код (C++):
     // Arduino UNO pins 0 - 7
    inline uint8_t ROL(uint8_t x)
    {
        return((x&0x80)>>7)|(x<<1);
    }

    void setup() {
    //    Serial.begin(250000);
    //    while(!Serial){};
    //    Serial.println("Staring...");
        DDRD = 0b11111111; // OUTPUT 0 - 7 pins
    }

    void loop() {
      static uint8_t MyVar = 0b00000001;
      PORTD = MyVar; // Переключаем пины 0, ..., 7
      MyVar = ROL(MyVar);
      delay(200);
    }
     
    Я пробовал этот код, работает)) Но вроде был разговор, что для массива он не подходит!? Или можно приспособить???
     
  8. mcureenab

    mcureenab Гуру

    Это как из Москвы в Питер через Магадан ехать.
    Положим, если биты байта раскидать на 8 циклических регистров, то можно прокручивать все регистры на 1 шаг, а затем читать, например 0е биты и отправлять на 1й разряд индикатора, 1е биты на 2й разряд и т.д.
    Наверное мутно объяснил. Но неохота расписывать явно бредовый подход.
     
  9. mcureenab

    mcureenab Гуру

    Допилил код с циклическим выводом.

    Код (C++):
    class Iterator {
    public:
        Iterator( uint8_t i_start): pos(i_start) { if ( size <= pos ) pos = 0;  }
        Iterator& operator++() { if ( size <= ++pos ) pos = 0; return *this; }
    //    Iterator operator++(uint8_t) { Iterator res(*this); operator++(); return res; }
        operator uint8_t() const { return pos; }
    private:
        static const uint8_t size;
        uint8_t pos;
    };

    const static uint8_t ASZ = 16 + 1; // 4 пробелы, 4 - температура, 4 пробелы, 4 влажность, \0.

    const uint8_t Iterator::size = ASZ;

    char arr[ASZ] = "    ....    ...."; // Строка для вывода в окно.


    void SetPos(int pos)
    {
      Serial.println();
    }

    void PrintCell(char ch)
    {
      Serial.print(ch);
    }

    void setup()
    {
        Serial.begin(250000);
        while(!Serial){};
        Serial.println("Staring...");
        memcpy( arr + 4, "1234", 4);
        memcpy( arr + 12, "5678", 4);
    }

    void loop() {
        static Iterator pos(0); // Позиция окна вывода в строке arr.
        SetPos(0); // позиция печати
        Iterator i(pos);
        for ( uint8_t n(5); --n; ++i )
        { // Выводим в окно из (5-1)=4х символов
            PrintCell(arr[i]); // печать символа и сдвиг в следующую позицию
        }
        ++pos; // Продвигаем окно
        delay(500);
    }

    Код (Text):

    Staring...

     
       1
      12
    123
    1234
    234
    34
    4
     
       5
      56
    567
    5678
    678
    78
    8

     
       1
      12
    123
    1234
    234
    34
    4
     

     
     
    Последнее редактирование: 28 апр 2017
  10. Eragon

    Eragon Нерд

    В итоге всего вышесказанного, можно сделать вывод о том, что не стоит на данном этапе лезть в сдвиг массива:D
     
  11. Eragon

    Eragon Нерд

    Спасибо, возьму на заметку. Но с классами я ещё не разбирался. Только структуры начал изучать...)
     
  12. mcureenab

    mcureenab Гуру

    Структура, это частный случай класса.

    Код (C++):
    struct Iterator {
    public:
        Iterator( uint8_t i_start): pos(i_start) { if ( size <= pos ) pos = 0;  }
        Iterator& operator++() { if ( size <= ++pos ) pos = 0; return *this; }
    //    Iterator operator++(uint8_t) { Iterator res(*this); operator++(); return res; }
        operator uint8_t() const { return pos; }
    private:
        static const uint8_t size;
        uint8_t pos;
    } ;

    const static uint8_t ASZ = 16 + 1; // 4 пробелы, 4 - температура, 4 пробелы, 4 влажность, \0.

    const uint8_t Iterator::size = ASZ;

    char arr[ASZ] = "    ....    ...."; // Строка для вывода в окно.


    void SetPos(int pos)
    {
      Serial.println();
    }

    void PrintCell(char ch)
    {
      Serial.print(ch);
    }

    void setup()
    {
        Serial.begin(250000);
        while(!Serial){};
        Serial.println("Staring...");
        memcpy( arr + 4, "1234", 4);
        memcpy( arr + 12, "5678", 4);
    }

    void loop() {
        static Iterator pos(0); // Позиция окна вывода в строке arr.
        SetPos(0); // позиция печати
        Iterator i(pos);
        for ( uint8_t n(5); --n; ++i )
        { // Выводим в окно из (5-1)=4х символов
            PrintCell(arr[i]); // печать символа и сдвиг в следующую позицию
        }
        ++pos; // Продвигаем окно
        delay(500);
    }
     
  13. Eragon

    Eragon Нерд

    Да... ещё учится и учится....
     
  14. Eragon

    Eragon Нерд

    А осуществить сдвиг элементов массива на 4 символа, просто чтобы остался пустой экран тоже сложно? Или можно как-нибудь проще, без структур и классов?
     
  15. mcureenab

    mcureenab Гуру

    Можно и так. Только буфер со строкой будет одноразовым. Т.е. после каждого цикла его нужно будет заново пропечатывать числами. И вообще придется пользоваться небезопасными операциями.

    Код (C++):
    const static uint8_t ASZ = 17; // 4 пробелы, 4 - температура, 4 пробелы, 4 влажность, 1 пробел заполнитель \0.

    char arr[ASZ];

    void SetPos(int pos)
    {
      Serial.println();
    }

    void PrintCell(char ch)
    {
      Serial.print(ch);
    }

    void setup()
    {
        Serial.begin(250000);
        while(!Serial){};
        Serial.println("Staring...");
    }

    void loop() {
        static uint8_t pos(0); // Позиция окна вывода в строке arr.
        SetPos(0); // позиция печати
        if( !pos ) // новый цикл прокрутки буфера
        {
            memcpy( arr, "    ....    .... ", ASZ); // Строка для вывода в окно.
            memcpy( arr + 4, "1234", 4); // Число 1
            memcpy( arr + 12, "5678", 4); // Число 2
        }
        char * p = arr;
        for ( uint8_t n(5); --n; ++p )
        { // Выводим в окно из (5-1)=4х символов
            PrintCell(*p); // печать символа и сдвиг в следующую позицию
        }
        memmove(arr, arr+1, ASZ-1); // Сдвигаем массив
        ++pos;
        if( ASZ <= pos ) pos = 0;
        delay(500);
    }
     

    Код (Text):
    Staring...

       
       1
      12
    123
    1234
    234
    34
    4  
       
       5
      56
    567
    5678
    678
    78
    8  
       
       
       1
      12
    123
    1234
    234
    34
    4  
       
     
  16. Eragon

    Eragon Нерд

    Спасибо:) Буду думать, что со всем этим делать)
     
  17. mcureenab

    mcureenab Гуру

    С такой модификацией буфер заворачивается в кольцо.
    Код (C++):

        arr[ASZ-1] = arr[0]; // Закольцевали буфер
        memmove(arr, arr+1, ASZ-1); // Сдвигаем массив
     
     
  18. Eragon

    Eragon Нерд

    memmove, memcpy - подобные функции первый раз вижу)))
     
  19. mcureenab

    mcureenab Гуру

    Стандартная библиотека C.

    Они делают одно и то же, но memmove умеет правильно копировать когда области памяти перекрываются.

    Надежнее, конечно, использовать коллекции из библиотеки шаблонов. Но вы до нее ещё не добрались.
     
  20. Eragon

    Eragon Нерд

    Это точно!:D Рано мне ещё с таим дело иметь!