Как мне сдвинуть биты в C? - PullRequest
3 голосов
/ 08 сентября 2010

Я пытаюсь написать функцию на C, которая будет сдвигать отдельные биты байта на основе тактового сигнала.До сих пор я придумал это ...

void ShiftOutByte (char Data)
{
    int Mask = 1;
    int Bit = 0;
    while(Bit < 8)
    {
        while(ClkPin == LOW);
        DataPin = Data && Mask;
        Mask = Mask * 2;
        Bit++;
    }
}

, где DataPin представляет вывод порта, на который я хочу сместить данные, а ClkPin - вывод тактового порта.

Я хочуустройство сдвинуть на 8 бит, начиная с младшего разряда байта.По какой-то причине мой выходной контакт остается высоким.Я уверен, что контакты порта настроены правильно, так что это чисто логическая проблема.

Ответы [ 3 ]

5 голосов
/ 08 сентября 2010

Вы хотите использовать &, а не &&.&& является логическим и, тогда как & является побитовым и.

3 голосов
/ 08 сентября 2010

Ваше решение почти есть, но есть несколько проблем:

  • Когда часы повышаются, вы выкачаете данные в серии, прежде чем часы снова получат шанс понизиться, поэтому вам нужно сделать паузу, пока часы высокие, прежде чем проверять их низкое значение (если аппаратное обеспечение не приостановит выполнение до часы идут низко). Это можно сделать либо в конце цикла, либо в начале. Я выбрал начало в примере ниже, потому что он позволяет вам вернуться из функции, когда часы еще высоки, и выполнить некоторую обработку, пока она еще высока.
  • Вы использовали логические и (&&) вместо побитового и (&), как указали другие
  • Я не знаком с вашей архитектурой, поэтому не могу сказать, может ли DataPin принимать только 0 или 1. Но это также еще один момент, когда все может пойти не так. Data & Mask вернет бит, сдвинутый влево (1, 2, 4, 8, ...) в зависимости от положения бита.

Итак, в целом, я бы сделал что-то вроде:

void ShiftOutByte (unsigned char Data)
{
    int Bit;
    for(Bit=0; Bit < 8; ++Bit)
    {
        while(ClkPin == HIGH);
        while(ClkPin == LOW);
        DataPin = Data & 1;
        Data >>= 1;
    }
}

Примечание : я использовал цикл for вместо шаблона while ... Bit++ для ясности цели.

1 голос
/ 08 сентября 2010

У вас есть опечатка, которая заменила один оператор другим, который имеет аналогичную функцию. Таким образом, && гарантированно выдаст ответ 1, если оба его операнда логически верны. Поскольку вы почти наверняка тестируете с Data, отличным от нуля, то это относится ко всем восьми итерациям вашего цикла.

Это может быть маскировка более тонкой проблемы. Я не знаю, какова ваша целевая архитектура, но если DataPin является регистром шириной в один бит, то вам, вероятно, следует быть осторожным, чтобы не пытаться присвоить ему значения, отличные от 0 или 1. Один из способов добиться этого - написать DataPin = !!(Data & Mask);. Другой - сдвинуть данные в другом направлении и использовать фиксированную маску 1.

...