Например TDA7294

Форум РадиоКот • Просмотр темы - 2 кнопки - Нужно выжать 5 режимов обработки.
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вс дек 28, 2025 20:29:59

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 54 ]    , , 3
Автор Сообщение
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Вс фев 13, 2022 18:42:04 
Опытный кот
Аватар пользователя

Карма: -2
Рейтинг сообщений: -23
Зарегистрирован: Сб окт 22, 2016 17:33:32
Сообщений: 760
Откуда: кг
Рейтинг сообщения: 1
main.c
Спойлер
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "Button.h"

typButton aButtons[] = {
  {.ddr=&DDRB, .port=&PORTB, .pin=&PINB, .bitmask=_BV(PB0)},
  {.ddr=&DDRC, .port=&PORTC, .pin=&PINC, .bitmask=_BV(PC1)},
  {.ddr=&DDRD, .port=&PORTD, .pin=&PIND, .bitmask=_BV(PD2)}
};

// every 1 ms
volatile uint8_t Strobe1ms;

ISR(TIMER2_COMPA_vect)
{
  Strobe1ms = 1;
}

void Setup(void)
{
  btnSetup(sizeof(aButtons) / sizeof(aButtons[0]));
  // Timer 2
  Strobe1ms = 0;
  // Timer2, Mode 2 Clear Timer on Compare Match (CTC) mode, OC2A and OC2B disconnected
  TCCR2A = _BV(WGM21);
  // T = clkIO/64 = 4 us
  TCCR2B = _BV(CS22);
  // (249 + 1) * 4 us = 1 ms
  OCR2A  = 249;
  // Output Compare A Match Interrupt Enable
  TIMSK2 = _BV(OCIE2A);
  // interrupts enable
  sei();
}

int main(void)
{
  Setup();
  while(1) {
    if(Strobe1ms) {
      Strobe1ms = 0;
      btnCheckOnTimer(sizeof(aButtons) / sizeof(aButtons[0]));
      uint8_t AllButtonsLongPressed = 1;
      for(uint8_t i = 0; i < sizeof(aButtons) / sizeof(aButtons[0]); ++i) {
        AllButtonsLongPressed &= (btnRepeat == aButtons[i].state) || (btnAmbRepeat == aButtons[i].state);
        switch(aButtons[i].state) {
        case btnDbl:    // двойной клик
          break;
        case btnOn:     // нажали
          break;
        case btnRepeat: // автоповтор
          break;
        default:
          break;
        }
      }
      if(AllButtonsLongPressed) {
        ; // все кнопки нажаты продолжительное время
      }
    }
  }
}

Button.h
Спойлер
Код:
#ifndef BUTTON_H
#define BUTTON_H

typedef enum {btnOff = 0, btnAmbOn, btnAmbDbl_1, btnAmbDbl_2, btnDbl, btnOn, btnAmbRepeat, btnRepeat} typBtnState;

// in makefile
#ifndef BTN_BEFORE_ON
#define BTN_BEFORE_ON       200   // 200ms
#endif

#ifndef BTN_BEFORE_DBL
#define BTN_BEFORE_DBL       50   // 50ms
#endif

#ifndef BTN_BEFORE_REPEAT
#define BTN_BEFORE_REPEAT   200   // 200ms
#endif

#ifndef BTN_REPEAT_DELAY
#define BTN_REPEAT_DELAY    150   // 150ms
#endif

typedef struct {
  volatile uint8_t * ddr;
  volatile uint8_t * port;
  volatile uint8_t * pin;
  const uint8_t bitmask;
  typBtnState state;
  uint16_t tick;
} typButton;

extern typButton aButtons[];

void btnSetup(uint8_t qtty);
uint8_t btnCheckOnTimer(uint8_t qtty);

#endif

Button.c
Спойлер
Код:
#include <avr/io.h>
#include "Button.h"

void btnSetup(uint8_t qtty)
{
  typButton* pButton = aButtons;
  while(qtty--) {
    // input
    *pButton->ddr  &= ~pButton->bitmask;
    // pull-up
    *pButton->port |=  pButton->bitmask;
    pButton->state  = btnOff;
    pButton->tick   = 0;
    ++pButton;
  }
}

