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

 
 
> Многопоточность на attiny2313
aivs
сообщение Apr 6 2013, 21:15
Сообщение #1


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

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



Продолжаю изучать программирование под avr.
Написал программу "Часы", добавил три кнопки для выставления времени, кнопки обрабатываются по прерыванию от Таймера каждые 0.1 сек, время тикает от того же таймера, все красиво и четко работает.
Затем я задействовал термодатчик ds18b20 с шиной 1ware и написал программу для показа температуры на дисплее hd44780, датчик опрашивается по прерыванию от таймера каждые 0.1 сек, прекрасно работает.
А затем я решил совместить эти две программы, чтобы часы в одной части дисплея работали, а температура в другой части. Получилось кривенько, при опросе датчика прерывания запрещены, соответственно на нажатия кнопок реакция заторможенная.
Подскажите, как бы реализовать подобие многопоточности?
Может тут подойдут конечные автоматы?
Приветствую список литературы по этому вопросу!
А может для attiny2313 вообще это не возможно сделать без тормозов?

Сообщение отредактировал aivs - Apr 6 2013, 21:16
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Xenia
сообщение Apr 8 2013, 22:36
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Я тоже сразу заметила, что в этой программе пока держишь кнопку нажатой, то висишь в прерывании, а система стоит. Тоже сперва хотела этим возмутиться, но одумалась sm.gif. В принципе процесс установки времени не обязан сопровождаться одновременной работой устройства. Например, никто не возмущается тем, что в процессе установки точного времени (перевода часов) на микроволновке в это время нельзя жарить курицу-гриль. sm.gif Вот и наручные часы не обязаны соблюдать точность хода, пока им переводят стрелки. А COM-порт соблюдать правильную передачу, в то время, тогда ему переустанавливают боды.

Поэтому, наверное, не стоит заставлять топикстатера возиться с этими кнопками, переводя их правильный режим. Поскольку он имеет полное право не рассматривать установочную процедуру, как часть рабочего цикла.
Go to the top of the page
 
+Quote Post
aivs
сообщение Apr 9 2013, 08:17
Сообщение #3


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

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



Цитата(Xenia @ Apr 9 2013, 02:36) *
Поэтому, наверное, не стоит заставлять топикстатера возиться с этими кнопками, переводя их правильный режим. Поскольку он имеет полное право не рассматривать установочную процедуру, как часть рабочего цикла.

Нет! заставляйте меня делать правильно! Я только учусь и хочу все делать правильно, сложностей не боюсь.
И еще во время установки времени, я бы хотел, чтобы время шло, в данный момент время останавливается пока кнопка нажата, это и понятно, но я уберу из прерывания обработку нажатий, в перывании буду только менять статус переменной для кнопки: нажата/не нажата
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Apr 9 2013, 09:43
Сообщение #4


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

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



Цитата(aivs @ Apr 9 2013, 11:17) *
Нет! заставляйте меня делать правильно! Я только учусь и хочу все делать правильно, сложностей не боюсь.
И еще во время установки времени, я бы хотел, чтобы время шло, в данный момент время останавливается пока кнопка нажата, это и понятно, но я уберу из прерывания обработку нажатий, в перывании буду только менять статус переменной для кнопки: нажата/не нажата


Простейший вариант организации обработки кнопки. Раньше я пользовался подобным методом (один из вариантов, их у меня много было).

Код
typedef struct {
unsigned char status; //статус структуры, не кнопки!!!
unsigned char timer; //таймер
} stButton;
stButton button[1]; //это одна кнопка, а может быть несколько если записать button[3];

#define button1_msk 0x1; //маска кнопки 1
unsigned char button_states;
volatile unsigned char timer_flag;
unsigned char one_wire_timer = 0; //это позволит быстро произвести первый опрос датчика
unsigned char display_flag = 1; //это позволит первый раз отобразить данные на индикаторе

while(1)
{

//код ниже будет выполняться только если установлен флаг прерывания от таймера
//этот флаг можно устанавливать скажем раз в 10 мС
//грубо говоря это системный таймер
if(timer_flag)
{
timer_flag = 0;

button_states = getDin(); //получения текущего состояния кнопок

//декремент таймеров кнопок (может быть несколько)
if(button[0].timer > 0) button[0].timer --;

//обработка кнопок (может быть не одна кнопка)
switch(button[0].status)
{
case 0: //ожидание нажатия кнопки
           if(button_states & button1_msk)
           {
              //ожидаемая кнопка нажата
              //какие-либо действия для данной кнопки - например инкремент часов
             incHoures(); //эта процедура должна устанавливать флаг что данные на индикаторе обновились

             button[0].status = 1; //переход на ожидание отпускания
             button[0].timer = 50; //таймаут автоинкремента (50*(период системного таймера) == 500мС)
           }
break;
case 1: //ожидание нажатия кнопки
           if( !(button_states & button1_msk) )
           {
              //ожидаемая кнопка отпущена
             button[0].status = 0; //переход на ожидание нажатия
             button[0].timer = 30; //таймаут антидребезга  (30*(период системного таймера) == 300 мС)
           }

          if(button.timer == 0)
         {
             //вышел таймаут автоинкремента
            //какие-либо действия для данной кнопки - например инкремент часов
             incHoures(); //эта процедура должна устанавливать флаг что данные на индикаторе обновились
            
                       button[0].timer = 50; (50*(период системного таймера) == 500мС)
         }
break;

default: button[0].status = 0; //переход на ожидание нажатия
            button[0].timer = 0;
break;
}

//проверка флага опроса по 1wire
if(one_wire_timer > 0) one_wire_timer--;
else
{
one_wire_timer = 1000; (1000*(период системного таймера) == 10000 мС)
//тут опрос датчика, после опроса необх удостоверится что температура поменялась и установить флаг что данные на индикаторе обновились
}

//проверка флага необходимости отображения изменений на индикаторе
//может быть установлен по нажатию кнопок, после опроса 1-wire или при изменении времени

if(display_flag)
{
display_flag = 0;
//отображам изменения на индикаторе
}

}

__enable_interrupt();
__sleep();

}


