|
Многопоточность на attiny2313 |
|
|
|
Apr 8 2013, 08:08
|
Частый гость
 
Группа: Участник
Сообщений: 175
Регистрация: 18-01-06
Из: Москва
Пользователь №: 13 329

|
Цитата(_Pasha @ Apr 8 2013, 11:57)  Вы не с того конца мысль выразили.  Чаще считывать температуру не надо, потому что в этом случае идет саморазогрев ds18b20. Палка - о двух концах. И что, сильный саморазогрев ? А если бы аналоговый датчик был, то зафигачиваем, на сколько АЦП тянет ? Мой подход - с точки зрения логики. И относится не только к датчикам температуры. Зачем "грузить" процессор, если в этом нет необходимости?
--------------------
" Будут с водкою дебаты, отвечай : Нет ребяты-демократы, только чай ! "
|
|
|
|
|
Apr 8 2013, 13:36
|
Частый гость
 
Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731

|
Спасибо, уберу из прерывания: Код _delay_ms(25); // Пауза на 25 мс Ну, и ктож задержки делает в обработчике прерываний ?????? if (bit_is_clear(PIND,5)) { // Если кнопка PD5 нажат while (bit_is_clear(PIND,5)); //Ждем отжатия клавиши Еще бы не тормозило ! На дисплей информацию буду выводить по мере ее поступления, а не в цикле. Датчик температуры по реже буду опрашивать.
|
|
|
|
|
Apr 8 2013, 14:36
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(mempfis_ @ Apr 8 2013, 10:31)  Не всегда программист выбирает к какому выводу подключать датчики. Ну да, на RESET не подключили - и на том спасибо. Но всё-таки выводы надо бы соответственно задаче выбирать. Цитата(mempfis_ @ Apr 8 2013, 10:31)  И не всегда "правильные" выводы свободны. Бывает...тогда другой МК лучше выбирать, более подходящий. Цитата(mempfis_ @ Apr 8 2013, 10:31)  Зато можно написать одну процедуру чтения 1-wire устройства, которая будет работать на любом пине любого порта AVR. Решение универсальное и отсюда его недостатки. Цитата(mempfis_ @ Apr 8 2013, 10:31)  В чём странность запрещать прерывания? Возникновение прерывания во время вызова процедуры __delay_cycles() увеличивает задержку на время входа в прерывание, его обработки и выхода из прерывания. Странность в том же, что в случае вызова задержек в прерывании. Нехорошо это.
|
|
|
|
|
Apr 8 2013, 16:37
|
Частый гость
 
Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731

|
Цитата(_basile @ Apr 8 2013, 11:52)  DATASHEET 2313: "The External Interrupts are triggered by the INT0 pin, INT1 pin or any of the PCINT7..0" Ну, и зачем кнопки по таймеру опрашивать? А у меня три кнопки, как быть если не по таймер опрашивать?
|
|
|
|
|
Apr 8 2013, 17:48
|

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

|
всем начинающим всегда рекомендую мудрить поменьше, а поступать попроще: делайте в прерываниях только то, что либо требует мгновенной реакции на внешнее событие, либо должно происходить незаметно для всех остальных дел. для первого подходят прерывания от внешних сигналов типа INT0, встроенных SPI и т.п. интерфейсов, а для второго - таймеры (иногда иначе). при этом всегда обработчик прерывания должен стремиться быть максимально коротким по времени выполнения.
кнопки по определению не попадают в эти категории, т.к. работа с ними всегда ведется в диапазоне человеческих реакций: человек физически неспособен заметить разницу между мгновенной реакцией на нажатие кнопки и реакцией, последовавшей через 150 миллисекунд (чертовски много по меркам МК), т.к. только специально тренированный человек имеет мускульную реакцию, соизмеримую с этим интервалом времени, все прочие тормозят сильнее.
все это я к тому, что работу кнопок в 99% случаев следует делать самым тупым способом - методом опроса пинов в главном цикле. при числе кнопок не более 8, особенно если они подключены к пинам одного порта, лучше этого способа вряд ли можно придумать.
итак, опрос кнопок - методом поллинга в главном цикле, т.е. без прерываний.
надеюсь, проведя аналогичные рассуждения можно прийти к выводу, что индикация на ЖКИ и работа с DS18B20 так же не попадают в категорию, для которой применение прерываний является НЕОБХОДИМЫМ. следовательно, не мудрите понапрасну, в главном цикле делайте все максимально просто: 1. вывели на индикатор подготовленные данные 2. опросили кнопки 3. обменялись с датчиком температуры 4. в зависимости от нажатой кнопки подготовили новые данные 5. перешли к п.1
и будет вам счастье!
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Apr 8 2013, 22:36
|

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

|
Я тоже сразу заметила, что в этой программе пока держишь кнопку нажатой, то висишь в прерывании, а система стоит. Тоже сперва хотела этим возмутиться, но одумалась  . В принципе процесс установки времени не обязан сопровождаться одновременной работой устройства. Например, никто не возмущается тем, что в процессе установки точного времени (перевода часов) на микроволновке в это время нельзя жарить курицу-гриль.  Вот и наручные часы не обязаны соблюдать точность хода, пока им переводят стрелки. А COM-порт соблюдать правильную передачу, в то время, тогда ему переустанавливают боды. Поэтому, наверное, не стоит заставлять топикстатера возиться с этими кнопками, переводя их правильный режим. Поскольку он имеет полное право не рассматривать установочную процедуру, как часть рабочего цикла.
|
|
|
|
|
Apr 9 2013, 08:17
|
Частый гость
 
Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731

|
Цитата(Xenia @ Apr 9 2013, 02:36)  Поэтому, наверное, не стоит заставлять топикстатера возиться с этими кнопками, переводя их правильный режим. Поскольку он имеет полное право не рассматривать установочную процедуру, как часть рабочего цикла. Нет! заставляйте меня делать правильно! Я только учусь и хочу все делать правильно, сложностей не боюсь. И еще во время установки времени, я бы хотел, чтобы время шло, в данный момент время останавливается пока кнопка нажата, это и понятно, но я уберу из прерывания обработку нажатий, в перывании буду только менять статус переменной для кнопки: нажата/не нажата
|
|
|
|
|
Apr 9 2013, 09:14
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(aivs @ Apr 9 2013, 11:17)  Нет! Упражнение было для одного знакомого: 4 канала температуры + выход последовательного порта. Работает уж 3 года. Но код ужасен: я не ставил комментарии и всё это, можно сказать, левой ногой и в спешке. И на меге16. А по построению - все, что говорил выше. И даже плавучка есть, и все успевает и все прозрачно.
example.zip ( 17.8 килобайт )
Кол-во скачиваний: 71Конечно, со временем стало ясно, что можно и культурнее написать и меньше текста итд итп... PS еще тема есть такая http://electronix.ru/forum/index.php?showtopic=10934 прикреплённая, там много чего интересного.
Сообщение отредактировал _Pasha - Apr 9 2013, 09:18
|
|
|
|
|
Apr 9 2013, 09:43
|

Профессионал
    
Группа: Свой
Сообщений: 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 простых прерывания) и определяемая вами реакция на кнопки.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|