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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Таймер на Atmega8, Работает при симуляции, но не работает в железе
shatov
сообщение Oct 16 2013, 03:19
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 17-09-13
Пользователь №: 78 360



Таймер на Atmega8.

Таймер должен считать дни, питание от 3В. При нажатии на кнопку INT0 высвечивается счет секунд (нужно для проверки работоспособности таймера), при повторном нажатии высвечиваются отсчитанные дни. В спящий режим таймер переходит при нажатии на кнопку в третий раз, либо по истечении 5 сек с момента нажатия на кнопку в первый раз:

if (secL==5) {flagbutton=0;}
if (secL>9) {secH++; secL=0; flagbutton=0;}


Также необходим reset, но не замыканием соответствующего вывода на землю, а так, чтобы человек перепутав кнопки не сбросил свое насчитанное. Поэтому Reset осуществляется при последовательном нажатии int0 и зажимании PB5, т.е. нажав только PB5 таймер не сбросить.

Два индикатора: на одном отображаются единицы (PORTC), на другом - десятки (PORTD).
Т.к. питание от двух пальчиковых батареек, то необходим power save mode, поэтому ставлю внешний часовой кварц и по нему считает timer2.
Из спящего режима МК выходит по низкому уровню на INT0.

При симуляции всё работает, но при реализации на макетной плате ничего не выходит. Не пойму ошибку в коде. На этой же плате проверялась более простая версия прошивки (файл: as_work.c). Reset подтянул через 10k к питанию, кварц выдает что то похожее на нужную частоту с размахом около 0,5В. МК никак не реагирует на нажатие кнопки (INT0). Даже если бы совпадали моменты обнуления flagbutton и нажатия, то при повторном нажатии индикатор должен был бы показать число. МК обрабатывает нажатие INT0, т.к. ток потребления увеличивается (подключал к лабораторному БП), также варьировал с питанием (от 3 до 5В). Если кнопку не трогать, БП показывает ноль по потреблению тока, значит МК находится в режиме Powre Save и при нажатие обрабатывается прерывание... но почему ничего не выводится на сегменты, не могу понять.


#include <mega8.h>
#include <delay.h>

char sec=0;
int min=0;
int hour=0;
char secH=0, secL=0;
int flagbutton=0;
char dayH=0, dayL=0;


interrupt [EXT_INT0] void ext_int0_isr(void)
{
flagbutton++;
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
secL++;
if (secL==5) {flagbutton=0;}
if (secL>9) {secH++; secL=0; flagbutton=0;}
if (secH>5) {secH=0;}
if (sec>59) {min++; sec=0;}
if (min>59) {hour++; min=0;}
if (hour>23) {dayL++; hour=0;}
if (dayL>9) {dayH++; dayL=0;}
if (dayH>9) {dayH=0;}
}

void main(void)
{
PORTB=0x20;
DDRB=0x1F;
PORTD=0x04;
DDRD=0x3B;
PORTC=0x00;
DDRC=0xFF;

ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

GICR|=0x40;
GIFR=0x40;

MCUCR=0xB0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;

#asm("sei");

while (1)
{while (flagbutton==1)
{
switch(secL)
{
case 0:{PORTC=~0xC0; PORTB.0=0; break;}
case 1:{PORTC=~0xF9; break;}
case 2:{PORTC=~0xA4; PORTB.0=1; break;}
case 3:{PORTC=~0xB0; break;}
case 4:{PORTC=~0x99; break;}
case 5:{PORTC=~0x92; PORTB.0=1; break;}
case 6:{PORTC=~0x82; break;}
case 7:{PORTC=~0xF8; PORTB.0=0; break;}
case 8:{PORTC=~0x80; PORTB.0=1; break;}
case 9:{PORTC=~0x90; break;}
};

switch(secH)
{
case 0:{PORTD=~0x40; break;}
case 1:{PORTD=~0x79; break;}
case 2:{PORTD=~0xA0; break;}
case 3:{PORTD=~0x30; break;}
case 4:{PORTD=~0x19; break;}
case 5:{PORTD=~0x12; break;}
case 6:{PORTD=~0x02; break;}
case 7:{PORTD=~0x78; break;}
case 8:{PORTD=~0x00; break;}
case 9:{PORTD=~0x10; break;}
};
}
while (flagbutton==2)
{
switch(dayL)
{
case 0:{PORTC=~0xC0; PORTB.0=0; break;}
case 1:{PORTC=~0xF9; break;}
case 2:{PORTC=~0xA4; PORTB.0=1; break;}
case 3:{PORTC=~0xB0; break;}
case 4:{PORTC=~0x99; break;}
case 5:{PORTC=~0x92; PORTB.0=1; break;}
case 6:{PORTC=~0x82; break;}
case 7:{PORTC=~0xF8; PORTB.0=0; break;}
case 8:{PORTC=~0x80; PORTB.0=1; break;}
case 9:{PORTC=~0x90; break;}
};

switch(dayH)
{
case 0:{PORTD=~0x40; break;}
case 1:{PORTD=~0x79; break;}
case 2:{PORTD=~0xA0; break;}
case 3:{PORTD=~0x30; break;}
case 4:{PORTD=~0x19; break;}
case 5:{PORTD=~0x12; break;}
case 6:{PORTD=~0x02; break;}
case 7:{PORTD=~0x78; break;}
case 8:{PORTD=~0x00; break;}
case 9:{PORTD=~0x10; break;}
};
};

PORTD=0x04; PORTC=0x00; PORTB.0=0;
#asm("sleep");
}

}

