Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: прерывание от таймера меги16
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
wert123
Подскажите в чем проблема, не наблюдаеться перехода на обработку прерывания т/с0 по совпадению, хотя TIFR флаг появляеться:
.include "m16def.inc"

rjmp reset
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
rjmp TAMER0_COMP


reset:
clr r16
ldi r16,low(RAMEND);
out spl,r16;
ldi r16,high(RAMEND);
out sph,r16;
ldi r16,255;
out DDRA,r16;
ldi r16,0;
out PORTA,r16;
;;;;конфигурирование таймера
sei
ldi r16,9
out OCR0,r16
ldi r16,2;прерыв по совпад
out TIMSK,r16
ldi r16,9;по совпадению, вн генер 1Мгц
out TCCR0,r16
;;;задержка
delay:
ldi r19,20;
delay1:
ldi r17,100;
delay2:
ldi r18,20;
delay3:
dec r18;
brne delay3;
dec r17;
brne delay2;
dec r19;
brne delay1;

TAMER0_COMP:
ldi r16,255;
out PORTA,r16;
=AVR=
Кроме этого, не наблюдаетЬся и каких-либо следов прочтения даташита и даже малейшего понимания сути работы механизма Compare, прерываний и т.д. Марш зубрить букварь!
defunct
Извините, было лениво искать ошибку в вашем коде.
Привожу пример который работает, сравните со своим кодом и найдите ошибку.

CODE

.include "m16def.inc"

.def AH = R25
.def AL = R24
.def BlinkReg = R15

.ORG 0
jmp PROG_START

.ORG 0x26
rjmp TIMER0_COMP_HANDLER


PROG_START:
// stack initialization
ldi AL, Low( RAMEND)
out SPL, AL
ldi AL, High( RAMEND )
out SPH, AL

// timer0 initialization
ldi AL, (1 << OCIE0)
out TIMSK, AL
ldi AL, 9 // your OCR value
out OCR0, AL
ldi AL, (1 << CTC0) | (1 << CS00)
out TCCR0, AL

// initialize port A as output
ldi AL, 0xFF
out DDRA, AL

// enable ints
sei



MAIN_LOOP:
rjmp MAIN_LOOP



TIMER0_COMP_HANDLER:
com BlinkReg
out PortA, BlinkReg
reti
bodja74
Цитата(wert123 @ Dec 16 2007, 19:12) *
Подскажите в чем проблема, не наблюдаеться перехода на обработку прерывания т/с0 по совпадению, хотя TIFR флаг появляеться:
.include "m16def.inc"

rjmp reset
nop


Так таблица прерваний делается только для меги8\48\88\8515\8535 и тинек ,для меги16 каждый вектор идет в четыре байта ,тоесть заместь rjmp reset идет jmp reset ,
команда nop имеет размер 2 байта и если хотите заполнить вектора nop-ами ,нужно указавать по два nop на каждый вектор.
Можно еще так smile.gif
.org 0
jmp reset
.org 0x26
jmp Compare_T0
wert123
Цитата(bodja74 @ Dec 16 2007, 23:36) *
Так таблица прерваний делается только для меги8\48\88\8515\8535 и тинек ,для меги16 каждый вектор идет в четыре байта ,тоесть заместь rjmp reset идет jmp reset ,
команда nop имеет размер 2 байта и если хотите заполнить вектора nop-ами ,нужно указавать по два nop на каждый вектор.
Можно еще так smile.gif
.org 0
jmp reset
.org 0x26
jmp Compare_T0



Чтоб не начинать новую тему, да эта и похожа, у меня такой вопрос-как организовать счет внешних событий(скажем по нажатию на кнопку 5 раз) и после этого, чтоб на какой-нибудь разряд порта выдовать 1.
Я думал (у меня мега16) можно сконфигурировать скажем т/с0 на прерыв по совпадению, в ОСR0 загнать 5, и TCCR0 на тактирование от внешнего источника, тоесть счет импульсов от нажатия кнопки РВ0 , но не получаеться, что не так?
Сергей Борщ
Цитата(wert123 @ Dec 17 2007, 12:57) *
что не так?
Если "выдовать 1" происходит раньше, чем на пятом нажатии - скорее всего дребезг контактов вызывает больше, чем один импульс на нажатие.
wert123
Цитата(Сергей Борщ @ Dec 17 2007, 15:46) *
Если "выдовать 1" происходит раньше, чем на пятом нажатии - скорее всего дребезг контактов вызывает больше, чем один импульс на нажатие.



