Перейти к содержанию
  • запись
    31
  • комментария
    453
  • просмотров
    67 857

Простой селектор входов для УМ (2..4 входа)


aitras

14 096 просмотров

Простой селектор входов для усилителя мощности. Выполнен на микроконтроллере ATtiny13A.

Подключение выполняется по следующей схеме:

SELECTOR.png.0325ddd52ddc53e6f245b828e73f036d.png

Естественно, что вместо светодиодов должны стоять реле.

В 1 кбайте памяти микроконтроллера спрятан следующий функционал:
- использование от 2-х до 4-х входов, количество которых определяется автоматически (неиспользуемые 4-й или 3-й и 4-й входы следует подтянуть к питанию через резистор 5-10 кОм);
- переключение одной кнопкой "по кругу";
- запоминание последнего выбранного входа;
- задержка при включении (2 c);
- защита от дребезга кнопки;
- mute между переключениями каналов (0,5 c).

При программировании следует установить фьюзы следующим образом: HIGH - 0xFF, LOW  - 0x79. То есть нужно отключить делитель частоты на 8, и выбрать источник тактирования - внутренний RC-генератор на 4,8 МГц с задержкой старта в 64 мс.

Платы под схему нет, предполагаю, что каждый нарисует себе сам под необходимые детали.

На видео показан макет, демонстрирующий работу селектора:

 

Скачать файл прошивки

39 Комментариев


Рекомендуемые комментарии