Прикрепленные файлы
Прикрепленный файл  Timer_7sg.rar ( 33.86 килобайт ) Кол-во скачиваний: 10
 
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 16 2013, 04:30
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(shatov @ Oct 16 2013, 07:19) *
... но почему ничего не выводится на сегменты, не могу понять.
Вероятно, из-за дребезга контактов по однократному нажатию кнопки переменная flagbutton принимает значение гораздо больше единицы.
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 16 2013, 04:41
Сообщение #3


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(shatov @ Oct 16 2013, 07:19) *
... питание от 3В.
... Два индикатора: на одном отображаются единицы (PORTC), на другом - десятки (PORTD).
Т.к. питание от двух пальчиковых батареек, то необходим power save mode, поэтому ставлю внешний часовой кварц и по нему считает timer2.
Из спящего режима МК выходит по низкому уровню на INT0.

При симуляции всё работает, но при реализации на макетной плате ничего не выходит. Не пойму ошибку в коде.... МК находится в режиме Powre Save и при нажатие обрабатывается прерывание... но почему ничего не выводится на сегменты, не могу понять.

Если при симуляции все работает, зачем искать ошибку в коде? Попробуйте поискать ошибку в монтаже, о грамотной разводке земли недавно тема была. Опять же, два индикатора - это порядочный ток, как питание себя ведет? Ну и наконец - у меги 8-8 нижний предел питания 2.7в, у Вас какой?
В крайнем случае, код можно проверить по кускам, отключите прерывание и проверьте циклический вывод индикации, а потом уже двигайтесь дальше. Кстати, fuse как определяете sm.gif


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
shatov
сообщение Oct 16 2013, 05:17
Сообщение #4





Группа: Новичок
Сообщений: 5
Регистрация: 17-09-13
Пользователь №: 78 360



Цитата(Палыч @ Oct 15 2013, 18:30) *
Вероятно, из-за дребезга контактов по однократному нажатию кнопки переменная flagbutton принимает значение гораздо больше единицы.


Чтобы исключить дребезг, замкнул вывод int0 на землю перемычкой еще до включения, тогда на индикаторе должен был бы отображаться ход секунд (идентично зажатому состоянию кнопки), но никаких изменений это не принесло.

Цитата(Abell @ Oct 15 2013, 18:41) *
Если при симуляции все работает, зачем искать ошибку в коде? Попробуйте поискать ошибку в монтаже, о грамотной разводке земли недавно тема была. Опять же, два индикатора - это порядочный ток, как питание себя ведет? Ну и наконец - у меги 8-8 нижний предел питания 2.7в, у Вас какой?
В крайнем случае, код можно проверить по кускам, отключите прерывание и проверьте циклический вывод индикации, а потом уже двигайтесь дальше. Кстати, fuse как определяете sm.gif


На одной и той же отладочной плате проверяю две прошивки. Ту, что привел, и ту, что попроще:

#include <mega8.h>
#include <delay.h>

char sec=0;
int min=0;
int hour=0;
int day=0;
char secH=0, secL=0;
int flagbutton=0;

interrupt [EXT_INT0] void ext_int0_isr(void)
{
flagbutton=1;
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
TCNT2=0x00;
secL++;
if (secL>9) {secH++; secL=0;}
if (secH>5) {secH=0;}
if (sec>59) {min++; sec=0;}
if (min>59) {hour++; min=0;}
if (hour>23) {day++; hour=0;}
if (day>99) {day=0;}

}


void main(void)
{

PORTB=0x00;
DDRB=0x3F;
PORTD=0x04;
DDRD=0xFB;
PORTC=0x00;
DDRC=0x01;

ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

GICR|=0x40;
GIFR=0x40;

MCUCR=0xB0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;

#asm("sei")

while (1)
{
if (flagbutton==1)
{switch(secL)
{
case 0:{PORTB=~0xC0; break;}
case 1:{PORTB=~0xF9; break;}
case 2:{PORTB=~0xE4; PORTC.0=1; break;}
case 3:{PORTB=~0xF0; PORTC.0=1; break;}
case 4:{PORTB=~0xD9; PORTC.0=1; break;}
case 5:{PORTB=~0xD2; PORTC.0=1; break;}
case 6:{PORTB=~0xC2; PORTC.0=1; break;}
case 7:{PORTB=~0xF8; PORTC=0x00; break;}
case 8:{PORTB=~0xC0; PORTC.0=1; break;}
case 9:{PORTB=~0xD0; PORTC.0=1; break;}
};

switch(secH)
{
case 0:{PORTD=~0x40; break;}
case 1:{PORTD=~0x79; break;}
case 2:{PORTD=~0xA0; break;}
case 3:{PORTD=~0x30; break;}
case 4:{PORTD=~0x19; break;}
case 5:{PORTD=~0x12; break;}
case 6:{PORTD=~0x02; break;}
case 7:{PORTD=~0x78; break;}
case 8:{PORTD=~0x00; break;}
case 9:{PORTD=~0x10; break;}
};
}

flagbutton=0;
delay_ms(10);
if (flagbutton==0)
{PORTB=0x00; PORTD=0x04; PORTC.0=0x00;}

#asm("sleep");
}}