Вам необходимо организовать прерывания от таймера с периодом скажем 10 мС и устанавливать в них флаг timer_flag.
При желании можете завести отдельный таймер с секундными прерываниями для часов или использовать системный таймер.
Как определить нужен ли Вам отдельный таймер для часов - если длительность опроса 1-wire будет заведомо меньше периода системного таймера, то можете использовать системный таймер. Иначе для надёжности введите таймер для часов или просто увеличьте системный период.
В результате у Вас одно (максимум 2 простых прерывания) и определяемая вами реакция на кнопки.
Go to the top of the page
 
+Quote Post
ARV
сообщение Apr 9 2013, 10:11
Сообщение #5


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

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



Цитата(mempfis_ @ Apr 9 2013, 13:43) *
Простейший вариант организации обработки кнопки.



в общем на самом деле простейший вариант, для начинающего самое то smile3009.gif

P.S. судя по вашему коду, МК у вас спит все время между прерываниями таймера - нафига тогда флаги какие-то?!




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


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

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



Цитата(ARV @ Apr 9 2013, 13:11) *
P.S. судя по вашему коду, МК у вас спит все время между прерываниями таймера - нафига тогда флаги какие-то?!


В этой программе может быть флаги не нужны, и то при условии что будет только один источник прерываний от системного таймера. Если прерываний будет несколько (другие таймеры, уарты и т.д.) то без этого флага никак т.к. мк просыпается от любого прерывания. Лучше сразу выработать правильный подход. Можно вообще не использовать таймер и для отлад ввести delay_ms(); вместо __enable_interrupt(); __sleep();

Для топикстартера - чтобы работала инструкция __sleep(); необходимо установить бит SE регистра MCUCSR. Если этого не сделать, то процессор будет себя вести так, будто совсем не спит. Если бы не было флага от таймера, то сами догадайтесь что могло бы произойти с исполняемой программой sm.gif
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- aivs   Многопоточность на attiny2313   Apr 6 2013, 21:15
- - ILYAUL   ЦитатаПолучилось кривенько, при опросе датчика пре...   Apr 6 2013, 21:52
- - Xenia   Цитата(aivs @ Apr 7 2013, 01:15) Получило...   Apr 6 2013, 23:39
|- - _Артём_   Цитата(Xenia @ Apr 7 2013, 02:39) что нел...   Apr 7 2013, 00:31
- - aivs   В прерывании я опрашиваю три кнопки, и если кнопка...   Apr 7 2013, 07:38
|- - Xenia   Цитата(aivs @ Apr 7 2013, 11:38) Код // ...   Apr 7 2013, 12:23
||- - _Pasha   Цитата(Xenia @ Apr 7 2013, 15:23) Возможн...   Apr 7 2013, 14:19
||- - Xenia   Цитата(_Pasha @ Apr 7 2013, 18:19) Там в ...   Apr 7 2013, 14:31
||- - _Pasha   Цитата(Xenia @ Apr 7 2013, 17:31) А syste...   Apr 7 2013, 14:35
|- - mempfis_   ЦитатаЗадержки с использованием _delay_us и _delay...   Apr 7 2013, 12:58
- - _Pasha   Могу сказать, как делаю я. 1. Беру за основу идею,...   Apr 7 2013, 09:58
- - mempfis_   Цитата(aivs @ Apr 7 2013, 01:15) Затем я ...   Apr 7 2013, 11:12
|- - _Артём_   Цитата(mempfis_ @ Apr 7 2013, 14:12) Есть...   Apr 7 2013, 19:37
|- - mempfis_   ЦитатаПроблемы скорее нет, чем есть. Разве самому ...   Apr 8 2013, 07:31
|- - _basile   DATASHEET 2313: "The External Interrupts are ...   Apr 8 2013, 07:52
||- - _Pasha   Цитата(_basile @ Apr 8 2013, 10:52) Как т...   Apr 8 2013, 07:57
|||- - _basile   Цитата(_Pasha @ Apr 8 2013, 11:57) Вы не ...   Apr 8 2013, 08:08
|||- - _Pasha   Цитата(_basile @ Apr 8 2013, 11:08) И что...   Apr 8 2013, 08:22
||- - aivs   Цитата(_basile @ Apr 8 2013, 11:52) DATAS...   Apr 8 2013, 16:37
|- - _Артём_   Цитата(mempfis_ @ Apr 8 2013, 10:31) Не в...   Apr 8 2013, 14:36
- - aivs   Спасибо, уберу из прерывания: Код_delay_ms(25...   Apr 8 2013, 13:36
- - ARV   всем начинающим всегда рекомендую мудрить поменьше...   Apr 8 2013, 17:48
- - _Pasha   Цитата(Xenia @ Apr 9 2013, 01:36) Поэтому...   Apr 9 2013, 01:23
- - _Pasha   Цитата(aivs @ Apr 9 2013, 11:17) Нет...   Apr 9 2013, 09:14


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

 


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


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