Спасибо за выдОвать-не углядел, у меня вопрос не в этом, скорее я не правильно его сформулировал-как организовать счет внешних событий?И возможно ли, чтоб внешними собітиями біли импульсы от нажатия кнопки?


Цитата(wert123 @ Dec 17 2007, 18:24) *
Спасибо за выдОвать-не углядел, у меня вопрос не в этом, скорее я не правильно его сформулировал-как организовать счет внешних событий от нажатия кнопки-только организацией внешних прерываний?И скажите какой минимальной может быть частота внешнего сигнала для того, чтоб таймер считал эти импульсы?
Сергей Борщ
Цитата(wert123 @ Dec 17 2007, 16:49) *
как организовать счет внешних событий?И возможно ли, чтоб внешними собітиями біли импульсы от нажатия кнопки?
Можно так, как вы описали - завести на счетный вход таймера. Такой вариант хорош, если импульсы формируются каким-либо датчиком, у которого отсутствует дребезг. Для кнопки не подходит, или надо как-то давить дребезг аппаратно. Можно таймер заставить генерить прерывания с периодом 10мс и в прерывании считывать состояние ножки, к которой подключена кнопка. Любая вменяемая кнопка имеет дребезг меньше 10мс. Дальше программно считать количество нажатий. Можно завести кнопку на вход прерывания, по нажатию кнопки будет генерится прерывание, в нем увеличиваем счетчик нажатий, запрещаем это прерывание на 10 мс. Чаще всего используется второй способ.
wert123
Цитата(Сергей Борщ @ Dec 17 2007, 18:58) *
Можно так, как вы описали - завести на счетный вход таймера. Такой вариант хорош, если импульсы формируются каким-либо датчиком, у которого отсутствует дребезг. Для кнопки не подходит, или надо как-то давить дребезг аппаратно. Можно таймер заставить генерить прерывания с периодом 10мс и в прерывании считывать состояние ножки, к которой подключена кнопка. Любая вменяемая кнопка имеет дребезг меньше 10мс. Дальше программно считать количество нажатий. Можно завести кнопку на вход прерывания, по нажатию кнопки будет генерится прерывание, в нем увеличиваем счетчик нажатий, запрещаем это прерывание на 10 мс. Чаще всего используется второй способ.


Спасибо все понял, но я еще до дребезга не дошел, я проверяю только в AVR studio, и выставляю через какое то время в PINB0 "1"-симулируя нажатие кнопки, а счета почему-то не происходит в таймере0.Вот код:
.include "m16def.inc"
.org 0
jmp reset
.org 0x26
jmp TAMER0_COMP


reset:
clr r16
ldi r16,low(RAMEND);
out spl,r16;
ldi r16,high(RAMEND);
out sph,r16;
ldi r16,255;
out DDRA,r16;
ldi r16,0;
out PORTA,r16;
ldi r16,0;
out DDRB,r16;
;;;;конфигурирование таймера
sei
ldi r16,5
out OCR0,r16
ldi r16,2;прерыв по совпад
out TIMSK,r16
ldi r16,14;по совпадению, вн генер
out TCCR0,r16

;;;задержка
delay:
ldi r19,20;
delay1:
ldi r17,100;
delay2:
ldi r18,200;
delay3:
dec r18;
brne delay3;
dec r17;
brne delay2;
dec r19;
brne delay1;

TAMER0_COMP:
ldi r16,255;
out PORTA,r16;

ldi r19,20;
delay7:
ldi r17,100;
delay8:
ldi r18,20;
delay9:
dec r18;
brne delay9;
dec r17;
brne delay8;
dec r19;
brne delay7;
jmp reset
;;;;задержка
defunct
Цитата(wert123 @ Dec 17 2007, 18:22) *
Вот код:
TAMER0_COMP:
ldi r16,255;
out PORTA,r16;
...
jmp reset
;;;;задержка

А где RETI?
Из прерывания надо выходить командой RETI - которая вытаскивает из стека адрес возврата и устанавливает флаг I (тем самым разрешая прерывания). Вместо "jmp reset" поставьте reti.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.