Arduino:Примеры/ShftIn14

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Нажата ли кнопка?[1]

Это скетч для платы Arduino и одного сдвигового регистра CD4021B. Он считывает данные с переключателей, подключенных к сдвиговому регистру, и определяет, находится ли заданная кнопка в состоянии «вкл».

Код

//**************************************************************//
//  Название    : Нажата ли кнопка?                             //
//  Автор       : Кэрлин Мо                                     //
//  Дата        : 25 января 2007 года                           //
//  Версия      : 1.0                                           //
//  Примечания  : Скетч для использования со сдвиговым          //
//              : регистром CD4021B                             //
//**************************************************************//

// задаем номера для интерфейсных контактов:
int latchPin = 8;
int dataPin = 9;
int clockPin = 7;

// задаем переменные, которые будут хранить данные для 
// сдвигового регистра; в целях отладки лучше начать 
// со значений без «0»:  
byte switchVar1 = 72;  //01001000

byte lowcBitNum = 7;
byte dBitNum = 6;
byte eBitNum = 5;
byte fBitNum = 4;
byte gBitNum = 3;
byte aBitNum = 2;
byte bBitNum = 1;
byte highcNum = 0;

boolean dBit;


void setup() {
  // запускаем последовательную коммуникацию:
  Serial.begin(9600);

  // задаем режимы для контактов:
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT); 
  pinMode(dataPin, INPUT);

}

void loop() {

  // подаем импульс на контакт-защелку;
  // чтобы собрать параллельные данные, задаем ему значение «1»:
  digitalWrite(latchPin,1);
  // ждем:
  delayMicroseconds(20);
  // задаем ему «0», чтобы передать последовательные данные:
  digitalWrite(latchPin,0);

  // пока сдвиговый регистр переключен в последовательный режим, 
  // собираем все его данные в байт; сначала это делает регистр, 
  // подключенный к чипу: 
  switchVar1 = shiftIn(dataPin, clockPin);

  // показываем результат; если первый контакт получит значение HIGH, 
  // то «0», стоящий в старшей части байта (7, 6, 5 и т.д.), 
  // будет удален:
  Serial.println(switchVar1, BIN);

// вы можете узнать состояние бита при помощи функции ниже, либо...

// задаем переменную типа boolean:
dBit = getBit(switchVar1, dBitNum);

  if (dBit) {
    Serial.println("D");
  }

// проверяем правильность функции (новой переменной не требуется):
 if (getBit(switchVar1, aBitNum)) {
    Serial.println("A");
  }

// пустое место:
Serial.println("-------------------");
// вставляем задержку, чтобы все как следует допечаталось:
delay(500);

}

//-----------------------------------------------конец главного цикла

////////// ----------------------------------- функция shiftIn()
///// в качестве аргументов ей требуются лишь контакт для данных 
///// и контакт-защелка; возвращает байт, у которого каждый бит 
///// соответствует какому-либо контакту сдвигового регистра: 
///// 7-ой бит – это 7-ой контакт, 0-ой бит – это 0-ой контакт

byte shiftIn(int myDataPin, int myClockPin) { 

// аналог блока setup() внутри функции:
  int i;
  int temp = 0;
  int pinState;
  byte myDataIn = 0;

  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, INPUT);

//8 раз подаем на тактовый контакт значение HIGH (0,..,7),
// т.е. при каждом прохождении цикла for(); 

// в начале каждого цикла мы задаем тактовому контакту значение LOW;
// это нужно для последующего перехода из LOW в HIGH, чтобы сдвиговый 
// регистр поменял состояние на основе значения в следующем бите 
// последовательного потока данных;

// регистр передает информацию о контактах в порядке с 7-го по 0-ой,
// поэтому наша функция ведет отсчет в обратном порядке:

  for (i=7; i>=0; i--)
  {
    digitalWrite(myClockPin, 0); 
    delayMicroseconds(0.2);
    temp = digitalRead(myDataPin);
    if (temp) {
      pinState = 1;
      // несмотря ни на что, задаем биту значение «0»:
      myDataIn = myDataIn | (1 << i);
    }
    else {
      pinState = 0;
    }

    // печатаем отладочную информацию (если отладка не нужна,
    // оставьте эти строчки закоментированными):
    //Serial.print(pinState);
    //Serial.print("     ");
    //Serial.println (dataIn, BIN);

    digitalWrite(myClockPin, 1);

  }
  // печатаем пустое место, разделяющее проверочные данные: 
  //Serial.println();
  //Serial.println(myDataIn, BIN);
  return myDataIn;
}

////// ---------------------------------------- функция getBit()
boolean getBit(byte myVarIn, byte whatBit) {
  boolean bitState;
  bitState = myVarIn & (1 << whatBit);
  return bitState;
}


////// маленькая дополнительная функция... 
////// ---------------------------------------- функция setBit()
byte setBit(byte myVarIn, byte whatBit, boolean s) {
  boolean bitState;
  if (s) {
    myVarIn = myVarIn | (1 << whatBit);
  } else {
    myVarIn = myVarIn & ~(1 << whatBit);
  }
  return myVarIn;
}

См.также

Внешние ссылки