Эта работает как надо. Фьюзы в обоих случаях ставлю одинаково:


Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 16 2013, 10:27
Сообщение #5


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(shatov @ Oct 16 2013, 09:17) *
На одной и той же отладочной плате проверяю две прошивки. Ту, что привел, и ту, что попроще:

while (1)
{
if (flagbutton==1)
{switch(secL)
{
};

switch(secH)
{
};
}

flagbutton=0;
delay_ms(10);
if (flagbutton==0)
{PORTB=0x00; PORTD=0x04; PORTC.0=0x00;}

#asm("sleep");
}}

Извиняюсь спросить, а если в первом варианте, который не работает, после свичей тоже обнулять flagbutton, и тоже выдержку поставить, изменения будут? Или я просто не заметил, где обнуление впендюрено и сколько времени индикатор отрабатывает, прежде чем контроллер заснет - тогда извиняюсь laughing.gif ...


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
shatov
сообщение Oct 16 2013, 11:18
Сообщение #6





Группа: Новичок
Сообщений: 5
Регистрация: 17-09-13
Пользователь №: 78 360



Цитата(Abell @ Oct 16 2013, 01:27) *
Извиняюсь спросить, а если в первом варианте, который не работает, после свичей тоже обнулять flagbutton, и тоже выдержку поставить, изменения будут? Или я просто не заметил, где обнуление впендюрено и сколько времени индикатор отрабатывает, прежде чем контроллер заснет - тогда извиняюсь laughing.gif ...


обнуление каждые пять секунд

Проблема в строке: flagbutton++;
Но т.к. дребезг был исключен замыканием INT0 на землю, то совсем не ясно, почему нет увеличения переменной по нажатию...
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 16 2013, 11:23
Сообщение #7


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(shatov @ Oct 16 2013, 15:18) *
обнуление каждые пять секунд

Проблема в строке: flagbutton++;
Но т.к. дребезг был исключен замыканием INT0 на землю, то совсем не ясно, почему нет увеличения переменной по нажатию...

Да, уже разглядел. Ну как-то надо исключать дребезг, аппаратно или программно laughing.gif А пока, если вообще отключить прерывание и присвоить flagbutton значение 1, то контроллер запускается и на индикаторе идет отсчет 5 секунд, правильно понял?


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 16 2013, 11:31
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(shatov @ Oct 16 2013, 15:18) *
Проблема в строке: flagbutton++;

Не в самой строке, но - близко. Вы настроили прерывание по int0 на низкий уровень, и этот уровень в настоящее время постоянно присутствует - прерывания генерятся, переменная наращивается... Нажатие кнопки, как правило, фиксируют по перепаду уровня.
Go to the top of the page
 
+Quote Post
shatov
сообщение Oct 16 2013, 11:58
Сообщение #9





Группа: Новичок
Сообщений: 5
Регистрация: 17-09-13
Пользователь №: 78 360



Цитата(Abell @ Oct 16 2013, 02:23) *
Да, уже разглядел. Ну как-то надо исключать дребезг, аппаратно или программно laughing.gif А пока, если вообще отключить прерывание и присвоить flagbutton значение 1, то контроллер запускается и на индикаторе идет отсчет 5 секунд, правильно понял?


Даже если в прерывании записать flagbutton=1, то при нажатии кнопки будут отображаться 5 сек счета. Поняли правильно.

Цитата(Палыч @ Oct 16 2013, 02:31) *
Не в самой строке, но - близко. Вы настроили прерывание по int0 на низкий уровень, и этот уровень в настоящее время постоянно присутствует - прерывания генерятся, переменная наращивается... Нажатие кнопки, как правило, фиксируют по перепаду уровня.


Сделал MCUCR=0xB1, т.е. настроил на перепад, перемычку заменил кнопкой, но ничего не изменилось, индикаторы молчат.

Цитата(Палыч @ Oct 16 2013, 02:31) *
Не в самой строке, но - близко. Вы настроили прерывание по int0 на низкий уровень, и этот уровень в настоящее время постоянно присутствует - прерывания генерятся, переменная наращивается... Нажатие кнопки, как правило, фиксируют по перепаду уровня.


Но я понял, что исключив дребезг - зациклил программу. Тогда нужно как то избавляться от дребезга. Пробовал сделать задержку в прерывании (10ms), но не помогло. Что можно еще сделать? Поставить параллельно 10нФ и последовательно резистор около 300Ом?
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 16 2013, 12:02
Сообщение #10


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(shatov @ Oct 16 2013, 15:58) *
Тогда нужно как то избавляться от дребезга. Пробовал сделать задержку в прерывании (10ms), но не помогло. Что можно еще сделать? Поставить параллельно 10нФ и последовательно резистор около 300Ом?

Как вариант. Или в обработчике прерывания сразу же запрещать INT0, генерить задержку по свободному таймеру и разрешать. Прерывание, естественно, по фронту.


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 16 2013, 12:20
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(shatov @ Oct 16 2013, 15:58) *
Сделал MCUCR=0xB1, т.е. настроил на перепад

