|
winavr - помогите с прерываниями, не хотят совместно работать в простой программе |
|
|
|
Aug 10 2009, 20:20
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
делаю прогу под (tiny2313) в winavr для контроля зависания компа - комп переодически шлет импульс и если очередной не пришол вовремя то контроллер делает сброс для наколенной проверки вешаю на ногу диод и на другую кнопку - диод мигает а тыкание кнопки частое должно прерывать мигание диода пока щелкается кнопка - но получается лишь продлить период мигания диода Код int c=0;
ISR(INT0_vect){c=1;} // прерывание от кнопки
ISR(TIMER1_OVF_vect) {TCNT1=65500;if (c==1){c=0;} else {PORTB^=1<<3;}} // прерывание по таймеру - лампа гаснет или загорается
int main(void) { TIMSK=0x80; // Timer 1 Overflow Interrupt: On
TCNT1=65500; // значение счетного регистра - чтоб до переполнения было около 1 сек.
DDRB|=_BV(3);// Вывод порта настраеваем как выход (диод)
PORTD&=~_BV(PD2);// вешаем 0 на вход кнопки GIMSK=0b01000000; //разрешаем прерывание int0 - кнопка MCUCR=0x03; // int by rising front - для кнопки
sei(); // общее разрешение прерывания (sreg 0100000....)
while (1); } т.е. прерывание по кнопке срабатывает лишь 1 раз сколько бы не нажимать - после очередной сработки по таймеру опять только раз - а надо чтоб постоянно - в чем причина не пойму
|
|
|
|
|
Aug 11 2009, 07:12
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
дописал volatile int c=0; эффета нет
DDRD есть и по умолчанию там 0 - т.е. вход ( а когда писал туда 0 то почемуто не работала) кнопка на 1 замыкает - да . 0 там чтоб четче по переднему фронту отрабатывало так как без нуля там около 1В.
инициализация в основной программе это после main? тогда ругаться будет что в описании прерываний непонятки это как понимаю плата за неохоту изучать ассемблер?
|
|
|
|
|
Aug 11 2009, 10:25
|

Частый гость
 
Группа: Участник
Сообщений: 80
Регистрация: 16-07-07
Из: Беларусь, г.Гомель
Пользователь №: 29 165

