hc2hunter 0 2 января, 2008 Опубликовано 2 января, 2008 (изменено) · Жалоба AVR Mega8, 16МГц, среда разработки CVAVR v1.25. Делаю все по шаблону, как предлагает мастер. Пытаюсь создать прерывание по таймеру №0 каждые 64 мкс (15625 Гц). Вот текст программы: #include <mega8.h> #include <delay.h> interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0x00; // сбросить счетчик таймера PORTB.0=0; // выставить на ножке "0" на период ~3...4 мкс delay_us (3); } void main(void) { PORTB=0x00; DDRB=0xFF; PORTC=0x00; DDRC=0x7F; PORTD=0x00; DDRD=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 15,625 kHz TCCR0=0x05; TCNT0=0x00; // Timer/Counter 1 initialization TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01; // Analog Comparator initialization ACSR=0x80; SFIOR=0x00; #asm("sei") while (1) { PORTB.0=1; //на ножке постоянная "1", прерывать ее каждые 64 мкс }; } Результат смотрю на осциллографе - хрен два! Постоянная единица, ничего не прерывается. Пробовал и так и эдак... И что я только не писал в обработчик прерывания - ничего не помогает. И запрещать прерывания там пробовал, и заново таймер реинициализировал... Разве что проскакивает этот самый ожидаемый "0" каждые примерно 5 секунд (определяю по взмаргиванию линии на осциллографе). И что это за бред...? :cranky: Где моя ошибка? Изменено 2 января, 2008 пользователем HCHUNTER Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Откуда 64 мкс насчитали ? 8e6/1024/256 - 30 Гц. У вас фуз работы от кварца прошит ? Или от внутренного RC по умолчанию работаете ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hc2hunter 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Работаю от кварца, это совершенно точно. Я такую простенькую программку написал уже от безысходности, чтобы выяснить где же я дурак... Раньше с таймерами не работал, факт. А почему Вы пишете 8e6/1024/256 - 30 Гц ? отуда 256? Мастер мне пишет, что частота настроенная составляет 15625 Гц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба там таймер0 - 8 битный, перполнение будет когда 255 превысит и сбросит в ноль, вот и 256 берется. 1024 - prescaler у Вас. Кстати delay - я так понял библиотечная ? Я бы свою, попроще поставил вначале. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hc2hunter 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба а как же мне тогда правильно таймер проинициализировать? Получается TCCR0=0x05; TCNT0=0xFF; так? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба нет, или надо тогда переписывать TCNT0 не нулем в прерывании а 256 - N , где N - коэфф деления или воспользваться чем-нибудь более продвинутым, типа Compare в 1-ом таймере. 256 - N - тут могу путать немного, не силен в арифметике и голова плохо варит. Кстати TCNT0=0x00; // сбросить счетчик таймера - это Вы написали или мастер ? Предделитель тоже 1024 великоват, 8e6/1024 = 7812.5 Гц. Попробуйте TCCR0 = 4 (делитель на 256), а в прерывании писать TCNT0 = 254. И уберите библиотечную задержку - и без нее нормальным осциллом все увидите Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hc2hunter 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Вобщем, сделал как сам же написал выше TCCR0=0x05; TCNT0=0xFF; вроде бы все заработало... щас буду думать дальше... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба А ну да, у Вас же 16 Мгц, а не 8, что-то зациклился. Тогда правильно, только где Вы выше написали про = 0xFF ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hc2hunter 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Да, конечно. В самой процедуре прерывания я тоже поправляю счетчик таймера. В любом случае, огромное спасибо за наводку на мою ошибку! Пойду, попробую "прикрутить" полученное под свою конкретную задачу... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
INT1 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Кстати, писать столько нулей в инициализации портов и глобальных переменных, вроде как и смысла нет, они по Атмелю и АНСИ СИ и так обнуляются Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость =AVR= 2 января, 2008 Опубликовано 2 января, 2008 (изменено) · Жалоба Эээ... это по какому такому АНСИ СИ порты "и так обнуляются", интересно узнать? Изменено 2 января, 2008 пользователем =AVR= Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aesthete Animus 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Лучше инвертировать по прерыванию таймера ножку порта, то есть: interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Инвертировать быстрее xor`ом. Но т.к. я не знаю // специфики CV, то написал так: PORTB.0 = (PORTB.0 == 0 ? 1 : 0); // Инвертируем ножку } При этом не забудьте убрать цикл "while (1)" из мейна. Хочу заметить, что всякие задержки в прерываниях (наподобее delay_us) крайне не рекоммендуются, прерывание - это критическая часть кода, из которого следует выходить как можно скорее. =AVR=`у они [порты] по Атмелю и АНСИ СИ и так обнуляются ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Эээ... это по какому такому АНСИ СИ порты "и так обнуляются", интересно узнать? Для тех, кто читает не всё: порты - по Atmel (default value); глобальные переменные - по АНСИ СИ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hc2hunter 0 2 января, 2008 Опубликовано 2 января, 2008 (изменено) · Жалоба При этом не забудьте убрать цикл "while (1)" из мейна. А это для чего? что оно мне даст? куда же я тогда возвращаться-то буду... в "никуда" получается... Хочу заметить, что всякие задержки в прерываниях (наподобее delay_us) крайне не рекоммендуются, прерывание - это критическая часть кода, из которого следует выходить как можно скорее. Вот это мне тоже, кстати, не совсем понятно... Звучит как заученная фраза из книжек. А если мне нужно по возникновении прерывания выполнить массу всего? Что мне тогда делать...? Ведь мне никто не запрещает в прерывании остановить таймер, выполнить все что мне нужно, а по выходу из прерывания снова его запустить? С моей (ламерской) точки зрения процедура-обработчик может быть сколь угодно долгой. Главное, чтобы в это время я не наловил новых прерываний... Изменено 2 января, 2008 пользователем HCHUNTER Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 2 января, 2008 Опубликовано 2 января, 2008 · Жалоба Вот это мне тоже, кстати, не совсем понятно... Звучит как заученная фраза из книжек. А если мне нужно по возникновении прерывания выполнить массу всего? Что мне тогда делать...? Мне кажется что в учебниках как раз про это не слова. Как правило это из опыта. Но тем не менее возможен и такой способ работы (как вы описали). Если у вас одно прерывание. Можно и с несколькими обойтись, таким же образом. Только надо чётко представлять что ты делаешь и какие проблемы могут возникнуть. Если же в рамках общепринятого, то на вопрос "А если мне нужно по возникновении прерывания выполнить массу всего?" можно ответить таким образом. Выставить в прерывании флаг а в голове определить флаг и "выполнить массу всего". В программировании любое действие можно сделать десятком способов. Выбирайте свой. Но мнение других всётаки желательно хотя бы послушать. Чтобы самому сделать свой выбор. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться