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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
_Pasha
сообщение Apr 8 2013, 07:57
Сообщение #16


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_basile @ Apr 8 2013, 10:52) *
Как тут уже заметили, температура - штука достаточно инерционная, поэтому ее вполне можно считывать раз в 10 секунд.

Вы не с того конца мысль выразили. sm.gif Чаще считывать температуру не надо, потому что в этом случае идет саморазогрев ds18b20.
Go to the top of the page
 
+Quote Post
_basile
сообщение Apr 8 2013, 08:08
Сообщение #17


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

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



Цитата(_Pasha @ Apr 8 2013, 11:57) *
Вы не с того конца мысль выразили. sm.gif Чаще считывать температуру не надо, потому что в этом случае идет саморазогрев ds18b20.

Палка - о двух концах. И что, сильный саморазогрев ? А если бы аналоговый датчик был, то зафигачиваем, на сколько АЦП тянет ?
Мой подход - с точки зрения логики. И относится не только к датчикам температуры. Зачем "грузить" процессор, если в этом нет необходимости?


--------------------
" Будут с водкою дебаты, отвечай : Нет ребяты-демократы, только чай ! "
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 8 2013, 08:22
Сообщение #18


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(_basile @ Apr 8 2013, 11:08) *
И что, сильный саморазогрев ? А если бы аналоговый датчик был, то зафигачиваем, на сколько АЦП тянет ?
Мой подход - с точки зрения логики. И относится не только к датчикам температуры. Зачем "грузить" процессор, если в этом нет необходимости?

Разогрев до 3 градусов - аж бегом. И Zth корпуса не позволяет культурно отвести тепло.
Насчет инерционности: объясните это устройству, измеряющему и регулирующему температуру воздушного потока. Или контроллеру модуля Пельтье в режимах вблизи точки росы. sm.gif

Цитата(_basile @ Apr 8 2013, 10:52) *
Ха! Дак у топикстартера что в прерывании по таймеру творится:

sm.gif ага.
Go to the top of the page
 
+Quote Post
aivs
сообщение Apr 8 2013, 13:36
Сообщение #19


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

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



Спасибо, уберу из прерывания:
Код
_delay_ms(25); // Пауза на 25 мс Ну, и ктож задержки делает в обработчике прерываний ??????
if (bit_is_clear(PIND,5)) { // Если кнопка PD5 нажат
while (bit_is_clear(PIND,5)); //Ждем отжатия клавиши Еще бы не тормозило !

На дисплей информацию буду выводить по мере ее поступления, а не в цикле.
Датчик температуры по реже буду опрашивать.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Apr 8 2013, 14:36
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 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() увеличивает задержку на время входа в прерывание, его обработки и выхода из прерывания.

Странность в том же, что в случае вызова задержек в прерывании. Нехорошо это.

Go to the top of the page
 
+Quote Post
aivs
сообщение Apr 8 2013, 16:37
Сообщение #21


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

Группа: Участник
Сообщений: 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"
Ну, и зачем кнопки по таймеру опрашивать?


А у меня три кнопки, как быть если не по таймер опрашивать?
Go to the top of the page
 
+Quote Post
ARV
сообщение Apr 8 2013, 17:48
Сообщение #22


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

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



всем начинающим всегда рекомендую мудрить поменьше, а поступать попроще: делайте в прерываниях только то, что либо требует мгновенной реакции на внешнее событие, либо должно происходить незаметно для всех остальных дел. для первого подходят прерывания от внешних сигналов типа INT0, встроенных SPI и т.п. интерфейсов, а для второго - таймеры (иногда иначе). при этом всегда обработчик прерывания должен стремиться быть максимально коротким по времени выполнения.

кнопки по определению не попадают в эти категории, т.к. работа с ними всегда ведется в диапазоне человеческих реакций: человек физически неспособен заметить разницу между мгновенной реакцией на нажатие кнопки и реакцией, последовавшей через 150 миллисекунд (чертовски много по меркам МК), т.к. только специально тренированный человек имеет мускульную реакцию, соизмеримую с этим интервалом времени, все прочие тормозят сильнее.

все это я к тому, что работу кнопок в 99% случаев следует делать самым тупым способом - методом опроса пинов в главном цикле. при числе кнопок не более 8, особенно если они подключены к пинам одного порта, лучше этого способа вряд ли можно придумать.

итак, опрос кнопок - методом поллинга в главном цикле, т.е. без прерываний.

надеюсь, проведя аналогичные рассуждения можно прийти к выводу, что индикация на ЖКИ и работа с DS18B20 так же не попадают в категорию, для которой применение прерываний является НЕОБХОДИМЫМ. следовательно, не мудрите понапрасну, в главном цикле делайте все максимально просто:
1. вывели на индикатор подготовленные данные
2. опросили кнопки
3. обменялись с датчиком температуры
4. в зависимости от нажатой кнопки подготовили новые данные
5. перешли к п.1

и будет вам счастье!


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


Гуру
******

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



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

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


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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

Интересно все-таки, какой индивид первым придумал, что пофиксенная бага есть фича ...
Go to the top of the page
 
+Quote Post
aivs
сообщение Apr 9 2013, 08:17
Сообщение #25


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

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



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

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


;
******

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Apr 9 2013, 09:43
Сообщение #27


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

Группа: Свой
Сообщений: 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
Сообщение #28


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

Группа: Свой
Сообщений: 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
Сообщение #29


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

Группа: Свой
Сообщений: 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

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

 


RSS Текстовая версия Сейчас: 27th June 2025 - 20:18
Рейтинг@Mail.ru


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