Логичнее было бы применить "The falling edge of INT0 generates an interrupt request", т.е. прерывание по спаду.

PS. Чтобы не мучать ни себя ни других людей, которые вызовутся Вам помочь, возмите себе за правило записывать значения в регистры таким образом:
Код
MCUCR= (1<<SE) | (1<<SM1) | (1<<SM0) | (1<<ISC10);
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 18 2013, 02:25
Сообщение #12


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Дребезг исключается другим образом.
Во первых не следует использовать прерывание для чтения кнопки.

Следует сделать автомат на 4 состояния и вызывать его каждые 10 миллисекунд



void state_machine()
{
static int timeout;
static int state = 0;

switch(state)
{
default:
case 0:
if(button_pressed())
{
state = 1;
timeout = 5;
}
break;


case 1:
if(--timeout == 0)
{
if(button_pressed())
{
state = 2;
/* buton was pressed call button press handler */
buton_press_action();
}
else
{
state = 0;
}
}
break;

case 2:
if(button_pressed())
{
state = 3;
timeout = 5;
}
break;

if(--timeout == 0)
{
if(button_pressed())
{
state = 2;
}
else
{
state = 0;
/* buton was released -- call button press handler */
buton_release_action();
}
}
break;
}
}
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Oct 18 2013, 03:11
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



2 Tarbal:
Где case 3: ??
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 18 2013, 04:28
Сообщение #14


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(shatov @ Oct 16 2013, 15:58) *
Даже если в прерывании записать flagbutton=1, то при нажатии кнопки будут отображаться 5 сек счета. Поняли правильно.

Сделал MCUCR=0xB1, т.е. настроил на перепад, перемычку заменил кнопкой, но ничего не изменилось, индикаторы молчат.

Но я понял, что исключив дребезг - зациклил программу. Тогда нужно как то избавляться от дребезга. Пробовал сделать задержку в прерывании (10ms), но не помогло. Что можно еще сделать? Поставить параллельно 10нФ и последовательно резистор около 300Ом?

От дребезга избавитесь потом, когда станет понятно, что только он - источник всех бед. Хорошо, если при этом станет понятно, что алгоритм работы устройства следует радикально пересмотреть. В частности, совершенно нет обработки критических ситуаций, ошибок.
Микроконтроллер за Вас додумывать не будет, ему надо четко расписать, как себя вести в разных ситуациях sm.gif Переменная flagbutton должна принимать только те значения, которые можно корректно обработать. Ну хотя бы в обработчик прерывания вставьте if, который при переполнении flugbutton будет сбрасывать в 0. В этом случае даже при сильном дребезге у Вас будет веселое перемигивание индикаторов, но оно - будет!
А уж как дребезг устранить - дело десятое, повторяю - хоть программно, хоть аппаратно.


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2013, 04:55
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Tarbal @ Oct 18 2013, 06:25) *
Во первых не следует использовать прерывание для чтения кнопки.

IMHO, вредный совет для разработки устройств с батарейным питанием.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 18 2013, 11:28
Сообщение #16


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(alexeyv @ Oct 18 2013, 07:11) *
2 Tarbal:
Где case 3: ??

Sorry

case 2:
if(button_pressed())
{
state = 3;
timeout = 5;
}
break;

case 3:
if(--timeout == 0)

Цитата(Палыч @ Oct 18 2013, 08:55) *
IMHO, вредный совет для разработки устройств с батарейным питанием.


Это почему это?
От прерывания можно просыпаться, но использовать его для обработки нажатия дребезжащей кнопки очень нехорошо. Я видел как люди боролись с нестингом, создавая ненужные сущности.
В итоге они создавали програмных монстров и франкенштейнов.

Цитата(shatov @ Oct 16 2013, 07:19) *
При симуляции всё работает, но при реализации на макетной плате ничего не выходит.


При симуляции у Вас нет дребезжащей кнопки, поэтому условие сравнивания количества нажатий с единицей проходит. В реальности количество нажатий больше единицы и сравнение с единиицей не выстреливает.

Сообщение отредактировал Tarbal - Oct 18 2013, 11:24
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2013, 12:45
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Tarbal @ Oct 18 2013, 15:28) *
Это почему это?
От прерывания можно просыпаться, но использовать его для обработки нажатия дребезжащей кнопки очень нехорошо.

Чтобы не "создавать ненужные сущности".
Я понимаю, что кому то нравиться поллинг, кому то прерывания... Но, коль в данном случае мы вынуждены пользоваться прерыванием, то накладывать на него ещё и поллинг - это и есть "ненужные сущности". Методы борьбы с дребезгом кнопки, подключенной к линии генерации прерывания int0 - банальны: аккуратно запретить прерывание от int0 на время несколько бОльшее, чем время дребезга.

