реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> winavr - помогите с прерываниями, не хотят совместно работать в простой программе
семен78
сообщение Aug 10 2009, 20:20
Сообщение #1





Группа: Участник
Сообщений: 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 раз сколько бы не нажимать - после очередной сработки по таймеру опять только раз - а надо чтоб постоянно - в чем причина не пойму
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 10 2009, 21:08
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(семен78 @ Aug 10 2009, 23:20) *
в чем причина не пойму

volatile int c;
Go to the top of the page
 
+Quote Post
Sergey'F
сообщение Aug 10 2009, 21:10
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 351
Регистрация: 17-09-05
Из: Москва
Пользователь №: 8 660



Я не работал с тинькой, но чему равен DDRD, если он там есть? Кнопка замыкает на 1? Зачем выводить 0 в порт, если там кнопка? Переменную c по хорошему надо инициализировать в основной программе и объявить как volatile.

P.S. Минимализм описания в данном случае во вред. Как и использование вперемешку разных способов задания масок. Почитайте MISRA guidelines. В IAR они есть.
Go to the top of the page
 
+Quote Post
семен78
сообщение Aug 11 2009, 07:12
Сообщение #4





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



дописал volatile int c=0;
эффета нет

DDRD есть и по умолчанию там 0 - т.е. вход ( а когда писал туда 0 то почемуто не работала)
кнопка на 1 замыкает - да . 0 там чтоб четче по переднему фронту отрабатывало так как без нуля там около 1В.

инициализация в основной программе это после main? тогда ругаться будет что в описании прерываний непонятки

это как понимаю плата за неохоту изучать ассемблер?
Go to the top of the page
 
+Quote Post
Кастусь Рыжов
сообщение Aug 11 2009, 10:25
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 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);//настроить на вход если так нужно


--------------------
Прибор должен работать не в принципе, а в корпусе!
Go to the top of the page
 
+Quote Post
семен78
сообщение Aug 11 2009, 10:58
Сообщение #6





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



DDRD(2) - вход по умолчанию - т.е. там 0
и кста в шите написано что сработает даже по выходу (int0) - тут вопроса нет - кнопка же срабатывает
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 11 2009, 11:24
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Наконец-то вчитался в постановку задачи. Обнаружил, что надо ведь порт тоже обнулять. Иначе - так и есть - кнопкой продлеваете период мигания СД.
Код
ISR(TIMER1_OVF_vect)
{TCNT1=65500;if (c==1){c=0;PORTB &= ~(1<<3);} else {PORTB^=1<<3;}}
Go to the top of the page
 
+Quote Post
семен78
сообщение Aug 11 2009, 11:57
Сообщение #8





Группа: Участник
Сообщений: 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);
}
Go to the top of the page
 
+Quote Post
Sergey'F
сообщение Aug 11 2009, 13:23
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
семен78
сообщение Aug 11 2009, 14:09
Сообщение #10





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



то есть, нажатия кнопки будут продлевать до бесконечности как выключенное, так и включенное состояние выхода.
вот именно этого я и добиваюсь

1В на входе - видимо это третье состояние такое(высоко импедансное) - формально по умолчанию 0 - а когда туда пишешь 0 то 0.15В показывает

про между ресет и main не понял
Go to the top of the page
 
+Quote Post
Sergey'F
сообщение Aug 11 2009, 16:35
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
семен78
сообщение Aug 11 2009, 17:04
Сообщение #12





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



схема совсем простетская - проверять нечего - диод на ноге да кнопка

по оформлению - красиво!
сейчас переделаю

по Capture - это тоже не принципиальное наверно изменение
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 11 2009, 18:12
Сообщение #13


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Sergey'F @ Aug 11 2009, 19:35) *
2) Детектировать встроенным модулем Capture

А это уже совсем наворот. Разве только - в целях обучения/работы над собой поизвращаться...
Go to the top of the page
 
+Quote Post
Sergey'F
сообщение Aug 11 2009, 20:35
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 351
Регистрация: 17-09-05
Из: Москва
Пользователь №: 8 660



Цитата(семен78 @ Aug 11 2009, 21:04) *
схема совсем простетская - проверять нечего - диод на ноге да кнопка

Надеюсь, диод с резистором последовательно? Это шутка, но вот как это - кнопка на ноге? А когда кнопка не нажата, что обеспечивает уровень на ножке? Либо заводите кнопку на 0 и включайте подтягивающий резистор, либо это непонятно что.

Цитата(_Pasha @ Aug 11 2009, 22:12) *
А это уже совсем наворот. Разве только - в целях обучения/работы над собой поизвращаться...

laughing.gif Не знаю, по-моему красиво и ресурсы не использует, и не так уж сложно - просто будет два обработчика от одного таймера - один capture, другой overflow. К тому же автор темы уже настолько заделил system clock, что noise canceler еще и дребезг подавит.
Go to the top of the page
 
+Quote Post
семен78
сообщение Aug 11 2009, 21:04
Сообщение #15





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



вопрос снят
причина - отсутствие внешней подтяжки к земле

Цитата
Не знаю, по-моему красиво и ресурсы не использует, и не так уж сложно - просто будет два обработчика от одного таймера - один capture, другой overflow. К тому же автор темы уже настолько заделил system clock, что noise canceler еще и дребезг подавит.


мысль интеренсая - буду пробовать
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 00:01
Рейтинг@Mail.ru


Страница сгенерированна за 0.01503 секунд с 7
ELECTRONIX ©2004-2016