|
Таймер на Atmega8, Работает при симуляции, но не работает в железе |
|
|
|
Oct 16 2013, 03:19
|
Группа: Новичок
Сообщений: 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"); } }
|
|
|
|
|
 |
Ответов
|
Oct 18 2013, 19:10
|
Группа: Новичок
Сообщений: 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 "О создании ненужных сущностей"
в конце немного укоротил программу, т.к. для проверки работоспособности проще выводить ход секунд, чтобы не ждать, и убрал один индикатор, но суть осталась та же
|
|
|
|
|
Oct 19 2013, 05:37
|

профессиональный дилетант
   
Группа: Участник
Сообщений: 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;} } Вот это правильно  только зачем две переменных завели, когда достаточно одной? 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, и все
--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...  
|
|
|
|
|
Oct 19 2013, 06:53
|

Гуру
     
Группа: Свой
Сообщений: 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. ...пожалуй, приведённого выше - достаточно...
|
|
|
|
|
Oct 19 2013, 08:40
|

профессиональный дилетант
   
Группа: Участник
Сообщений: 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. ...пожалуй, приведённого выше - достаточно... ТС скорее всего только начинает свой трудный путь в освоении микроконтроллеров  Поэтому, как мне кажется, применить две кнопки - правильное направление, это и имел в виду. Если есть свободные порты - почему бы не использовать? Тем более, применением поллинга полностью гарантировать отсутствие дребезга не удастся, ведь в какой-то момент опроса там может быть и 0  В конечном итоге автор сам придет к правильным выводам. Применить два флага, когда достаточно одного - вот это неправильно, но опять-таки, это проблемы автора. Насчет корявости кода - полностью согласен, это беда всех начинающих, постепенно с опытом проходит. Если он будет нарабатываться, этот опыт. Ну мы же не будем писать для автора темы программу, за бесплатно, верно?  Пока же, как мне кажется, автор слабо представляет себе, как должно работать устройство и как объяснить это микроконтроллеру на понятном ему языке, ну это пройдет. Вообще, последнее время все чаще приходится сталкиваться с самодельными разработками, клиенты воют - просят переделать, такого насмотришься, что и этот мелкий проект вполне достойно смотрится  Еще один прикол сам не видел, но рассказывали, что кое-кто для AVR на бейсике пишет, вот это был шок, да...
--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...  
|
|
|
|
Сообщений в этой теме
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 Цитата(Палыч @ 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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|