to TC
Прошу прощения, выше я Вам дал "вредный" совет - использовать прерывание по спаду для фиксации факта нажатия на кнопку. Дело в том, что выход из "Idle mode" возможен только по уровню, но никак не по перепаду...
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 18 2013, 14:03
Сообщение #18


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(Палыч @ Oct 18 2013, 16:45) *
Чтобы не "создавать ненужные сущности".
Я понимаю, что кому то нравиться поллинг, кому то прерывания... Но, коль в данном случае мы вынуждены пользоваться прерыванием, то накладывать на него ещё и поллинг - это и есть "ненужные сущности". Методы борьбы с дребезгом кнопки, подключенной к линии генерации прерывания int0 - банальны: аккуратно запретить прерывание от int0 на время несколько бОльшее, чем время дребезга.

to TC
Прошу прощения, выше я Вам дал "вредный" совет - использовать прерывание по спаду для фиксации факта нажатия на кнопку. Дело в том, что выход из "Idle mode" возможен только по уровню, но никак не по перепаду...


Мне не нравится ни поллинг ни прерывания. Я применяю то, что больше подходит.
Мое решение выверено временем я применял его в устройствах, которые больше 15 лет уже работают причем в больших количествах. Кстати и свидетелем неуемной борьбы с нестингом прерываний дребезжащего контакта я тоже был. Пока я не переделал на поллинг проблемы не кончались. Манипуляция с запретом прерываний на время это беда.


Палыч, а хотите я расскажу вам про приоритеты прерываний то, что я знаю давно, а вы не знаете.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2013, 16:45
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Tarbal @ Oct 18 2013, 18:03) *
Я применяю то, что больше подходит.
И, это - правильно. Полностью с Вами согласен.
Цитата(Tarbal @ Oct 18 2013, 18:03) *
Манипуляция с запретом прерываний на время это беда.
Возможно, вы недопоняли... Речь шла не о полном (глобальном) запрете прерываний, а о врЕменном запрете только прерывания INT0,
Цитата(Tarbal @ Oct 18 2013, 18:03) *
Палыч, а хотите я расскажу вам про приоритеты прерываний то, что я знаю давно, а вы не знаете.
Если Вы знаете что-то такое о прерываниях в AVR, что не отражено в документации производителя, то - расскажите. Эта информация, вероятно, будет полезна многим. Наверное, уместнее будет это сделать в специально созданной для этого теме.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 18 2013, 18:04
Сообщение #20


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(Палыч @ Oct 18 2013, 20:45) *
И, это - правильно. Полностью с Вами согласен.
Возможно, вы недопоняли... Речь шла не о полном (глобальном) запрете прерываний, а о врЕменном запрете только прерывания INT0,

Проходили это. Не нашли хорошего решения.


Цитата(Палыч @ Oct 18 2013, 20:45) *
Если Вы знаете что-то такое о прерываниях в AVR, что не отражено в документации производителя, то - расскажите. Эта информация, вероятно, будет полезна многим. Наверное, уместнее будет это сделать в специально созданной для этого теме.

Да я просто выпендриться захотел сгоряча. Однако есть один тонкий момент с пониманием приоритета прерывания, о котором мало кто думает. Знать может и знают, но не осознают.
Дело в том, что в мелких микропроцессорах если обрабатывается прерывание, другое прерывание вызвать обработчик не сможет. Однако есть такое понятие как приоритет прерываний. Что оно означает? Оно означает в каком порядке будут вызываться прерывания, которые ждали обработки, пока либо обрабатывалось прерывание, либо прерывания были запрещены.
Однако в более мощных процессорах есть приоритет прерывания, означающий, что прерывание может прервать обработчик низкоприоритетного прерывания. Таким образом есть два различных понятия, которые называются одинаково.

Сообщение отредактировал Tarbal - Oct 18 2013, 18:08
Go to the top of the page
 
+Quote Post
shatov
сообщение Oct 18 2013, 19:10
Сообщение #21





Группа: Новичок
Сообщений: 5
Регистрация: 17-09-13
Пользователь №: 78 360



Решил переделать программно, поставив вторую кнопку на INT1. Всё заработало.

#include <mega8.h>
#include <delay.h>

char sec=0;
int min=0;
int hour=0;
char secH=0, secL=0;
int flagbutton0=0, flagbutton1=1;
char dayH=0, dayL=0;

void(* resetFunc) (void) = 0; // Reset MC function

