реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Мгновенно реагировать на нажатие кнопки. Attiny 2313, прерывания
aivs
сообщение Mar 8 2013, 20:12
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731



Учусь программировать под Attiny 2313, написал такую программку:
Если нажать на кнопку, то запускается цикл мигания 6 светодиодов, если в конце мигания шестого светодиода нажать кнопку, то мигание выключится.
Вот код для gcc:
Код
unsigned char LIGHT = 0;
while (1) {
  // Если свет не горит и нажата кнопку
  if (LIGHT == 0 && bit_is_clear(PIND,0)) {
    // Включить свет
    while (LIGHT == 0) {
        PORTB = 0b11111110;
        _delay_ms(200);
        PORTB = 0b11111101;
        _delay_ms(200);
        PORTB = 0b11111011;
        _delay_ms(200);
        PORTB = 0b11110111;
        _delay_ms(200);
        PORTB = 0b11101111;
        _delay_ms(200);
        PORTB = 0b11011111;
        _delay_ms(200);
        // Если нажата кнопка, то выключаем свет
        if (bit_is_clear(PIND,0)) {
            PORTB = 0b11111111;
            _delay_ms(200);
            LIGHT = 1;
        }
    }
  }
  // Если свет выключен и нажата кнопка, то включаем свет
  if (LIGHT == 1 && bit_is_clear(PIND,0)) {
    LIGHT = 0;
  }
}

Работает как я и планировал, но есть одна недоработка.

Как сделать так, чтобы нажав на кнопку в ЛЮБОЙ момент времени светодиоды остановились мигать (а не только в конце цикла мигания)? подскажите куда копать? если есть простой пример на Си буду рад его изучить.

Сообщение отредактировал aivs - Mar 8 2013, 20:14
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Mar 8 2013, 20:27
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(aivs @ Mar 8 2013, 23:12) *
Как сделать так, чтобы нажав на кнопку в ЛЮБОЙ момент времени светодиоды остановились мигать (а не только в конце цикла мигания)? подскажите куда копать? если есть простой пример на Си буду рад его изучить.


Вам надо фиксацию нажатия кнопки выполнять в прерывании или периодически по таймеру обязательно с алгоритмом антидребезга. И управлять длительностью моргания формируя задержки с помощью таймера.

Для простоты замените delay_ms(200) на некую процедуру которая будет опрашивать флаг таймаута и состояние нажатия кнопки. Если обнаружено нажатие кнопки, то гасите светодиоды и переходите в исходное состояние. Если обнаружен флаг таймаута, то выполняете цикл моргания дальше. Флаг таймаута устанавливайте в прерывании от таймера счётчика.
Go to the top of the page
 
+Quote Post
kovigor
сообщение Mar 9 2013, 04:24
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(aivs @ Mar 8 2013, 23:12) *
Как сделать так, чтобы нажав на кнопку в ЛЮБОЙ момент времени светодиоды остановились мигать (а не только в конце цикла мигания)? подскажите куда копать? если есть простой пример на Си буду рад его изучить.

По-научному это называется "машина состояний" ("state machine")", или "цифровой автомат". Например:
http://mcu.ucoz.ru/publ/programmirovanie/r...llerov/11-1-0-4
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Mar 9 2013, 08:19
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(kovigor @ Mar 9 2013, 07:24) *
По-научному это называется "машина состояний" ("state machine")", или "цифровой автомат".


+1
Сам поначалу описал вариант с применением автомата состояний, но потом для простоты предложил заменить процедуру.
Опишу ещё раз.
Вводите переменную состояние устройства state которая будет принимать значения 0 - ожидание нажатия, 1 - исполнение цикла.
button - флаг нажатия кнопки.
timer - таймер для формирования требуемой задержки
led_cnt - счётчик морганий

Код
switch(state)
{
case 0:
if(button)
{
//переход на моргание по нажатию кнопки
button = 0;
state = 1;
ledOn();
timer = _200mS;
led_cnt = 12;
}
break;

case 1:
if(button)
{
//переход в исходное состояние по нажатию кнопки
button = 0;
state = 0;
ledOff();
timer = 0;
}

if(timer == 0)
{

if(led_cnt>0)
{
//инвертируем состояние светодиодов
led_cnt--;
ledInvert();
timer = _200mS;
}
else
{
//переход в исходное состояние т.к. отработали цикл
button = 0;
state = 0;
ledOff();
timer = 0;
}

}
break;


default:
//переход в исходное из неизвестного состояния автомата (это на всякий случай)
button = 0;
state = 0;
ledOff();
timer = 0;
break;
}


Запускаете такой автомат в вечном цикле. А в прерывании от таймера сканируете кнопку и выполняете обратный отсчёт переменной timer с самоостановом
Код
if(timer) timer--;


