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

 
 
> Таймер на 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
 
Start new topic
Ответов
Палыч
сообщение 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
shatov
сообщение Oct 16 2013, 05:17
Сообщение #3





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


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

Группа: Участник
Сообщений: 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
Сообщение #5





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


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

Группа: Участник
Сообщений: 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
shatov
сообщение Oct 16 2013, 11:58
Сообщение #7





Группа: Новичок
Сообщений: 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 18 2013, 04:28
Сообщение #8


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

Группа: Участник
Сообщений: 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

Сообщений в этой теме
- shatov   Таймер на Atmega8   Oct 16 2013, 03:19
||- - Abell   Цитата(shatov @ Oct 16 2013, 15:58) Тогда...   Oct 16 2013, 12:02
||- - Палыч   Цитата(shatov @ Oct 16 2013, 15:58) Сдела...   Oct 16 2013, 12:20
|- - Палыч   Цитата(shatov @ Oct 16 2013, 15:18) Пробл...   Oct 16 2013, 11:31
- - Abell   Цитата(shatov @ Oct 16 2013, 07:19) ... п...   Oct 16 2013, 04:41
- - Tarbal   Дребезг исключается другим образом. Во первых не с...   Oct 18 2013, 02:25
|- - Палыч   Цитата(Tarbal @ Oct 18 2013, 06:25) Во пе...   Oct 18 2013, 04:55
- - alexeyv   2 Tarbal: Где case 3: ??   Oct 18 2013, 03:11
|- - Tarbal   Цитата(alexeyv @ Oct 18 2013, 07:11) 2 Ta...   Oct 18 2013, 11:28
|- - Палыч   Цитата(Tarbal @ Oct 18 2013, 15:28) Это п...   Oct 18 2013, 12:45
|- - Tarbal   Цитата(Палыч @ Oct 18 2013, 16:45) Чтобы ...   Oct 18 2013, 14:03
|- - Палыч   Цитата(Tarbal @ Oct 18 2013, 18:03) Я при...   Oct 18 2013, 16:45
|- - Tarbal   Цитата(Палыч @ Oct 18 2013, 20:45) И, это...   Oct 18 2013, 18:04
|- - Палыч   Цитата(Tarbal @ Oct 18 2013, 22:04) ...ес...   Oct 18 2013, 20:03
- - shatov   Решил переделать программно, поставив вторую кнопк...   Oct 18 2013, 19:10
|- - Tarbal   Цитата(shatov @ Oct 18 2013, 23:10) P.S. ...   Oct 18 2013, 20:52
|- - Abell   Цитата(shatov @ Oct 18 2013, 23:10) Решил...   Oct 19 2013, 05:37
||- - Палыч   Цитата(Abell @ Oct 19 2013, 09:37) Вот эт...   Oct 19 2013, 06:53
||- - Abell   Цитата(Палыч @ Oct 19 2013, 10:53) Гм-м-м...   Oct 19 2013, 08:40
||- - Палыч   Цитата(Abell @ Oct 19 2013, 12:40) примен...   Oct 19 2013, 09:09
||- - Tarbal   Я многие годы делаю так: 1. Настраиваю таймер выз...   Oct 20 2013, 15:57
||- - Abell   Цитата(Tarbal @ Oct 20 2013, 19:57) Я мно...   Oct 21 2013, 12:50
||- - Tarbal   Цитата(Abell @ Oct 21 2013, 16:50) Ему сп...   Oct 21 2013, 16:21
||- - Abell   Цитата(Tarbal @ Oct 21 2013, 20:21) А как...   Oct 21 2013, 16:56
||- - Tarbal   Цитата(Abell @ Oct 21 2013, 20:56) А я и ...   Oct 21 2013, 16:57
||- - Палыч   Цитата(Tarbal @ Oct 21 2013, 20:57) А как...   Oct 21 2013, 18:54
||- - Tarbal   Цитата(Палыч @ Oct 21 2013, 22:54) Замеча...   Oct 21 2013, 19:07
|- - ae_   Цитата(shatov @ Oct 19 2013, 04:10) ... c...   Oct 19 2013, 07:01
- - smk   Вот такую строчку допишите: #include <avr/inter...   Oct 19 2013, 07:25
- - ILYAUL   Во ,разведка вопрос задал Тут только носители язы...   Oct 21 2013, 14:33


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

 


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


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