Создал проект, добавил файл прошивки, в опциях микросхемы поставил CKSEL Fuses в 4.8MHz, запускаю симуляцию, кликаю кнопочку - светодиоды не загораются :(

1122.PNG

1122.PNG

Изменено пользователем drcrash
Ссылка на комментарий

Спасибо, заработало, но не так, как ожидалось - как видите по схеме у меня 2 входа, но контроллер считает, что их 4. пробовал 5К и 10К - на R32 и R31 при переключении точно также переключает, как и на активные каналы, то есть 4 активных канала вместо двух

Изменено пользователем drcrash
Ссылка на комментарий

Открыл исходники, а то забыл уже что там было. 

В общем, при запуске проверяются только 4 и 3 каналы, т.е. с конца. А вы отключили 1 и 2.

Ссылка на комментарий

Ок, сделал как показано на схеме:

1122.PNG.f2736836645ab46a92e5bf5d57061fa2.PNG

 

В результате есть проблема - как видно из схемы 7-й контакт микросхемы "загорелся", в общем участвует в переключении. Со вторым контактом все ок - его пропускает. Странно.

И можно ли задержку переключения в пол-секунды поставить?

Изменено пользователем drcrash
Ссылка на комментарий

Действительно с подтяжками 10к такое поведение. Вечером посмотрю где ошибка.

Задержка между переключениями и так полсекунды сейчас.

Ссылка на комментарий

Собственно без них напрямую контакты на питание все ок работает, но вот можно ли так использовать микросхему в реальности не знаю :unknw:

Изменено пользователем drcrash
Ссылка на комментарий

Защита от дребезга контактов - слишком громко сказано. Это элементарщина. Вижу код тут не выкладывается. Зря. Конечные автоматы, автоматное программирование. Функционал в начале расписан. Будем считать это как ТЗ. Накидать программу за вечерок как два пальца... Дарю кусочек кода

Spoiler

//========================================================================
#ifndef KBD_DRV_H

#define KBD_DRV_H

#include "kbd_drv.h"

#include "main_def_func.h"
//========================================================================

//========================================================================
#ifdef __PROJECT_MODE_WORK__
#define DEBOUNCE_DELAY 30
#define HOLD_DELAY_1   300
#define HOLD_DELAY_2   5000
#endif

#ifdef __PROJECT_MODE_DEBUG__
#define DEBOUNCE_DELAY 3
#define HOLD_DELAY_1   10
#define HOLD_DELAY_2   50
#endif
//========================================================================

//========================================================================
#ifdef __WORK_BOARD__
#define KEY_PIN        PINB
#define KEY_PORT       PORTB
//------------------------------------------------------------------------
#define KEY            PB0
#define KEY_BIT        1<<KEY
#endif
//------------------------------------------------------------------------

//------------------------------------------------------------------------
#ifdef __DEBUG_BOARD__
#define KEY_PIN        PIND
#define KEY_PORT       PORTD
//------------------------------------------------------------------------
#define KEY            PD0
#define KEY_BIT        1<<KEY
#endif
//========================================================================

//========================================================================
//#define KEY1_PRESSED() ((KEYS1_PIN & (1<<BIT_KEY1) == 0)
//#define KEY1_UNPRESSED() ((KEYS1_PIN & (1<<BIT_KEY1) == 1)

#ifdef __PROJECT_MODE_WORK__
#define Set_Is_Key_Pressed() !(check_bit (KEY_PIN, KEY))  // Low level.
#endif

#ifdef __PROJECT_MODE_DEBUG__
#define Set_Is_Key_Pressed() check_bit (KEY_PIN, KEY)  // Low level.
#endif

// При работе с буфером входов (расширение ввода-вывода):
// #define Set_Is_Key_Stop_Pressed()   check_bit (inputs_buf [0], KEY_STOP)
//========================================================================

//========================================================================
typedef enum _kbd_drv
{
   KBD_DRV_INIT = 0,
   KBD_DRV_NONE,
   KBD_DRV_WAIT_DOWN,
   KBD_DRV_DOWN,
   KBD_DRV_WAIT_UP,
   KBD_DRV_UP,
} kbd_drv_t;
//========================================================================

//========================================================================
typedef enum keys_buf
{
   KEY_COD_SHORT_PRESS = 0,
   KEY_COD_LONG_PRESS,
} key_cod_t;
//========================================================================

//========================================================================
typedef enum key_press_mode
{
   KEY_PRESS_MODE_NONE = 0,
   KEY_PRESS_MODE_WAIT_LONG_PRESS,
   KEY_PRESS_MODE_WAIT_RESET,
} key_press_mode_t;
//========================================================================

//========================================================================
void kbd_drv (void);
//------------------------------------------------------------------------
void Set_Keys_Buf (key_cod_t a);
key_cod_t Get_Keys_Buf (void);
//========================================================================

#endif

//========================================================================
#include "kbd_drv.h"
//========================================================================

//========================================================================
static kbd_drv_t _kbd_drv;

static key_cod_t keys_buf;

static key_press_mode_t key_press_mode;

static soft_timer ST_KBD_DRV;
//========================================================================

//========================================================================
void kbd_drv (void)
{
   switch (_kbd_drv)
   {
      case KBD_DRV_INIT:
         key_press_mode = KEY_PRESS_MODE_NONE;
         _kbd_drv = KBD_DRV_NONE;
         break;

      case KBD_DRV_NONE:
         if (Set_Is_Key_Pressed ()) // Если кнопка нажата, то
         {
            set_soft_timer (ST_KBD_DRV, DEBOUNCE_DELAY); // установка таймера антидребезга.
            _kbd_drv = KBD_DRV_WAIT_DOWN;
         }
         break;

      case KBD_DRV_WAIT_DOWN:
         if (handle_soft_timer (ST_KBD_DRV)) // Таймер антидребезга.
         {
            if (Set_Is_Key_Pressed ())
            {
               set_soft_timer (ST_KBD_DRV, HOLD_DELAY_1); // Установка таймера длинного нажатия кнопки.
               key_press_mode = KEY_PRESS_MODE_WAIT_LONG_PRESS;
               _kbd_drv = KBD_DRV_DOWN;
            }
            else
               _kbd_drv = KBD_DRV_NONE;
         }
         break;

      case KBD_DRV_DOWN:
         if (Set_Is_Key_Pressed ())
         {
            if (handle_soft_timer (ST_KBD_DRV))
            {
               switch (key_press_mode)
               {
                  case KEY_PRESS_MODE_WAIT_LONG_PRESS:
                     set_soft_timer (ST_KBD_DRV, HOLD_DELAY_2); // Установка таймера RESET.
                     key_press_mode = KEY_PRESS_MODE_WAIT_RESET;
                     break;

                  case KEY_PRESS_MODE_WAIT_RESET:
                     Set_Event (EV_ID_RESET, USER_EVENT); // Событие нажатия кнопки.
                     key_press_mode = KEY_PRESS_MODE_NONE;
                     _kbd_drv = KBD_DRV_WAIT_UP;
                     break;
               }
            }
         }
         else
            _kbd_drv = KBD_DRV_WAIT_UP;
         break;

      case KBD_DRV_WAIT_UP:
         if (!(Set_Is_Key_Pressed ())) // Если кнопка отпущена, то
         {
            set_soft_timer (ST_KBD_DRV, DEBOUNCE_DELAY); // Таймер подавления дребезга.
            _kbd_drv = KBD_DRV_UP;
         }
         break;

      case KBD_DRV_UP:
         if (handle_soft_timer (ST_KBD_DRV)) // Таймер подавления дребезга.
         {
            if (!(Set_Is_Key_Pressed ()))
            {
               switch (key_press_mode)
               {
                  case KEY_PRESS_MODE_WAIT_LONG_PRESS:
                     Set_Keys_Buf (KEY_COD_SHORT_PRESS); // Короткое нажатие.
                     Set_Event (EV_ID_KEY_PRESSED, USER_EVENT); // Событие нажатия кнопки.
                     break;

                  case KEY_PRESS_MODE_WAIT_RESET:
                     Set_Keys_Buf (KEY_COD_LONG_PRESS); // Длинное нажатие.
                     Set_Event (EV_ID_KEY_PRESSED, USER_EVENT); // Событие нажатия кнопки.
                     break;
               }

               _kbd_drv = KBD_DRV_INIT;
            }
            else
               _kbd_drv = KBD_DRV_WAIT_UP;
         }
         break;
   }
}
//========================================================================

//========================================================================
void Set_Keys_Buf (key_cod_t a)
{
   keys_buf = a;
}
//------------------------------------------------------------------------
key_cod_t Get_Keys_Buf (void)
{
   return keys_buf;
}
//========================================================================


//Шкелет основной программы:

//========================================================================
void proc_device (void)
{
   static proc_device_t _proc_device;

   static soft_timer ST_PROC_DEVICE;

   static u08 cnt_inputs;

   if (Get_Event (EV_ID_RESET))
      _proc_device = PROC_DEVICE_INIT;

   switch (_proc_device)
   {
      case PROC_DEVICE_INIT: // Блок инициализации.
         break;

      case PROC_DEVICE_1:
         if (Get_Event (KEY_COD_SHORT_PRESS))
         {
            if (++cnt_inputs >= MAX_INPUTS)
               cnt_inputs = 0;
         }

         switch (cnt_inputs)
         {
            case 0:
               INPUTS_PORT = INPUT_2
               break;

            case 1:
               INPUTS_PORT = INPUT_3
               break;

            case 2:
               INPUTS_PORT = INPUT_4
               break;

            case 3:
               INPUTS_PORT = INPUT_1
               break;
         }
         break;

      case PROC_DEVICE_2:
         break;
   }
}
//========================================================================

 

 

Ссылка на комментарий

у меня еще вопрос - почему вместо реле не используют транзисторы в подобных схемах?

Изменено пользователем drcrash
Ссылка на комментарий

Мне кажется для микроконтроллера это маловато, переключение каналов можно организовать на D тригере и логикой (=1). Думаю тут надо идти дальше и сделать автоматический селектор. Правда Attiny тут хватит на не больше чем 2 канала. Можно влепить Атмегу 168 или 328p.

Её прошивать проще, среда разработки ардуино.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Добавить комментарий...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...

×
×
  • Создать...