Кнопка (button Aruino DUE)

Конструкції та прграмування ARDUINO DUE
Відповісти
Аватар користувача
radioman
Site Admin
Повідомлень: 134
З нами з: 28 вересня 2020, 12:01
Звідки: Тернопіль
Дякував (ла): 8 разів
Подякували: 6 разів

Кнопка (button Aruino DUE)

Повідомлення radioman »

У темі про Arduino UNO я описав підключення кнопки з нівелюванням "брязкоту контактів". Для Aruino DUE кнопка підключається аналогічно, лише варто пам'ятати про те, що на вхід можна подавати не більше 3.3 В:
Варіант схеми підключення кнопки в Aruino DUE
Варіант схеми підключення кнопки в Aruino DUE
і, у відповідності до схеми, вніс деякі зміни в скетч:

Код: Виділити все

int pinButton = A0;                            // Пін кнопки
int pinLED = 13;                               // Пін світлодіода (використано інтегрований)

Код скетчу можна дещо змінити, використавши пряме звернення до контактів. Спочатку, замість присвоєння змінній номера вихідного піну,

Код: Виділити все

int pinLED = 13;                               // Пін світлодіода (використано інтегрований)
одразу запрограмуємо порт В27 (13 контакт) як вихід:

Код: Виділити все

PIOB->PIO_OER = 1 << 27;                        // Встановлюємо пін світлодіода як вихід (13 контакт = В27)
В самому тілі програми будемо просто інвертувати значення на виході:

Код: Виділити все

REG_PIOB_ODSR ^= 1 << 27;                       //Переключити (інвертувати) рівень 13 виходу
(або виконувати будь яку потрібну нам дію).
Аватар користувача
radioman
Site Admin
Повідомлень: 134
З нами з: 28 вересня 2020, 12:01
Звідки: Тернопіль
Дякував (ла): 8 разів
Подякували: 6 разів

Re: Кнопка (button Aruino DUE)

Повідомлення radioman »

Для мого проекту важлива швидкодія, так як відслідковування натискання кнопки відбувається в обробнику переривань під час виконання основного завдання. Тому pinMode(pinLED, OUTPUT) замінив на пряме звертання до регістрів PIOB->PIO_OER = 1 << 27 (PIOB->PIO_OER = PIO_PB27), а ось із кодом зчитування інформації про натискання кнопки виникли певні труднощі. Відповіді на питання знайшов на arduino.cc:

Код: Виділити все

/*
  https://radioman.com.ua/posting.php?mode=reply&f=9&t=41
  https://forum.arduino.cc/t/how-to-read-port-pin-directly-in-due-direct-port-manipulation/424079
  PIO with polling input
  Example  which uses a tactile switch that when pressed dims a normally lit onboard LED.
  The switch is configured as an input on PC12/DUE PIN N° 51 and the onboard LED is located on PB27/DUE PIN N°13.
 */

void setup() 
{
  //We need to associate clock with Port C so we can read input
    
  PMC->PMC_PCER0 = PMC_PCER0_PID13; // PIOC power on
  
  //Enable PB27 and PC12 (Peripheral Enable Register)
  PIOB->PIO_PER = PIO_PB27;
  PIOC->PIO_PER = PIO_PC12;
  
  //Set B27 as output (Output Enable Register)
  PIOB->PIO_OER = PIO_PB27;

  //Set C12 as input (Ouput Disable Register)
  PIOC->PIO_ODR = PIO_PC12;

  //Disable pull-up on both pins (Pull Up Disable Register)
  PIOB->PIO_PUDR = PIO_PB27;
  PIOC->PIO_PUDR = PIO_PC12;
}

