Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

Arduino:Примеры/ShftIn23

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

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

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


Печать включенных настроек[1]

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

Код

  1. //**************************************************************//
  2. //  Название    : Печать включенных настроек                    //
  3. //  Автор       : Кэрлин Мо                                     //
  4. //  Дата        : 25 января 2007 года                           //
  5. //  Версия      : 1.0                                           //
  6. //  Примечания  : Скетч для использования с двумя сдвиговыми    //
  7. //              : регистрами CD4021B                            //
  8. //**************************************************************//
  9.  
  10. // задаем номера для интерфейсных контактов:
  11. int latchPin = 8;
  12. int dataPin = 9;
  13. int clockPin = 7;
  14.  
  15. // задаем переменные, которые будут хранить данные для
  16. // каждого сдвигового регистра; в целях отладки лучше начать
  17. // со значений без «0»:    
  18. byte switchVar1 = 72;  //01001000
  19. byte switchVar2 = 159; //10011111
  20.  
  21. // задаем массив со значениями для каждого контакта
  22. // на первом сдвиговом регистре:  
  23. char note2sing[] = {
  24.   'C', 'd', 'e', 'f', 'g', 'a', 'b', 'c'};
  25.  
  26. // задаем массив со значениями для 1-7 (не 0) контактов
  27. // на втором сдвиговом регистре; без 0, потому что этот контакт
  28. // будет использоваться для флагового значения:
  29. byte settingVal[] = {
  30.   0, 0, 0, 0, 0, 0, 0};  
  31.  
  32. boolean MuteBit = 0;          
  33. boolean OctShftBit = 1;
  34. boolean DelayBit = 2;          
  35. boolean ReverbBit = 3;
  36. boolean VibratoBit = 4;
  37. boolean FunkifyBit = 5;
  38. boolean DampenBit = 6;
  39.  
  40. // флаговая переменная для определения того, находится ли скетч
  41. // в режиме обновления настроек:  
  42. byte settingSwitch = 0;  
  43.  
  44. void setup() {
  45.   // запускаем последовательную коммуникацию:
  46.   Serial.begin(9600);
  47.  
  48.   // задаем режимы для контактов:
  49.   pinMode(latchPin, OUTPUT);
  50.   pinMode(clockPin, OUTPUT);
  51.   pinMode(dataPin, INPUT);
  52.  
  53. }
  54.  
  55. void loop() {
  56.  
  57.   // подаем импульс на контакт-защелку;
  58.   // чтобы собрать параллельные данные, задаем ему значение «1»:
  59.   digitalWrite(latchPin,1);
  60.   // ждем:
  61.   delayMicroseconds(20);
  62.   // задаем ему «0», чтобы передать последовательные данные:
  63.   digitalWrite(latchPin,0);
  64.  
  65.   // пока сдвиговые регистры переключены в последовательный режим,
  66.   // собираем все их данные в байт; сначала это делает регистр,
  67.   // подключенный к чипу:
  68.   switchVar1 = shiftIn(dataPin, clockPin);
  69.   switchVar2 = shiftIn(dataPin, clockPin);
  70.  
  71.   // показываем результат; если первый контакт получит значение HIGH,
  72.   // то «0», стоящий в старшей части байта (7, 6, 5 и т.д.),
  73.   // будет удален:  
  74.   Serial.println(switchVar1, BIN);
  75.   Serial.println(switchVar2, BIN);
  76.  
  77.  
  78.   // этот цикл loop() бит за битом прочесывает байт,
  79.   // содержащий данные сдвигового регистра; найдя значение HIGH (1),
  80.   // он печатает соответствующее место в массиве:
  81.   for (int n=0; n<=7; n++)
  82.   {
  83.     // таким образом, когда «n» равно «3», код сравнивает биты
  84.     // в switchVar1 и двоичное число «00001000», возвращая «true»
  85.     // лишь в том случае, если в этом бите (т.е. контакте)
  86.     // есть значение «1», присланное от сдвигового регистра:  
  87.     if (switchVar1 & (1 << n) ){
  88.       // печатаем значение из этого места в массиве:
  89.       Serial.println(note2sing[n]);
  90.     }
  91.   }
  92.  
  93.   //--- ВТОРОЙ СДВИГОВЫЙ РЕГИСТР
  94.   // он ведет себя чуть сложнее
  95.  
  96.  
  97.   // если переключатель, подключенный к контакту 7,
  98.   // находится в состоянии HIGH:
  99.   if (switchVar2 & (1 << 7) ){
  100.     // если переключатель, подключенный к контакту 7,
  101.     // находится в состоянии HIGH:
  102.     Serial.println("Check, Check"); //  «Идет обновление настроек»
  103.     // задаем флаговой переменной значение «1», чтобы сообщить скетчу,
  104.     // что идет обновление настроек:
  105.     settingSwitch = 1;
  106.   }
  107.   // если переключатель находится в состоянии LOW...
  108.   else {
  109.     //...и если в последний раз при проверке оператором if()
  110.     // этот переключатель находился в состоянии HIGH (т.е. если
  111.     // переменная settingSwitch по-прежнему имеет значение «1»):
  112.     if (settingSwitch) {
  113.       //...то задаем переменной settingSwitch значение «0»:
  114.       settingSwitch=0;
  115.  
  116.       // просто печатаем, какие настройки включены:
  117.       if (getBit(switchVar2, MuteBit)) {
  118.         Serial.print("Mute On   ");  //  "Звук выключен"
  119.       }
  120.       if (getBit(switchVar2, OctShftBit)) {
  121.         Serial.println("Octave Shift On   ");  //  "Смещение октавы включено"
  122.       }
  123.       if (getBit(switchVar2, DelayBit)) {
  124.         Serial.println("Delay On   ");  //  "Задержка включена"
  125.       }
  126.       if (getBit(switchVar2, ReverbBit)) {
  127.         Serial.println("Reverb On   ");  //  "Реверберация включена"
  128.       }
  129.       if (getBit(switchVar2, VibratoBit)) {
  130.         Serial.println("Vibrato On   ");  //  "Вибрация включена"
  131.       }
  132.       if (getBit(switchVar2, FunkifyBit)) {
  133.         Serial.println("Funkified   ");  //  "Фанкизация включена"
  134.       }
  135.       if (getBit(switchVar2, DampenBit)) {
  136.         Serial.println("Note Dampened   ");  //  "Приглушение включено"
  137.       }
  138.     }
  139.   }        
  140.  
  141.  
  142.   // пустое место:
  143.   Serial.println("-------------------");
  144.   // вставляем задержку, чтобы все как следует допечаталось:
  145.   delay(500);
  146.  
  147. }
  148.  
  149. //------------------------------------------------конец главного цикла
  150.  
  151. ////////// ----------------------------------- функция shiftIn()
  152. ///// в качестве аргументов ей требуются лишь контакт для данных
  153. ///// и контакт-защелка; возвращает байт, у которого каждый бит
  154. ///// соответствует какому-либо контакту сдвигового регистра:
  155. ///// 7-ой бит – это 7-ой контакт, 0-ой бит – это 0-ой контакт
  156.  
  157. byte shiftIn(int myDataPin, int myClockPin) {
  158.   int i;
  159.   int temp = 0;
  160.   int pinState;
  161.   byte myDataIn = 0;
  162.  
  163.   pinMode(myClockPin, OUTPUT);
  164.   pinMode(myDataPin, INPUT);
  165.  
  166. // 8 раз подаем на тактовый контакт значение HIGH (0,..,7),
  167. // т.е. при каждом прохождении цикла for();
  168.  
  169. // в начале каждого цикла мы задаем тактовому контакту значение LOW;
  170. // это нужно для последующего перехода из LOW в HIGH, чтобы сдвиговый
  171. // регистр поменял состояние на основе значения в следующем бите
  172. // последовательного потока данных;
  173.  
  174. // регистр передает информацию о контактах в порядке с 7-го по 0-ой,
  175. // поэтому наша функция ведет отсчет в обратном порядке:
  176.  
  177.   for (i=7; i>=0; i--)
  178.   {
  179.     digitalWrite(myClockPin, 0);
  180.     delayMicroseconds(2);
  181.     temp = digitalRead(myDataPin);
  182.     if (temp) {
  183.       pinState = 1;
  184.       // несмотря ни на что, задаем биту значение «0»:
  185.       myDataIn = myDataIn | (1 << i);
  186.     }
  187.     else {
  188.       pinState = 0;
  189.     }
  190.  
  191.     // печатаем отладочную информацию (если отладка не нужна,
  192.     // оставьте эти строчки закоментированными):
  193.     //Serial.print(pinState);
  194.     //Serial.print("     ");
  195.     //Serial.println (dataIn, BIN);
  196.  
  197.     digitalWrite(myClockPin, 1);
  198.  
  199.   }
  200.   // печатаем пустое место, разделяющее отладочные данные:
  201.   //Serial.println();
  202.   //Serial.println(myDataIn, BIN);
  203.   return myDataIn;
  204. }
  205.  
  206. ////// ----------------------------------------функция getBit()
  207. boolean getBit(byte myVarIn, byte whatBit) {
  208.   boolean bitState;
  209.   bitState = myVarIn & (1 << whatBit);
  210.   return bitState;
  211. }
  212.  
  213.  
  214. ////// маленькая дополнительная функция
  215. ////// ----------------------------------------функция setBit()
  216. byte setBit(byte myVarIn, byte whatBit, boolean s) {
  217.   boolean bitState;
  218.   if (s) {
  219.     myVarIn = myVarIn | (1 << whatBit);
  220.   }
  221.   else {
  222.     myVarIn = myVarIn & ~(1 << whatBit);
  223.   }
  224.   return myVarIn;
  225. }

См.также

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

  1. www.arduino.cc - ShftIn23