interrupt [EXT_INT0] void ext_int0_isr(void)
{
flagbutton0=1;
flagbutton1=0;
if (PIND.2==0&&PIND.3==0) {resetFunc();}
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{
flagbutton1=1;
flagbutton0=0;
if (PIND.2==0&&PIND.3==0) {resetFunc();}
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
secL++;
if (secL>9) {secH++; secL=0; flagbutton0=0; flagbutton1=0;}
if (secH>5) {secH=0;}
if (sec>59) {min++; sec=0;}
if (min>59) {hour++; min=0;}
if (hour>23) {dayL++; hour=0;}
if (dayL>9) {dayH++; dayL=0;}
if (dayH>9) {dayH=0;}
}




void main(void)
{

PORTB=0x20;
DDRB=0x1F;
PORTD=0x0C;
DDRD=0xF3;
PORTC=0x00;
DDRC=0xFF;

ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

GICR|=0xC0;
MCUCR=0xB1;
GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x40;

#asm("sei");

while (1)
{while (flagbutton0==1)
{
switch(secL)
{
case 0:{PORTD=~0x40; PORTB.1=1; break;}
case 1:{PORTD=~0x71; PORTB.1=0; break;}
case 2:{PORTD=~0xA0; PORTB.1=1; break;}
case 3:{PORTD=~0x30; PORTB.1=1; break;}
case 4:{PORTD=~0x11; PORTB.1=0; break;}
case 5:{PORTD=~0x12; PORTB.1=1; break;}
case 6:{PORTD=~0x02; PORTB.1=1; break;}
case 7:{PORTD=~0x70; PORTB.1=0; break;}
case 8:{PORTD=~0x00; PORTB.1=1; break;}
case 9:{PORTD=~0x10; PORTB.1=1; break;}
};
}
while (flagbutton1==1)
{ switch(secH)
{
case 0:{PORTD=~0x40; PORTB.1=1; break;}
case 1:{PORTD=~0x71; PORTB.1=0; break;}
case 2:{PORTD=~0xA0; PORTB.1=1; break;}
case 3:{PORTD=~0x30; PORTB.1=1; break;}
case 4:{PORTD=~0x11; PORTB.1=0; break;}
case 5:{PORTD=~0x12; PORTB.1=1; break;}
case 6:{PORTD=~0x02; PORTB.1=1; break;}
case 7:{PORTD=~0x70; PORTB.1=0; break;}
case 8:{PORTD=~0x00; PORTB.1=1; break;}
case 9:{PORTD=~0x10; PORTB.1=1; break;}
};
}

PORTD=0x0C; PORTC=0x00; PORTB.0=0; PORTB.1=0;
#asm("sleep");
}
}

Спасибо всем за советы, многое для себя почерпнул.

P.S. Не хотел бы, чтобы моё сообщение послужило прерыванием дискуссии между Палыч и Tarbal "О создании ненужных сущностей"

в конце немного укоротил программу, т.к. для проверки работоспособности проще выводить ход секунд, чтобы не ждать, и убрал один индикатор, но суть осталась та же
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 18 2013, 20:03
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Tarbal @ Oct 18 2013, 22:04) *
...есть два различных понятия, которые называются одинаково.

Это Вы - погорячились. Приоритет - он, как говорится "и в Африке - приоритет". А, вот - реализация механизма прерываний в разных контроллерах/процессорах, действительно - разная... И хотя при описании работы этих разных механизмов используется термин "приоритет", однако его значение (а, термин "приоритет" означает: "старшинство", "важность", "первенство") не меняется.

Цитата(Tarbal @ Oct 18 2013, 22:04) *
Не нашли хорошего решения.
Это - не значит, что его не существует.
Так уж сложилось, что в проектируемых мной устройствах кнопок, обычно, - "воз и маленькая тележка". Из-за необходимости экономить дефицитные ноги МК, они (кнопки) собираются в матрицу. Наилучшее решение в этом случае - применить поллинг для определения изменения их состояния. В тех немногочисленных устройствах, где кнопок немного и есть возможность "посадить" каждую из них на "свою" ногу МК поллинг используется уже "по-привычке", как хорошо отработанный приём работы с кнопками... Однако, было и устройство, где необходимо было довольно точно определять момент нажатия на кнопку (точнее - это был концевик движения суппорта). Кнопка (концевик) была "посажена" на линию прерывания, ну, а устранение дребезга описал выше Abell:
Цитата
в обработчике прерывания сразу же запрещать INT0, генерить задержку по свободному таймеру и разрешать
Единственное, что можно было бы добавить к этому описанию антидребезга: после запрета прерывания INT0 - сбросить флаг INTF0, который мог быть взведен внешним сигналом за интервал времени, прошедший между автоматической очисткой этого флага при входе в прерывание и моментом времени запрета прерывания.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 18 2013, 20:52
Сообщение #23


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(shatov @ Oct 18 2013, 23:10) *
P.S. Не хотел бы, чтобы моё сообщение послужило прерыванием дискуссии между Палыч и Tarbal "О создании ненужных сущностей"


sm.gif Я дискуссию закончил.
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 19 2013, 05:37
Сообщение #24


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(shatov @ Oct 18 2013, 23:10) *
Решил переделать программно, поставив вторую кнопку на INT1. Всё заработало.

interrupt [EXT_INT0] void ext_int0_isr(void)
{
flagbutton0=1;
flagbutton1=0;
if (PIND.2==0&&PIND.3==0) {resetFunc();}
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{
flagbutton1=1;
flagbutton0=0;
if (PIND.2==0&&PIND.3==0) {resetFunc();}
}

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
secL++;
if (secL>9) {secH++; secL=0; flagbutton0=0; flagbutton1=0;}
if (secH>5) {secH=0;}
if (sec>59) {min++; sec=0;}
if (min>59) {hour++; min=0;}
if (hour>23) {dayL++; hour=0;}
if (dayL>9) {dayH++; dayL=0;}
if (dayH>9) {dayH=0;}
}

Вот это правильно sm.gif только зачем две переменных завели, когда достаточно одной?

interrupt [EXT_INT0] void ext_int0_isr(void)
{
flagbutton=1;
if (PIND.2==0&&PIND.3==0) {resetFunc();}
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{
flagbutton=2;
if (PIND.2==0&&PIND.3==0) {resetFunc();}
}

а в обработчике по таймеру после вывода индикации сбрасываете в 0, и все laughing.gif


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 19 2013, 06:53
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Abell @ Oct 19 2013, 09:37) *
Вот это правильно