void loop() 
{
  //Very simple polling routine that checks the Pin Data Register's status 
  //and sets the state of the LED accordingly.

  if ((PIOC->PIO_PDSR & PIO_PC12) == PIO_PC12)
    PIOB->PIO_SODR = PIO_PB27;  //Set Ouput Data Register
  else
    PIOB->PIO_CODR = PIO_PB27;  //Clear Output Data Register
  delay(10);
}
Після завантаження скетчу світлодіод, підключений до 13 контакту буде світитись і гаснути при натисканні кнопки.
Але, для виконання цьго коду, необхідно змінити схему підключення - кнопка підключена до контакту 51:
Варіант схеми підключення кнопки в Aruino DUE
Варіант схеми підключення кнопки в Aruino DUE
З урахування вище викладеного скетчу, мій код отримав такий вигляд:

Код: Виділити все

void setup()
{
  /*    https://radioman.com.ua/viewtopic.php?p=186#p186    */
  // Пов'язуємо тактування з портом C, щоб ми могли читати вхідні дані (PIOC power on)
  PMC->PMC_PCER0 = PMC_PCER0_PID13; 

  //Вмикаємо PB27 та PC12 (Peripheral Enable Register)
  PIOB->PIO_PER = PIO_PB27;
  PIOC->PIO_PER = PIO_PC12;

  //Встановлюємо B27 як вихід (Output Enable Register)
  PIOB->PIO_OER = PIO_PB27;

  //Встановлюємо C12 як вхід (Ouput Disable Register)
  PIOC->PIO_ODR = PIO_PC12;

  //Відключаємо підтягуючі резистори (Pull Up Disable Register)
  PIOB->PIO_PUDR = PIO_PB27;
  PIOC->PIO_PUDR = PIO_PC12;
}

bool lastButton = LOW;                             // "Обнуляємо" кнопку

bool debounce()                                    // Функція для ігнорування брязкоту контактів
{
  bool current = PIOC->PIO_PDSR & PIO_PC12;        // Зчитуємо стан кнопки
  if (current != lastButton)                       // Якщо старе значення відрізняється від отриманого
  {
    delay(10);                                     // Чекаємо коли стан стабілізується - ігноруємо брязкіт контактів
    current = PIOC->PIO_PDSR & PIO_PC12;           // Зчитуємо стабілізоване значення
  }
  return current;                                  // Повертаємо значення кнопки
}

void loop()
{
  int currentButton = debounce();                  // Отримуємо стабілізоване значення
  if (lastButton == LOW && currentButton == HIGH)  // Якщо стан кнопки "натиснута" - HIGH, а попередній LOW - фіксуємо подію натискання кнопки
  {
    REG_PIOB_ODSR ^= 1 << 27;                      // Переключити (інвертувати) рівень 13 виходу
  }
  lastButton = currentButton;                      // Запам'ятовуємо останній стан кнопки
}
Після завантаження скетчу світлодіод, підключений до 13 контакту буде світитись і змінювати свій стан при кожному натисканні-відпусканні кнопки.
Аватар користувача
radioman
Site Admin
Повідомлень: 134
З нами з: 28 вересня 2020, 12:01
Звідки: Тернопіль
Дякував (ла): 8 разів
Подякували: 6 разів

Re: Кнопка (button Aruino DUE)

Повідомлення radioman »

При програмуванні контакту Arduino DUE на вхід можна включити апаратний фільтр перешкод (ст. 625). У скетч з forum.arduino.cc пропишемо його включення:

Код: Виділити все

// Input Filter Enable Register
  PIOC->PIO_IFER = PIO_PC12;
Для роботи вхідних фільтрів необхідний дозвіл тактування контролера шини периферійного введення - виведення:

Код: Виділити все

// Пов'язуємо тактування з портом C, щоб ми могли читати вхідні дані (PIOC power on)
  PMC->PMC_PCER0 = PMC_PCER0_PID13; // PIOC power on
В результаті ми отримали можливість фільтрувати "брязкіт контактів" кнопки як і "схемним рішенням", так і апаратно на рівні МК.

PS. Змінений скетч в доданому архіві:
button_due_Input_Filter_Enable-Register.ino.7z
Апаратний фільтр перешкод
(943 байт) Завантажено 998 разів
Відповісти