Как сделать конкретную c битовую манипуляцию? - PullRequest
1 голос
/ 17 февраля 2020

Я практикую битовую манипуляцию в arduino со сдвиговым регистром 74HC595.

Я хотел бы создать алгоритм, позволяющий двоичному ди git выполнять таким образом:

1 0 0 0 0 0 0 1

0 1 0 0 0 0 1 0

0 0 1 0 0 1 0 0

.

.

.

1 0 0 0 0 0 0 1

В этом типе функции десятичные значения : (129,66,36 , 24,24,36,66,129) и т. Д. В al oop.

Как я могу выполнить этот тип сдвига? Я не очень бегло думаю об этом типе операций, я только выполнил циклический сдвиг с помощью «алгоритма» вроде:

//my circular shift

myByte = myByte*128 + myByte/2

Но я не знаю, как выполнить вывод, который я показал .

Как я могу это сделать? Спасибо

Ответы [ 3 ]

1 голос
/ 17 февраля 2020

Например, вы можете использовать следующий подход

#include <iostream>
#include <iomanip>
#include <limits>

int main() 
{
    unsigned char b = 0b10000001;
    int width = std::numeric_limits<unsigned char>::digits / 2;

    for ( int i = 0; i < width; i++ )
    {
            std::cout << std::hex << static_cast<int>( b ) << " - "
                      << std::dec << static_cast<int>( b ) << '\n';
            b = ( b & ( 0b1111 << width ) ) >> 1 | ( b & 0b1111 ) << 1;
    }

    for ( int i = 0; i < width; i++ )
    {
            std::cout << std::hex << static_cast<int>( b ) << " - "
                      << std::dec << static_cast<int>( b ) << '\n';
            b = ( b & ( 0b1111 << width ) ) << 1 | ( b & 0b1111 ) >> 1;
    }

    return 0;
}

Выход программы:

81 - 129
42 - 66
24 - 36
18 - 24
18 - 24
24 - 36
42 - 66
81 - 129
1 голос
/ 17 февраля 2020

Вы ищете одну операцию, которая может быть применена к 8-битному числу и приведет к заданному шаблону.

Вы хотите

x_(n+1) = f(x_(n))

для всех заданных входов и выходов , Проблема в том, что есть несколько потенциальных входов, которые имеют один из двух возможных выходов. Вы хотите

36 = f(66)

и

129 = f(66)

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

uint8_t n1 = 128, n2 = 1;
for(;;)
{
    std::cout << n1 | n2 << "\n";
    n1 = circular_right_shift(n1);
    n2 = circular_left_shift(n2);
}
0 голосов
/ 19 февраля 2020

Заметив, что:

129,66,36,24,24,36,66,129 = 128 + 1; 64 + 2; 32 + 4; 16 + 8; 16 + 8; 32 + 4; 64 + 2; 128 + 1;

Я получил этот код:

int latchPin = 11;
int clockPin = 9;
int dataPin = 12;
int dt = 2000;
uint8_t n1 = 128, n2 = 1;
byte myByte = 0b10000001; //in BIN

void setup() {
Serial.begin(9600);
pinMode(latchPin,OUTPUT);
pinMode(dataPin,OUTPUT);
pinMode(clockPin,OUTPUT);
}

//circular shift to the left
void loop() {
digitalWrite(latchPin,LOW);
shiftOut(dataPin,clockPin,LSBFIRST,myByte);
digitalWrite(latchPin,HIGH);
int i;


myByte = 0b10000001; //restarting the value of 129
        Serial.print("BIN: ");
        Serial.print(myByte,BIN);
        Serial.print(" --> ");
        Serial.print("HEX: ");
        Serial.print(myByte,HEX);
        Serial.print(" --> ");
        Serial.print("DEC: ");
        Serial.println(myByte,DEC);
        delay(200);


    for (int i = 0; i < 7; i++) {
        Serial.print("i:  ");
        Serial.println(i);
        //int i1 = i+1;
        //int myGap = myByte - (pow(2,i));      //no need to round when it's raised to 0;
        //int firstpart = (myGap/2);
        //int secondpart = 0.5 + pow(2,i1);     //because it rounds the number. (i.e --> 1.9999 = 1)
        //myByte = firstpart+ secondpart;

          myByte = (myByte - (pow(2,i)))/2 + (0.5 + pow(2,i+1));

        //Serial.print("firstpart: ");
        //Serial.println(firstpart);
        //Serial.print("secondpart: ");
        //Serial.println(secondpart);
        //delay(3000);
        Serial.print("BIN: ");
        Serial.print(myByte,BIN);
        Serial.print(" --> ");
        Serial.print("HEX: ");
        Serial.print(myByte,HEX);
        Serial.print(" --> ");
        Serial.print("DEC: ");
        Serial.println(myByte,DEC);
        digitalWrite(latchPin,LOW);
        shiftOut(dataPin,clockPin,LSBFIRST,myByte);
        digitalWrite(latchPin,HIGH);
        delay(100);
    }
//myByte = myByte*2;    //shift by right //using MSBFIRTS
//delay(dt);
}

И это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...