uint8_t btnCheckOnTimer(uint8_t qtty)
{
  uint8_t bNeedCheck = 0;
  typButton* pButton = aButtons;
  while(qtty--) {
    ++pButton->tick;
    if(*pButton->pin & pButton->bitmask) {  // нет нажатия
      switch(pButton->state) {
      case btnAmbOn:  // было нажатие, возможно двойной клик, отпустили раньше
        if(BTN_BEFORE_DBL <= pButton->tick) {
          pButton->state = btnAmbDbl_1;
          pButton->tick  = 0;
        }
        break;
      case btnAmbDbl_1: // не нажали повторно для двойного клика
        if(BTN_BEFORE_ON <= pButton->tick) {
          pButton->state = btnOff;
        }
        break;
      case btnAmbDbl_2: // двойное нажатие
        if(BTN_BEFORE_ON <= pButton->tick) { // слишком долгое повторное нажатие, сброс
          pButton->state = btnOff;
        } else if(BTN_BEFORE_DBL <= pButton->tick) {
          pButton->state = btnDbl;
          bNeedCheck = 1;
        }
        break;
      default:
        pButton->state = btnOff;
        break;
      }
    } else {            // зафиксировали нажатие
      switch(pButton->state) {
      case btnAmbDbl_1: // двойное нажатие
        if(BTN_BEFORE_DBL <= pButton->tick) {
          pButton->state = btnAmbDbl_2;
          pButton->tick  = 0;
        }
        break;
      case btnAmbDbl_2: // двойное нажатие, ждем отпускание кнопки
        break;
      case btnOff:      // ничего не было зафиксированно до сих-пор
        pButton->state = btnAmbOn;
        pButton->tick  = 0;
        break;
      case btnAmbOn:    // кнопка возможно нажата
        if(BTN_BEFORE_ON <= pButton->tick) {
          pButton->state = btnOn;       // точно нажата - обработать
          pButton->tick  = 0;
          bNeedCheck = 1;
        }
        break;
      case btnOn:
      case btnRepeat:
        pButton->state = btnAmbRepeat;  // будем ждать автоповтор
        // плавно попадаем в btnAmbRepeat
      case btnAmbRepeat:
        if(BTN_BEFORE_REPEAT <= pButton->tick) {
          pButton->state = btnRepeat;   // автоповтор
          pButton->tick  = 0;
          bNeedCheck = 1;
        }
        break;
      default:
        pButton->state = btnOff;        // ерунда какая-то
        break;
      }
    }
    ++pButton;
  }
  return bNeedCheck;
}


Вложения:
Комментарий к файлу: Проект
Buttons.rar [6.78 KiB]
Скачиваний: 117
Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Вс фев 13, 2022 19:32:11 
Встал на лапы

Зарегистрирован: Чт дек 16, 2021 18:20:02
Сообщений: 95
Рейтинг сообщения: 0
main.c


Спасибо, попробую.

Добавлено after 5 minutes 17 seconds:
Единственное, как я понял, тут реализован дабл клик?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Вс фев 13, 2022 20:57:08 
Опытный кот
Аватар пользователя

Карма: -2
Рейтинг сообщений: -23
Зарегистрирован: Сб окт 22, 2016 17:33:32
Сообщений: 760
Откуда: кг
Рейтинг сообщения: 0
дабл клик?

Да.

Если на множественное нажатие надо реагировать 1 раз, то какой-то триггер надо городить.
Настройки таймера 2 под ATmega328 16 МГц, в makefile. Под другую конфигурацию как-то по другому надо.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 04:38:11 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 139
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1480
Рейтинг сообщения: 0
Насчёт двойного клика. На одном форуме как-то было обсуждение обработки кнопок. Навешивать некоторые функции на модуль обработки клавиш, думаю неоптимально, с точки зрения универсальности. Модуль кнопок должен опрашивать кнопки, определять обычные нажатия, удержание, автоповтор, отпускание кнопок. Подсчет количества нажатий должно вестись в соответствующем программном модуле, который принимает события от модуля кнопок и коды кнопок. В этом случае соблюдается универсальность применения модуля обработки кнопок. Да и как бы это и логично. Двойное и так далее нажатия кнопок требование конкретного проекта, а не модуля обработки кнопок. Мало того. В отдельных случаях, удержание и автоповтор тоже можно разнести. На модуль обработки кнопок оставить некий общий принцип. Скажем, минималка удержания (особые требования реализовать уже в каждом конкретном проекте). То же касается и автоповтора. Пояснение, минимальное время удержания, скажем, 500 мс, время автоповтора, 25 мс. Удержание, автоповтор могут не потребоваться. В разных проектах разные требования ко времени удержания, автоповтора.
Конечно же, окончательное решение на своих проектах каждый принимает сам. Что оптимальнее и целесообразно