|
Цитата(семен78 @ Aug 11 2009, 10:12)  DDRD есть и по умолчанию там 0 - т.е. вход В коде у вас написано, что DDRB|=_BV(3)? вы установили работу порта 3 вывод на выход, а как вы настроили 2-й вывод порта D? Код DDRB|=_BV(3);// Вывод порта настраеваем как выход (диод)
PORTD&=~_BV(PD2);// вешаем 0 на вход кнопки Разберитесь с этим вначале, где настройка DDRD(2)? Код DDRB|=_BV(3);//настроить на выход или DDRB|=~_BV(3);//настроить на вход если так нужно
--------------------
Прибор должен работать не в принципе, а в корпусе!
|
|
|
|
|
Aug 11 2009, 10:58
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
DDRD(2) - вход по умолчанию - т.е. там 0 и кста в шите написано что сработает даже по выходу (int0) - тут вопроса нет - кнопка же срабатывает
|
|
|
|
|
Aug 11 2009, 11:57
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
не понял мысли - смысл прерывания по кнопке чтоб порт оставался не тронутым я попробовал эту добавку - не помогло попробовал без переменной - просто в прерывании кнопки менять показания счетного регистра - тоже не помогло Код ISR(INT0_vect){TCNT1=65500;} ISR(TIMER1_OVF_vect){TCNT1=65500; PORTB^=1<<3;}
int main(void){ CLKPR=0x80;CLKPR=0x08;//Cryst Oscil division:256 // Timer/Counter 1 initialization TCCR1A=0x00;// Mode: Normal top=FFFFh TCCR1B=5;// Clock value: /1024 TIMSK=0x80;// Timer 1 Overflow Interrupt: On TCNT1=65500;
DDRB|=_BV(3);// Вывод порта настраеваем как выход (диод) PORTD&=~_BV(PD2);// вешаем 0 - на кнопку с + GIMSK=0b01000000; //разрешаем прерывание int1 MCUCR=0x03; // int by rising front sei(); while (1); }
|
|
|
|
|
Aug 11 2009, 13:23
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 17-09-05
Из: Москва
Пользователь №: 8 660

|
Цитата(семен78 @ Aug 11 2009, 15:57)  не понял мысли - смысл прерывания по кнопке чтоб порт оставался не тронутым Представьте, что будет, если выход уже включился, а Вы жмете кнопку. Ведь выход не сбросится, пока не выполнится прерывание таймера, то есть, нажатия кнопки будут продлевать до бесконечности как выключенное, так и включенное состояние выхода. И непонятно как у Вас 1В на входе и что там за схема. Обычно вход кнопки подтягивают резистором к питанию, а саму кнопку вешают на землю. Пусть у Вас наоборот - но все равно не должно быть 1В. По поводу инициализации. Советую Вам явно инициализировать все переменные и значения портов всех регистров, не опираясь на значения по умолчанию. Также желательно знать, что происходит между reset и входом в main. В начале программы странно писать DDRB|=0x04; Если это не первая строка в main, и там есть еще какие-то вызовы функций, через год Вам самому придется прочитать код сверху донизу, чтобы понять, что ее никто до этого не менял. Напишите в начале PORTB=0x00; DDRB=0x04; и т.д.
Сообщение отредактировал Sergey'F - Aug 11 2009, 13:25
|
|
|
|
|
Aug 11 2009, 14:09
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
то есть, нажатия кнопки будут продлевать до бесконечности как выключенное, так и включенное состояние выхода. вот именно этого я и добиваюсь
1В на входе - видимо это третье состояние такое(высоко импедансное) - формально по умолчанию 0 - а когда туда пишешь 0 то 0.15В показывает
про между ресет и main не понял
|
|
|
|
|
Aug 11 2009, 16:35
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 17-09-05
Из: Москва
Пользователь №: 8 660

|
Цитата(семен78 @ Aug 11 2009, 18:09)  1В на входе - видимо это третье состояние такое(высоко импедансное) - формально по умолчанию 0 - а когда туда пишешь 0 то 0.15В показывает Я бы не назвал это нормальной работой схемы. Советую разобраться со схемой снаружи и посмотреть схему порта. Цитата(семен78 @ Aug 11 2009, 18:09)  про между ресет и main не понял Как Вы считаете, кто делает инициализацию для объявления int c = 0, которое у Вас раньше было? Какой-то код. И если Вы хотите написать надежную программу, надо знать, какой код и как исполняется между адресом сброса и Вашим C-шным main. Это не относится к Вашей проблеме сейчас, но если уж это ветка для начинающих, надо приучаться к определенному стилю проектирования. Я бы немного по другому упорядочил операторы: CODE ISR(INT0_vect){TCNT1=65500;} ISR(TIMER1_OVF_vect){TCNT1=65500; PORTB^=1<<3;}
main() { //конфигурация тактового импульса CLKPR = 0x80; //разрешаем запись делителя CLKPR = 0x08; //делитель 256 //по-хорошему, здесь надо подождать T1+T2 для смены частоты
//конфигурация портов PORTB=0x00; DDRB=0x08; PORTD=0x00; DDRD=0x00;
//конфигурация таймера 1 TCCR1B=0x00; //отключить таймер TCNT1=65500; //начальное значение для делителя TCCR1A=0x00; //Normal mode TCCR1B=0x05; //деление на 1024 TIFR=0x80; //сбрасываем флаг прерывания Timer 1 Overflow TIMSK=0x80; //разрешаем прерывание Timer 1 Overflow
//прерывания от кнопок MCUCR=0x03; //прерывание от Int0 по фронту EIFR=0x40; //сбрасываем флаг прерывания Int0 GIMSK=0x40; //разрешаем прерывание от Int0
//разрешаем прерывания asm("sei");
while(1); }
Но, вообще, я бы сделал: 1) Опрос кнопки по 0 (снаружи подтягивающий резистор, или, задействовать встроенный Pullup на ножке). 2) Детектировать встроенным модулем Capture
|
|
|
|
|
Aug 11 2009, 17:04
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
схема совсем простетская - проверять нечего - диод на ноге да кнопка
по оформлению - красиво! сейчас переделаю
по Capture - это тоже не принципиальное наверно изменение
|
|
|
|
|
Aug 11 2009, 20:35
|
Местный
  
Группа: Свой
Сообщений: 351
Регистрация: 17-09-05
Из: Москва
Пользователь №: 8 660

|
Цитата(семен78 @ Aug 11 2009, 21:04)  схема совсем простетская - проверять нечего - диод на ноге да кнопка Надеюсь, диод с резистором последовательно? Это шутка, но вот как это - кнопка на ноге? А когда кнопка не нажата, что обеспечивает уровень на ножке? Либо заводите кнопку на 0 и включайте подтягивающий резистор, либо это непонятно что. Цитата(_Pasha @ Aug 11 2009, 22:12)  А это уже совсем наворот. Разве только - в целях обучения/работы над собой поизвращаться...  Не знаю, по-моему красиво и ресурсы не использует, и не так уж сложно - просто будет два обработчика от одного таймера - один capture, другой overflow. К тому же автор темы уже настолько заделил system clock, что noise canceler еще и дребезг подавит.
|
|
|
|
|
Aug 11 2009, 21:04
|
Группа: Участник
Сообщений: 8
Регистрация: 10-08-09
Пользователь №: 51 829

|
вопрос снят причина - отсутствие внешней подтяжки к земле Цитата Не знаю, по-моему красиво и ресурсы не использует, и не так уж сложно - просто будет два обработчика от одного таймера - один capture, другой overflow. К тому же автор темы уже настолько заделил system clock, что noise canceler еще и дребезг подавит. мысль интеренсая - буду пробовать
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|