Гм-м-м.... Правильно? Ужасно! Лучше бы уж тогда ТС внял советам Tarbal и использовал бы прерывание для выхода из Idle, а состояние кнопки определял поллингом... ТС не привел текст программы к удобоваримому виду, лазить по DS и переводить константы - лень, то - "наглазок":
1. Вторая кнопка введена в устройство только лишь для того, чтобы исправить пробелы в программировании ТС. Функциональной необходимости в ней нет.
2. Кнопка, подключенная на int0, не выведет МК из спячки, поскольку прерывание настроено на перепад сигнала из высокого уровня в низкий.
3. Прерывания на int1, настроены на низкий уровень сигнала, поэтому при нажатии и удержании в нажатом состоянии подключенной к int1 кнопки будут формироваться множественные прерывания по int1. Фактически при выходе из прерывания МК снова войдет в процедуру прерывания по int1.
4. Вызов resetFunc() переведёт МК в состояние близкое к состоянию "по включению питания", при этом обнулятся переменные, ради подсчета которых и затевалась разработка устройства. Это - такая задумка: сбросить показания счетчика при нажатии двух кнопок? Тогда, возможно, смысл во второй кнопке есть...
5. Перевод устройства в "исходное" состояние (когда оба флага равны нулю) производится таймером при переходе единиц секунд через ноль (т.е. когда secL>9). Поскольку нажатие на кнопку производится в случайный момент времени, то время до перехода в "исходное" будет варьироваться от 9 до 1 сек.
6. Переход в спящий режим осуществляется в конце каждого цикла main loop. Поэтому индикация будет осуществляться исключительно потому, что непрерывно происходят прерывания по int1, которые из спящего режима МК выводят (см. п.3)
7. ...пожалуй, приведённого выше - достаточно...
Go to the top of the page
 
+Quote Post
ae_
сообщение Oct 19 2013, 07:01
Сообщение #26


Участник
***

Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695



Цитата(shatov @ Oct 19 2013, 04:10) *
...
char sec=0;
...
char secH=0, secL=0;
...
secL++;
if (secL>9) {secH++; secL=0; flagbutton0=0; flagbutton1=0;}
if (secH>5) {secH=0;}
if (sec>59) {min++; sec=0;}
...

У Вас объявлены sec,secL,secH, но sec нигде далее в программе не изменяется, значит и проверка "if (sec>59) {min++; sec=0;}" никогда не выполнится.
secL,secH - будут крутиться, а минуты, часы и дни - не будут.
Go to the top of the page
 
+Quote Post
smk
сообщение Oct 19 2013, 07:25
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Вот такую строчку допишите: #include <avr/interrupt.h>
А Вы наверно в кодевижине... тогда не надо.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 19 2013, 08:40
Сообщение #28


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(Палыч @ Oct 19 2013, 10:53) *
Гм-м-м.... Правильно? Ужасно! Лучше бы уж тогда ТС внял советам Tarbal и использовал бы прерывание для выхода из Idle, а состояние кнопки определял поллингом...
1. Вторая кнопка введена в устройство только лишь для того, чтобы исправить пробелы в программировании ТС. Функциональной необходимости в ней нет.
2. Кнопка, подключенная на int0, не выведет МК из спячки, поскольку прерывание настроено на перепад сигнала из высокого уровня в низкий.
3. Прерывания на int1, настроены на низкий уровень сигнала, поэтому при нажатии и удержании в нажатом состоянии подключенной к int1 кнопки будут формироваться множественные прерывания по int1. Фактически при выходе из прерывания МК снова войдет в процедуру прерывания по int1.
4. Вызов resetFunc() переведёт МК в состояние близкое к состоянию "по включению питания", при этом обнулятся переменные, ради подсчета которых и затевалась разработка устройства. Это - такая задумка: сбросить показания счетчика при нажатии двух кнопок? Тогда, возможно, смысл во второй кнопке есть...
5. Перевод устройства в "исходное" состояние (когда оба флага равны нулю) производится таймером при переходе единиц секунд через ноль (т.е. когда secL>9). Поскольку нажатие на кнопку производится в случайный момент времени, то время до перехода в "исходное" будет варьироваться от 9 до 1 сек.
6. Переход в спящий режим осуществляется в конце каждого цикла main loop. Поэтому индикация будет осуществляться исключительно потому, что непрерывно происходят прерывания по int1, которые из спящего режима МК выводят (см. п.3)
7. ...пожалуй, приведённого выше - достаточно...