Если ввести много состояний и определить условия перехода из одного в другой, то можете реализовывать различные световые эффекты или обеспечить некоторую световую индикацию. Я подобный образом формирую индикацию режимов работы своих устройств где в зависимости от состояния устройства(устройство спит, подключено к серверу, ищет сеть GSM и т.д.) светодиод зажигается/гасится на абсолютно разные интервалы времени.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Mar 9 2013, 11:13
Сообщение #5


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Могу предложить рабочий кусок кода с простеньким планировщиком задач и службой времени. Правда немного поправить наверно придется...это всё для меги8 писалось.
Антидребезг также присутсвтует.

Основной цикл будет выглядеть как-то так:
Код
void some_task()
{
//делаем что-то каждые 200ms
}

void some_task2()
{
//делаем что-то каждые 50ms
}

int main(void)
{
    uint8_t last_keys, keys;
    timer0_init();
    kbd_init();
    //клавиатура опрашивается каждые 20 миллисекунд
    shed_add_task(kbd_upd_rawstate, 20);
        //делаем что-то каждые 200ms
    shed_add_task(some_task, 200);
        //делаем что-то каждые 50ms
    shed_add_task(some_task2, 50);
    last_keys = 0;
    while(1)
    {      
        shed_upd_state();
        shed_run_tasks();            
        
        keys = kbd_get_keys();
        if ( (last_keys != keys) )
        {
            if ( (keys & 0x2) )
            {        
            //делаем что-то по кнопке 2
            }
            
            if ( (keys & 0x1) )
            {
            //делаем что-то по кнопке 1
            }    
            last_keys = keys;
        }
    }            
}

Выкладывать? Или сами птренеруетесь?


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
aivs
сообщение Mar 9 2013, 17:19
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731



Выкладывайте, изучу, спасибо за помощь
Go to the top of the page
 
+Quote Post
ARV
сообщение Mar 9 2013, 17:44
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



примитивные решения. надо многозадачную ОС для решения этой задачи. а чтобы было проще - бросить ущербную 8-битную архитектуру, взять ARM.


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Mar 9 2013, 18:01
Сообщение #8


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
римитивные решения. надо многозадачную ОС для решения этой задачи. а чтобы было проще - бросить ущербную 8-битную архитектуру, взять ARM.
Согласен, но для начала и AVR покатит))
Прикрепленные файлы
Прикрепленный файл  Electronix_help.zip ( 10.26 килобайт ) Кол-во скачиваний: 12
 


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
kovigor
сообщение Mar 9 2013, 18:04
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(ARV @ Mar 9 2013, 20:44) *
примитивные решения. надо многозадачную ОС для решения этой задачи. а чтобы было проще - бросить ущербную 8-битную архитектуру, взять ARM.

Да. Каждой детской песочнице - по мощному экскаватору. Самое то ...
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Mar 9 2013, 22:37
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(ARV @ Mar 9 2013, 21:44) *
примитивные решения. надо многозадачную ОС для решения этой задачи. а чтобы было проще - бросить ущербную 8-битную архитектуру, взять ARM.

ARM для такой задачи ТС слабоват. Вот со скрипом , может быть потянет. Но лучше поставить 2 и сразу.


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Mar 9 2013, 22:56
Сообщение #11


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Вообще нет, надо отечественный четырехядерник ставить, в интеле закладки же могут быть!
Можно кстати одним ядром клаву опрашивать, а вторым лампочки зажигать ) профит))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 10 2013, 06:33
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(sigmaN @ Mar 10 2013, 02:56) *
Вообще нет, надо отечественный четырехядерник ставить, в интеле закладки же могут быть!

Советские микросхемы - самые большие микросхемы в мире! (с) biggrin.gif
Go to the top of the page
 
+Quote Post
kolobok0
сообщение Mar 11 2013, 10:37
Сообщение #13


практикующий тех. волшебник
*****

Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417



Цитата(toweroff @ Mar 10 2013, 10:33) *
...Советские микросхемы - самые большие микросхемы в мире!...


это потому, что наши закладки студенты пишут на си бимоле sm.gif))
Go to the top of the page
 
+Quote Post
PheeL
сообщение Mar 11 2013, 13:43
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 24-11-07
Пользователь №: 32 633



Цитата(sigmaN @ Mar 10 2013, 02:56) *
Вообще нет, надо отечественный четырехядерник ставить, в интеле закладки же могут быть!
Можно кстати одним ядром клаву опрашивать, а вторым лампочки зажигать ) профит))

Вы забыли упомянуть, что это всё надо делать только под Линуксом, потому что микро-РТОС для таких задач совершенно не подходят, т.к. для них нет готовых коммуникационных стеков и драйверов! )


--------------------
Если друг оказался вдруг и не друг и не враг, а - JTAG.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Mar 11 2013, 18:47
Сообщение #15


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Ну это само собой! RT патч только не забыть))))

P.S. ой чую влетит нам щас за оффтоп )))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 24th July 2025 - 00:41
Рейтинг@Mail.ru


Страница сгенерированна за 0.01521 секунд с 7
ELECTRONIX ©2004-2016