|
Какой-то бред..., ...с прерыванием по таймеру |
|
|
|
Jan 2 2008, 10:34
|
Участник

Группа: Новичок
Сообщений: 19
Регистрация: 29-12-07
Пользователь №: 33 732

|
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 секунд (определяю по взмаргиванию линии на осциллографе). И что это за бред...? Где моя ошибка?
Сообщение отредактировал HCHUNTER - Jan 2 2008, 10:37
|
|
|
|
|
Jan 2 2008, 10:49
|
Участник

Группа: Новичок
Сообщений: 19
Регистрация: 29-12-07
Пользователь №: 33 732

|
Работаю от кварца, это совершенно точно. Я такую простенькую программку написал уже от безысходности, чтобы выяснить где же я дурак...
Раньше с таймерами не работал, факт. А почему Вы пишете 8e6/1024/256 - 30 Гц ? отуда 256? Мастер мне пишет, что частота настроенная составляет 15625 Гц.
|
|
|
|
|
Jan 2 2008, 11:16
|
Участник

Группа: Новичок
Сообщений: 19
Регистрация: 29-12-07
Пользователь №: 33 732

|
а как же мне тогда правильно таймер проинициализировать? Получается TCCR0=0x05; TCNT0=0xFF;
так?
|
|
|
|
|
Jan 2 2008, 11:37
|
Участник

Группа: Новичок
Сообщений: 19
Регистрация: 29-12-07
Пользователь №: 33 732

|
Вобщем, сделал как сам же написал выше TCCR0=0x05; TCNT0=0xFF; вроде бы все заработало... щас буду думать дальше...
|
|
|
|
|
Jan 2 2008, 11:49
|
Участник

Группа: Новичок
Сообщений: 19
Регистрация: 29-12-07
Пользователь №: 33 732

|
Да, конечно. В самой процедуре прерывания я тоже поправляю счетчик таймера.
В любом случае, огромное спасибо за наводку на мою ошибку! Пойду, попробую "прикрутить" полученное под свою конкретную задачу...
|
|
|
|
Guest_=AVR=_*
|
Jan 2 2008, 19:44
|
Guests

|
Эээ... это по какому такому АНСИ СИ порты "и так обнуляются", интересно узнать?
Сообщение отредактировал =AVR= - Jan 2 2008, 19:45
|
|
|
|
|
Jan 2 2008, 20:03
|

Местный
  
Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317

|
Лучше инвертировать по прерыванию таймера ножку порта, то есть: Код interrupt [TIM0_OVF] void timer0_ovf_isr(void) { // Инвертировать быстрее xor`ом. Но т.к. я не знаю // специфики CV, то написал так: PORTB.0 = (PORTB.0 == 0 ? 1 : 0); // Инвертируем ножку } При этом не забудьте убрать цикл "while (1)" из мейна. Хочу заметить, что всякие задержки в прерываниях (наподобее delay_us) крайне не рекоммендуются, прерывание - это критическая часть кода, из которого следует выходить как можно скорее. =AVR=`у Цитата(INT1 @ Jan 2 2008, 22:34)  они [порты] по Атмелю и АНСИ СИ и так обнуляются
|
|
|
|
|
Jan 2 2008, 20:36
|
Участник

Группа: Новичок
Сообщений: 19
Регистрация: 29-12-07
Пользователь №: 33 732

|
Цитата(Aesthete Animus @ Jan 2 2008, 23:03)  При этом не забудьте убрать цикл "while (1)" из мейна. А это для чего? что оно мне даст? куда же я тогда возвращаться-то буду... в "никуда" получается... Цитата Хочу заметить, что всякие задержки в прерываниях (наподобее delay_us) крайне не рекоммендуются, прерывание - это критическая часть кода, из которого следует выходить как можно скорее. Вот это мне тоже, кстати, не совсем понятно... Звучит как заученная фраза из книжек. А если мне нужно по возникновении прерывания выполнить массу всего? Что мне тогда делать...? Ведь мне никто не запрещает в прерывании остановить таймер, выполнить все что мне нужно, а по выходу из прерывания снова его запустить? С моей (ламерской) точки зрения процедура-обработчик может быть сколь угодно долгой. Главное, чтобы в это время я не наловил новых прерываний...
Сообщение отредактировал HCHUNTER - Jan 2 2008, 20:40
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|