Для ТС. Двойное и более нажатия. Реализация вне модуля опроса кнопок. В модуле приема событий кнопок создаётся переменная счётчик. Алгоритм. В случае события нажатия кнопок разбираем, какая кнопка нажата. Если на эту кнопку ведётся подсчет, инкремент переменной счётчика. Далее сравнение и соответствующее действие.


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 09:46:32 
Поставщик валерьянки для Кота

Карма: 20
Рейтинг сообщений: 256
Зарегистрирован: Вс июн 19, 2016 09:32:03
Сообщений: 2089
Рейтинг сообщения: 0
Подсчет количества нажатий должно вестись в соответствующем программном модуле, который принимает события от модуля кнопок и коды кнопок. В этом случае соблюдается универсальность применения модуля обработки кнопок. Да и как бы это и логично. Двойное и так далее нажатия кнопок требование конкретного проекта, а не модуля обработки кнопок. Мало того. В отдельных случаях, удержание и автоповтор тоже можно разнести. На модуль обработки кнопок оставить некий общий принцип. Скажем, минималка удержания (особые требования реализовать уже в каждом конкретном проекте).

Не удобно, я обычно стараюсь запихнуть всего побольше, но с возможностью выбора, правда на С такое красиво сделать вряд ли получится:
Код:
using pins = PinList<PC13, PA1, PB0, PB10>;
Buttons<pins> buttons;

Это простейший случай, ловим только обычные нажатия для всех кнопок.
Код:
constexpr ButtonConfig conf =
{
    .queueSize   = 4,
    .shortMask   = 0x0E,
    .longMask    = 0x0D,
    .releaseMask = 0x01,
    .repeatMask  = 0x0C,
    .longThreshold = 500,
    .....
};

using pins = PinList<PC13, PA1, PB0, PB10>;
Buttons<pins, conf> buttons;

А тут я включил очередь, что помимо прочего позволяет вызывать update() из прерывания, далее для трех кнопок ловим обычные нажатия, для двух из них включен автоповтор, а четвертая реагирует только на отпускания и длинные нажатия. Все эти параметры передаются в класс как константы, они даже во флеше не хранятся и если, допустим, сделать longMask нулевой, то весь код за обработки длинных нажатий выпилится потому что в классе десяток if constexpr:
Код:
if constexpr (longMask)
{
    auto diff = (prevLongPressed ^ current);
    state.longPressed = diff & current & longMask;
    prevLongPressed = current;
}

И так со всем, если очередь не используется, то вместо класса подставится bool и нигде не используемая булевая переменная тоже выпилится.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 10:38:17 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2135
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18447
Откуда: Новочеркасск
Рейтинг сообщения: 1
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Очереди, структуры в очередях... Как обычно, забыли о разделе, где идет обсуждение: в большинстве популярных AVR на очередь кнопок половина ОЗУ уйдет

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 10:47:49 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 139
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1480
Рейтинг сообщения: 0
To Reflector. Задача модуля кнопок выдать события нажатия, отжатия, удержания и повтора. Коды кнопок. В большинстве случаев в девайсах работает принцип обработка всех кнопок, как одну. Сочетания или одновременное нажатие кнопок используется не всегда.
Подсчет количества нажатий это уже задача конкретного проекта. Именно по этому я говорил про универсальность. Берешь свои готовые либы и чуток подпиливаешь под нужный проект. В большинстве случаев просто дефайнами переназначаешь пины мк. В вашем же случае это всегда глубокая переработка.

To ARV. Поддерживаю. Очередь кнопок не всегда нужна. Далеко не всегда. Это уже попахивает более серьезными проектами и микроконтроллерами. Скорее, линуксом. :)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 11:01:34 
Поставщик валерьянки для Кота

