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

 
 
> Таймер на 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
Ответов
shatov
сообщение Oct 18 2013, 19:10
Сообщение #2





Группа: Новичок
Сообщений: 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
Abell
сообщение Oct 19 2013, 05:37
Сообщение #3


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

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


Гуру
******

Группа: Свой
Сообщений: 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
Abell
сообщение Oct 19 2013, 08:40
Сообщение #5


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

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


Гуру
******

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

Сообщений в этой теме
- shatov   Таймер на Atmega8   Oct 16 2013, 03:19
- - Палыч   Цитата(shatov @ Oct 16 2013, 07:19) ... н...   Oct 16 2013, 04:30
|- - shatov   Цитата(Палыч @ Oct 15 2013, 18:30) Вероят...   Oct 16 2013, 05:17
|- - Abell   Цитата(shatov @ Oct 16 2013, 09:17) На од...   Oct 16 2013, 10:27
|- - shatov   Цитата(Abell @ Oct 16 2013, 01:27) Извиня...   Oct 16 2013, 11:18
|- - Abell   Цитата(shatov @ Oct 16 2013, 15:18) обнул...   Oct 16 2013, 11:23
||- - shatov   Цитата(Abell @ Oct 16 2013, 02:23) Да, уж...   Oct 16 2013, 11:58
||- - Abell   Цитата(shatov @ Oct 16 2013, 15:58) Тогда...   Oct 16 2013, 12:02
||- - Палыч   Цитата(shatov @ Oct 16 2013, 15:58) Сдела...   Oct 16 2013, 12:20
||- - Abell   Цитата(shatov @ Oct 16 2013, 15:58) Даже ...   Oct 18 2013, 04:28
|- - Палыч   Цитата(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
|- - Tarbal   Цитата(shatov @ Oct 18 2013, 23:10) P.S. ...   Oct 18 2013, 20:52
||- - 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 Текстовая версия Сейчас: 30th July 2025 - 11:15
Рейтинг@Mail.ru


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