ТС скорее всего только начинает свой трудный путь в освоении микроконтроллеров sm.gif Поэтому, как мне кажется, применить две кнопки - правильное направление, это и имел в виду. Если есть свободные порты - почему бы не использовать? Тем более, применением поллинга полностью гарантировать отсутствие дребезга не удастся, ведь в какой-то момент опроса там может быть и 0 sm.gif В конечном итоге автор сам придет к правильным выводам.
Применить два флага, когда достаточно одного - вот это неправильно, но опять-таки, это проблемы автора.
Насчет корявости кода - полностью согласен, это беда всех начинающих, постепенно с опытом проходит. Если он будет нарабатываться, этот опыт. Ну мы же не будем писать для автора темы программу, за бесплатно, верно? sm.gif
Пока же, как мне кажется, автор слабо представляет себе, как должно работать устройство и как объяснить это микроконтроллеру на понятном ему языке, ну это пройдет.
Вообще, последнее время все чаще приходится сталкиваться с самодельными разработками, клиенты воют - просят переделать, такого насмотришься, что и этот мелкий проект вполне достойно смотрится laughing.gif Еще один прикол сам не видел, но рассказывали, что кое-кто для AVR на бейсике пишет, вот это был шок, да...


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 19 2013, 09:09
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Abell @ Oct 19 2013, 12:40) *
применением поллинга полностью гарантировать отсутствие дребезга не удастся, ведь в какой-то момент опроса там может быть и 0
При программном антидребезге что при использовании прерываний, что при использовании поллинга метод отсечения дребезга одинаков - после фиксации изменения состояния на линии ввода на некоторое время прекратить анализ состояния. При использовании прерываний этот анализ выполняет аппаратура, при поллинге - программа.


Цитата(Abell @ Oct 19 2013, 12:40) *
ТС скорее всего только начинает свой трудный путь в освоении микроконтроллеров
Ага, очень похоже на лаб работу по дисциплине "Микропроцессорная техника" biggrin.gif
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 20 2013, 15:57
Сообщение #30


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Я многие годы делаю так:

1. Настраиваю таймер вызывать обработчик прерывания раз в 10 мС
2. при входе делаю только rt_cnt++;
3. вечный цикл:

santi_seconds = 100;
while(1)
{
while(rt_cnt==0)
{}
rt_cnt--;
//Here do each 10 ms action

if(--santi_seconds==0)
{
//Here do each second action
santi_seconds = 100;
if(++seconds==60)
{
seconds = 0;
if(++minutes==60)
{
minutes = 0;
//Here do each hour action

}
//Here do each minute action
}

}

}

Возможны опечатки. Сходу написал.

Сообщение отредактировал Tarbal - Oct 20 2013, 16:51
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 21 2013, 12:50
Сообщение #31


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(Tarbal @ Oct 20 2013, 19:57) *
Я многие годы делаю так:

1. Настраиваю таймер вызывать обработчик прерывания раз в 10 мС
2. при входе делаю только rt_cnt++;
3. вечный цикл:

santi_seconds = 100;
while(1)
{
while(rt_cnt==0)
{}
rt_cnt--;
//Here do each 10 ms action

if(--santi_seconds==0)
{
//Here do each second action
santi_seconds = 100;
if(++seconds==60)
{
seconds = 0;
if(++minutes==60)
{
minutes = 0;
//Here do each hour action

}
//Here do each minute action
}

}

}

Возможны опечатки. Сходу написал.

Ему спать хочется, а по внешнему прерыванию просыпаться sm.gif Контроллеру, имею ввиду. А, извиняюсь спросить, английский для Вас родной?


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Oct 21 2013, 14:33
Сообщение #32


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

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



Во ,разведка вопрос задал wacko.gif Тут только носители языка


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

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 21 2013, 16:21
Сообщение #33


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(Abell @ Oct 21 2013, 16:50) *
Ему спать хочется, а по внешнему прерыванию просыпаться sm.gif Контроллеру, имею ввиду. А, извиняюсь спросить, английский для Вас родной?


А как вы за временем следите?
Русский родной, но на клавиатуре нет русских букв.

Сообщение отредактировал Tarbal - Oct 21 2013, 16:23
Go to the top of the page
 
+Quote Post
Abell
сообщение Oct 21 2013, 16:56
Сообщение #34


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Цитата(Tarbal @ Oct 21 2013, 20:21) *
А как вы за временем следите?

А я и не слежу laughing.gif Автор темы следит sm.gif


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 21 2013, 16:57
Сообщение #35


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(Abell @ Oct 21 2013, 20:56) *
А я и не слежу laughing.gif Автор темы следит sm.gif


Очень смешно. А как одновременно спать и за временем следить?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Oct 21 2013, 18:54
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Tarbal @ Oct 21 2013, 20:57) *
А как одновременно спать и за временем следить?

Замечание было о том, что "просыпаться" 100 раз в секунду энергетически более расточительно, чем 1 раз в секунду, как это сделано у ТС. Кроме того, Ваш фрагмент кода не содержит инструкций (или намёка на место, куда их вставить) перевода МК в Sleep.
Go to the top of the page
 
+Quote Post
Tarbal
сообщение Oct 21 2013, 19:07
Сообщение #37


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

Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439



Цитата(Палыч @ Oct 21 2013, 22:54) *
Замечание было о том, что "просыпаться" 100 раз в секунду энергетически более расточительно, чем 1 раз в секунду, как это сделано у ТС. Кроме того, Ваш фрагмент кода не содержит инструкций (или намёка на место, куда их вставить) перевода МК в Sleep.


Я пример привел, как делать, а детали каждый сам выберет. Но весельчак Abell ни о каком пробуждении ежесекундном не говорит. Tолько о кнопке.
Это концепция измерения времени. Инструкцию sleep в конце вечного цикла последней командой.
Go to the top of the page
 
+Quote Post

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

 


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


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