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

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

  1. Igor68

    Igor68 Гуру

    Код (C++):

    uint8_t  MyVar = 0b10110010;
    uint8_t  k;
    while(1)
    {
        if(MyVar & 0x80)
           k=1;
        else
           k=0;
        MyVar = MyVar << 1;
        MyVar |= k;
    }
     
     
  2. Eragon

    Eragon Нерд

    Ну да, можно просто скопировать и вставить и будет оно работать, но есть желание саму суть процесса понять чтобы использовать с своих проектах. Вот тут http://arduino.ua/ru/prog/Bitshift что то похожее, но надо пробовать это зациклить,
     
  3. Eragon

    Eragon Нерд

    Т.е чтобы этот код применить к портам нужно внутри MyVar объявить номера пинов? Или по другому???
     
  4. Unixon

    Unixon Оракул Модератор

    Код (C++):

    #define RLC8(x) (((x&0x80)>>7)|(x<<1))
    #define RRC8(x) (((x&0x01)<<7)|(x>>1))
     
    Интересно, GCC свернет в одну инструкцию?
     
  5. mcureenab

    mcureenab Гуру

    Можно просто записать MyVar в регист портов. Сразу 8 пинов переключить. Вернусь домой, нарисую. Это уже без ассемблера.
     
  6. mcureenab

    mcureenab Гуру

    Одной инструкции нет. У меня три получилось.
     
  7. Eragon

    Eragon Нерд

    Спасибо, сразу 8 переключать не нужно, изначально планировалось 3-4 штуки зажечь и гонять их как по конвейеру....
     
  8. ostrov

    ostrov Гуру

    Ничто не мешает считывать выталкиваемый бит до и вставлять в начало его после сдвига. Это можно сделать 1-2 строками.
     
  9. Eragon

    Eragon Нерд

    Это я и хочу реализовать, только не доходит как...(((
     
  10. ostrov

    ostrov Гуру

    Сколько битов должно быть?
     
  11. Eragon

    Eragon Нерд

    Символов 4 штуки displayBuffer[2][4] Я для начала хотел на светодиодах потренироваться, пускай их 8 штук будет)
     
  12. mcureenab

    mcureenab Гуру

    Код (C++):
    uint8_t inline ROL(uint8_t MyVar)
    {
      asm ("mov __tmp_reg__, %[v0] \n rol __tmp_reg__ \n rol %[v0] \n" : [v0] "+r" (MyVar) );
      return MyVar;
    }

    static const uint8_t bit_pin [] = {3, 4, 5, 6, 7, 8, 9, 10 };

    void setup() {
        Serial.begin(250000);
        while(!Serial){};
        Serial.println("Staring...");
        for( int8_t i = sizeof(bit_pin); i--; ) {
            Serial.println(String(":") + i + " " + bit_pin[i] );
            pinMode(bit_pin[i], OUTPUT);
        }
    }

    void loop() {
      static uint8_t MyVar = 0b00000001;
    //  Serial.println(MyVar);
      uint8_t v(MyVar);
      for( int8_t i = sizeof(bit_pin); i--; ) {
          digitalWrite(bit_pin[i], v & 0b1 ? HIGH : LOW );
          v >>= 1;
      }
      MyVar = ROL(MyVar);
      delay(200);
    }

     
     
  13. Eragon

    Eragon Нерд

    Благодарю!, но всё же, опять ассемблер, неужели без него это не пишется!?
     
  14. mcureenab

    mcureenab Гуру

    На Arduino Leonardo не получилось сделать

    Код (C++):
    PORTD = MyVar;
    или
    Код (C++):
    PORTB = MyVar;
    Пины PD5 и PB0 МК заведен на TX/RX LED. А остальные порты меньше 8 пинов поддерживают.

    https://www.arduino.cc/en/Hacking/PinMapping32u4
     
  15. mcureenab

    mcureenab Гуру

    Уже написали

    Лучше через inline функции сделать
    Код (C++):
    inline uint8_t RLC8(uint8_t x)
    {
      return ((x&0x80)>>7)|(x<<1);
    }
     
     
  16. mcureenab

    mcureenab Гуру

    На Arduino UNO можно гораздо проще сделать:

    https://www.arduino.cc/en/Hacking/PinMapping168

    Код (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);
    }
     
     
    Последнее редактирование: 27 апр 2017
  17. AlexU

    AlexU Гуру

    В контексте AVR не свернёт, т.к. нет инструкции сдвига на несколько бит. Будет цикл со сдвигом на один бит. Поэтому операцию сдвига в микроконтроллерах типа ATmega328 "дешевле" заменить на операцию умножения, которая занимает всего два такта, в отличие от сдвига "в цикле".
     
  18. Eragon

    Eragon Нерд

    А можно подробнее, что Вы имейте ввиду.
     
  19. mcureenab

    mcureenab Гуру



     
  20. Eragon

    Eragon Нерд

    Так я и делаю на УНЕ )) Можно ещё объяснить,что в первых 5 строчках происходит...