Карма: 20
Рейтинг сообщений: 256
Зарегистрирован: Вс июн 19, 2016 09:32:03
Сообщений: 2089
Рейтинг сообщения: 0
Очереди, структуры в очередях... Как обычно, забыли о разделе, где идет обсуждение: в большинстве популярных AVR на очередь кнопок половина ОЗУ уйдет

Не очередь, а опциональная и выключенная по умолчанию очередь. А структура у меня на STM32, там 32 бита в регистре вернуть можно, на AVR никто так делать не заставляет.

Добавлено after 2 minutes 24 seconds:
To Reflector. Задача модуля кнопок выдать события нажатия, отжатия, удержания и повтора. Коды кнопок. В большинстве случаев в девайсах работает принцип обработка всех кнопок, как одну. Сочетания или одновременное нажатие кнопок используется не всегда.
Подсчет количества нажатий это уже задача конкретного проекта. Именно по этому я говорил про универсальность. Берешь свои готовые либы и чуток подпиливаешь под нужный проект. В большинстве случаев просто дефайнами переназначаешь пины мк. В вашем же случае это всегда глубокая переработка.

Ничего не понял, я же показал код в котором все конфигурируется в одном месте, где там глубокая переработка? То весь код, минимум две строки, дальше нужно вызвать init(), update и получить состояние кнопок, т.е. еще 3 строки. Сам класс живет в хедере и никогда не меняется, никаких дефайнов и т.д. больше нигде нет.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 11:54:54 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 139
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1480
Рейтинг сообщения: 0
Ты же сам написал. На си красиво не получится. Я про си и говорю


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 12:13:47 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 98
Рейтинг сообщений: 2135
Зарегистрирован: Чт дек 28, 2006 08:19:56
Сообщений: 18447
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Имхо, на си более-менее красиво получается, если писать отдельно систему событий и их обработку. А генератором событий делать, что угодно. Тогда верхний уровень пользуется только функцией get_event, а уж эта функция может и очередь обрабатывать, и приоритеты... А готовить данные для этой функции можно, как угодно: по таймеру кнопок, по прерыванию USART и т.п. Там же где-то внутри можно и двойные клики делать, и одновременные нажатия...

_________________
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 13:10:06 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 139
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1480
Рейтинг сообщения: 0
Как бы об этом я и писал и примерно так у меня и реализовано.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Пн фев 14, 2022 22:36:53 
Опытный кот
Аватар пользователя

Карма: -2
Рейтинг сообщений: -23
Зарегистрирован: Сб окт 22, 2016 17:33:32
Сообщений: 760
Откуда: кг
Рейтинг сообщения: 0
А чего стоит оставить своё мнение при себе?
Или, требуется _всех_ убедить в правильности своего мнения?
Я прекрасно понимаю, о чем вы пишите.
Только смысла в ваших конструкциях не вижу.
Переиначивая, весь ваш бред - бессмысленная хня.
Не умеешь писать - не пиши.

Добавлено after 3 hours 28 minutes 25 seconds:
примерно так у меня и реализовано.

Не стесняйся, выкладывай.
Счас все поржём.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Вт фев 15, 2022 03:09:53 
Это не хвост, это антенна

Карма: 4
Рейтинг сообщений: 139
Зарегистрирован: Ср июн 25, 2008 15:19:44
Сообщений: 1480
Рейтинг сообщения: 0
Вроде весна ещё не наступила... Выпил?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: 2 кнопки - Нужно выжать 5 режимов обработки.
СообщениеДобавлено: Вт фев 15, 2022 10:31:32 
Встал на лапы

Зарегистрирован: Чт дек 16, 2021 18:20:02
Сообщений: 95
Рейтинг сообщения: 0
Всем привет. продолжаю эксперименты с кнопками.
Набросал вот такой код:
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "main.h"

volatile uint8_t button1_count;// счетчик кнопки 1
volatile uint8_t button2_count;// счетчик кнопки 2
volatile uint8_t button3_count;// счетчик кнопки 2
volatile uint8_t button_click;//







