Как управлять выводом регистров сдвига по отдельности побитово
поэтому я работаю над проектом, который требует большого количества битовых манипуляций и смещения битов для индивидуального управления выводами регистров сдвига.
Поэтому я использую 2 регистра сдвига, соединенных цепочкой с 16 светодиодами. Теперь я хочу, чтобы я управлял светодиодами по отдельности, просто перемещая биты
вот что я попробовал
первая попытка
int latchPin = 4; // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 5; // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 3; // Data pin of 74HC595 is connected to Digital pin 4
byte leds=0b1000000000000001; // byte has 16 bits
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
updateShiftRegister();
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
Не работает! 2 - й регистр сдвига, похоже, копирует первый регистр сдвига, который мне не нужен
Во второй попытке я попробовал метод маскировки с шестнадцатеричным типом данных. Вот оно.
int latchPin = 4; // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 5; // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 3; // Data pin of 74HC595 is connected to Digital pin 4
byte leds=0xFFFF & 0x8001; // used hex masking method
// 0xFFFF = 1111111111111111
// 0x8001 = 1000000000000001
// After & it should be 1000000000000001
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
updateShiftRegister();
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, leds);
digitalWrite(latchPin, HIGH);
}
Это тоже дает тот же эффект, что и попытка 1 выше.
Теперь вот чего я хочу и в чем нуждаюсь...
byte leds = 0b1000000000000001
/* As you can see the index 0 and index 15 of the byte led
is set 1 or high which should produce +ve to the 15th pin of first register and 8th pin of second register.
но всякий раз, когда я пытаюсь это сделать, кажется, что один из регистров копирует другой.
Итак, есть ли какой-либо способ смещения битов для индивидуального управления выходами регистра сдвига?
если да, то, пожалуйста, приведите четкий пример кода с четким объяснением.
если нет, то , пожалуйста, предложите мне несколько альтернативных способов, которые можно использовать так же, как я хочу, конечно, с примером кода и объяснением.
Схема: arduino.cc/en/Tutorial/Foundations/ShiftOut
Большое Вам спасибо за ваше драгоценное время.
С нетерпением жду ваших ответов .
:)
2 ответа
Лучший ответ:
У вас есть две проблемы с вашим кодом:
byte
равенсимволу
без знака и может содержать только ровно один байт, он же 8 бит (а не 16 бит, как говорится в вашем комментарии). Но вы пытаетесь присвоить ему 16-битный номер. В этом процессе вырезаются верхние 8 бит. Они заблудились. Если вы хотите сохранить 16-битное число, вам необходимо использовать тип данных размером не менее 16 бит, напримерuint16_t
(или вы можете использоватьunsigned int
, хотя в таких ситуациях часто лучше использовать тип, который имеет одинаковый размер на всех платформах).uint16_t leds = 0b1000000000000001;
Функция
shiftOut()
имеет это объявление в wiring_shift.c:void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
Вы можете видеть, что
val
(то есть данные, которые должны быть сдвинуты) имеет типuint8_t
, такой же, какbyte
, который также может содержать только 8 бит. Верхние 8 бит 16-битного значения будут отключены, и функция также просто передает 8 бит, не более того (когда вы посмотрите на ее реализацию в упомянутом файле, вы увидите цикл for с 8 в качестве предела).Вместо этого вы должны вызывать эту функцию для каждого байта, который вы хотите передать в одной передаче; в вашем случае 2 раза, потому что у вас 2 регистра сдвига.
Таким образом, полученная программа будет выглядеть примерно так:
int latchPin = 4; // Latch pin of 74HC595 is connected to Digital pin 5
int clockPin = 5; // Clock pin of 74HC595 is connected to Digital pin 6
int dataPin = 3; // Data pin of 74HC595 is connected to Digital pin 4
uint16_t leds=0b1000000000000001; // uint16_t has 16 bits
void setup()
{
pinMode(latchPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
updateShiftRegister();
}
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
// Shiftout lower byte by masking the other byte with bitwise AND (&)
shiftOut(dataPin, clockPin, LSBFIRST, leds & 0xFF);
// Shiftout higher byte by shifting the bit pattern 8 bits to the right
// resulting in the high byte getting to the position of the low byte
// and then masking away anything else than the new position of the high
// byte data
shiftOut(dataPin, clockPin, LSBFIRST, (leds >> 8) & 0xFF);
digitalWrite(latchPin, HIGH);
}
Обратите внимание, что маскировка с помощью побитового оператора И здесь на самом деле не нужна, но мне нравится делать такие вещи явно, чтобы сделать это более понятным.
Поэтому мне нужно сохранить почти 50 бит в переменной, чтобы управлять столбцами, так может ли метод "uint" быть полезным в этом случае ?
В этом случае я бы использовал массив байтов для хранения данных. При 50 битах вы получаете 6,25 или 7 байт (так как у вас не может быть суббайтов). Декларация будет выглядеть примерно так:
byte leds[] = {0b00011001, ... }; // list the byte data here
А затем вы можете изменить это с помощью цикла for:
void updateShiftRegister()
{
digitalWrite(latchPin, LOW);
for(int i=0;i<sizeof(leds)/sizeof(leds[0]);i++){
shiftOut(dataPin, clockPin, LSBFIRST, leds[i]);
}
digitalWrite(latchPin, HIGH);
}
Обратите внимание, что sizeof(светодиоды)
вернет размер массива светодиодов
в байтах. Я также разделил размер одного элемента массива, чтобы получить количество элементов в массиве вместо байтов. В данном случае это то же самое, но поскольку типы данных могут меняться по ходу выполнения кода, лучше сохранить, чем сожалеть.
я попробовал метод маскировки с шестнадцатеричным типом данных.
Данные, которые выходят, те же самые. Arduino знает только двоичные данные. Он не знает о различных представлениях (например, двоичных, шестнадцатеричных или десятичных). Компилятор уже преобразует это в целевое значение. Так что для Arduino оба способа эквивалентны.
На самом деле, я работаю над проектом матрицы 50x8 точек и пишу библиотеку самостоятельно, вместо того, чтобы копировать чей-либо код. Поэтому мне нужно сохранить почти 50 бит в переменной для управления столбцами, так может ли метод "uint" быть полезным в этом случае ?, @Subha Jeet Sikdar
Эти 16 бит в байте типа данных-это всего лишь небольшой пример, который я использовал, чтобы объяснить свою проблему, @Subha Jeet Sikdar
@SubhaJeetSikdar Я добавил абзац об этом в конце ответа., @chrisl
Функция shiftOut()
работает только для 8-разрядных значений, как указано в документации.
Кроме того, byte
может хранить только 8 бит. Не имеет значения, сколько битов вы пытаетесь присвоить. (Компилятор должен был предупредить вас, но IDE любит это скрывать.)
Вам нужно написать свою собственную функцию вывода, чтобы сдвинуть 16 бит, AFAIK.
- 74HC595 к 4 значному 7 сегменту с использованием библиотеки SevSegShift
- LSB/MSB и shiftOut
- Прочитать значение регистра в arduino
- Использование массивов, двоичных данных и битового чтения
- Изменение одного бита в байтовом массиве
- Как обнаружить нажатия кнопок с помощью сдвигового регистра 74HC595?
- Проблема с подключением 2 8-разрядных сдвиговых регистров 74HC595 в каскадном соединении
- Вывести 2 числа, хранящиеся в 24-битном формате, в десятичном формате.
Пожалуйста, покажите, как вы подключили регистры сдвига. Если у вас действительно есть два из них, связанных цепочкой, они не могут копировать друг друга. Кроме того, вы, кажется, смещаетесь всего на 1 байт (8 бит). Для 16 светодиодов, подключенных к двум 8-разрядным регистрам сдвига, необходимо сдвинуть 2 байта., @StarCat
https://www.arduino.cc/en/Tutorial/Foundations/ShiftOut/ здесь вы можете найти схему, @Subha Jeet Sikdar
Не могли бы вы добавить эту ссылку к вопросу?, @StarCat
Ок добавил ссылку на вопрос через свой мобильный телефон., @Subha Jeet Sikdar