// обработчик прерывания по переполнению таймера 0
ISR(TIMER0_OVF_vect)
{
   //=========== опрос первой кнопки =============
   if (~PINC&(1<<PC0)) // если на ПИНе 1
   {
      if (bit.flag_1==0) //если флаг =0 , то считаем до 120 иначе до 61
      {
         if (button1_count<120) button1_count++;//Счетчик будет считать до 120 (~2с)
         if (bit.flag_2==1) //Если флаг =1 включаем репит клик (быстрый инкримент)
         {
            if(button1_count==118)
               button1_count=112;
               button_click=0;
         }
      }   
      else
      {
         if (button1_count<61) button1_count++;//Счетчик будет считать до 61 (~1с)   
      }   
   }
   else
   {
      if ((button1_count>5) && (button1_count<30)) bit.but_1=1;   //Короткий клик
      if ((button1_count>29) && (button1_count<=61)) bit.but_1=2;    //Средний клик
      if ((button1_count>61) && (button1_count<=120))bit.but_1=3;  //Длинный клик
           button1_count=0;
   }
   //===========Опрос второй кнопки ===========
   if (~PINC&(1<<PC1)) // если на ПИНе 1    
   {
      if (bit.flag_1==0) //если флаг =0 , то считаем до 120 иначе до 61
      {
         if (button2_count<120) button2_count++;//Счетчик будет считать до 120 (~2с)
      }
      else
      {
         if (button2_count<61) button2_count++;//Счетчик будет считать до 61 (~1с)
      }      
   }
   else
   {
      if ((button2_count>5) && (button2_count<30)) bit.but_2=1;    //Короткий клик
      if ((button2_count>29) && (button2_count<61)) bit.but_2=2;    //Средний клик
      if ((button2_count>61) && (button2_count<=120))   bit.but_2=3; //Длинный клик
         button2_count=0;
   }
   ////===========Опрос третьей кнопки ===========
   if (~PINC&(1<<PC2)) // если на ПИНе 1
   {
      if (bit.flag_1==0) //если флаг =0 , то считаем до 120 иначе до 61
      {
         if (button3_count<120) button3_count++;//Счетчик будет считать до 120 (~2с)
      }
      else
      {
         if (button3_count<61) button3_count++;//Счетчик будет считать до 61 (~1с)
      }   
   }
   else
   {
      if ((button3_count>5) && (button3_count<30)) bit.but_3=1;    //Короткий клик
      if ((button3_count>29) && (button3_count<=61)) bit.but_3=2;    //Средний клик
      if ((button3_count>61) && (button3_count<=120))   bit.but_3=3; //Длинный клик
      button3_count=0;
   }
   
   button_click = (bit.but_1<<4)|(bit.but_2<<2)|(bit.but_3);   
}

int main(void)
{
   TCCR0|=(1<<CS01) | (1<<CS00);// запуск таймера 0 с делителем 64
   TIMSK|=(1<<TOIE0); // разрешить прерывание по переполнению таймера 0
   
   DDRB=0xff;// пины светодиодов на вsход
   PORTB=0;
   DDRC &= ~(1<<PC0) | (1<<PC1) |(1<<PC2)|(1<<PC5)|(1<<PC4);
   PORTC|= (1<<PC0) | (1<<PC1) |(1<<PC2)|(1<<PC5)|(1<<PC4);

   
   sei();//глобально разрешить перерывания




   


   while (1)
   {

       if (~PINC&(1<<PC5))
        bit.flag_1=1;
        else
        bit.flag_1 =0;
        if (~PINC&(1<<PC4))
        bit.flag_2=1;
        else
        bit.flag_2 =0;
       

   
   }
}


Код:
#ifndef MAIN_H_
#define MAIN_H_
   struct my_button
   {
      unsigned char but_1:2;    //Битовый код 1ой кнопки 0-3
      unsigned char but_2:2;  //Битовый код 2ой кнопки 0-3
      unsigned char but_3:2;    //Битовый код 3ей кнопки 0-3
      unsigned char flag_1:1;  // Флаг разрешающий клик двух кнопок
      unsigned char flag_2:1;    // Флаг разрешающий инкремент по длинному клику
   };
    struct my_button bit;



#endif /* MAIN_H_ */


Но проблема в том, что в Протеусе, при отпускании кнопки, условия Элс выполняются через раз.
Счетчик сбрасывается в ноль стабильно, а вот присвоения значений bit.but_*** происходит как то не стабильно.
Подскажите, почему так происходит.
Думал про дребезг при отпускании, но раз счетчик обнуляется, то программа прорходит по всем сравнениям Ифф.

Тестирую пока все на кнопке РС0.


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 54 ]    , , 3

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 29


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y