Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прерывание на си
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Araxnid
МК - ATmega16.
До этого работал с ассемблером и все было очень понятно и ясно, вот сейчас начал С осваивать, написал обычную программу привет светодиод..
На PC2 повешен светодиод, на INT0 кнопка ( при нажатии "0", если отпущена то "1")
Настроил прерывание по INT0, если зафиксирован уровень "0", то светодиод должен погаснуть\засветится.
Вот код
CODE
#define F_CPU 6000000UL // 6 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

SIGNAL(INT0_vect)
{
PORTC ^= (1<<PC2);
}

int main(void)
{
int i=0;
TCCR0 = 1<<CS02|1<<CS00;
TIMSK = 1<<TOIE0;
DDRC = 1<<DDC2;
PORTC = 1<<PC2;
GICR = 1<<INT0;
sei();
while(1)
{
i++;
i++;
i--;
i--;
}
}


Проверяю в протеусе, если без прерываний, то светодиод горит, если с прерываниями то, тоже горит, но на нажатие кнопки не реагирует.
TCCR0 и TIMSK - это я с таймером экспериментировал, но там тоже ничего не вышло..
GICR - регистр для разрешение прерываний по INT0.

+ вопрос в догонку, а как здесь счетчики, которые и в главной функции работают, и в прерывании можно проверить..я так понимаю, через глобальные переменные только?

Ах да, если это важно, то компилирую в Avr studio v.5
Палыч
Даже если считать, что кнопка не имеет дребезга контактов, то, хорошо бы, условие прерывания настроить не на уровень (как сейчас), а на перепад из высокого в низкий уровень (см. регистр MCUCR)
Xenia
Цитата(Araxnid @ Jan 28 2012, 15:30) *
До этого работал с ассемблером и все было очень понятно и ясно, вот сейчас начал С осваивать, написал обычную программу привет светодиод..
Проверяю в протеусе, если без прерываний, то светодиод горит, если с прерываниями то, тоже горит, но на нажатие кнопки не реагирует.

А вы попросите компилятор сгенерировать ассемблерный листинг, а потом проверьте по листингу, так оно или не так, раз уж вы ассемблер уже знаете. Когда уже знаешь ассемблер, изучать С просто, куда труднее в обратную сторону - привычка к С расхолаживает.
_Pasha
И по шагам пройдитесь, а то неясно, чего Вам неясно. Протеус тоже.. расхолаживает.
Araxnid
Да, менял уже уровень сигнала для вызова прерывания, и по спаду, и по фронту ставил, ничего..

В авр студио прошагал, все отлично, если флаг прерывания выставляется (в ручную), то и прерывание вызывается..

В протеусе прерывание не вызывается, нажимаю я кнопку, отпускаю - ничего. И "зажимать" пробовал.
Дребезга нет, посмотрел на осциллографе.
Протеу,с по крайнее мере, главный цикл и инициализацию точно правильно прошагивает.
_Pasha
Ну я не знаю.. скиньте проект, в последнем протезе можно проверить...
Зы левом.
RabidRabbit
А по-моему зря прерывание от таймера включено, оно ведь каждый раз при сработке таймера будет программу перезапускать...
Вот слегка подпиленный код, с антидребезгом (как я его себе представляю sm.gif )
CODE

#define F_CPU 6000000UL // 6 MHz
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

volatile int i=0;

SIGNAL(INT0_vect)
{
GICR = (0 << INT0);
PORTC ^= (1<<PC2);
i = 30000;
}

int main(void)
{
//TCCR0 = 1<<CS02|1<<CS00;
//TIMSK = 1<<TOIE0;
DDRC = 1<<DDC2;
PORTC = 1<<PC2;
DDRD = (0 << DDD2);
PORTD = (1 << PORTD2);
GICR = 1<<INT0;
sei();

while(1)
{
//
if ( PIND & (1 << PIND2) )
{
//
if ( i )
{
//
if ( ! (--i) )
{
//
GICR = (1 << INT0);
}
}
}
}
}

Araxnid
2RabidRabbit
О! Ваш код заработал!
Только зачем здесь вот этот кусок:
CODE
if ( i )
{
//
if ( ! (--i) )

Палыч
Цитата(Araxnid @ Jan 30 2012, 12:27) *
Только зачем здесь вот этот кусок

Подавление дребезга контактов кнопки. При возникновении прерывания при нажатии кнопки, они (прерывания от кнопки) будут запрещены, до тех пор, пока МК не "открутит" до нуля вычитанием переменную i (пропуская таким образом время дребезга контактов), установленную в некоторое значение (в данном случае 30000) в процедуре прерывания от кнопки.

Цитата(Araxnid @ Jan 30 2012, 12:27) *
О! Ваш код заработал!

Ваш код тоже - худо-бедно но заработал бы, если бы Вы удалили из него разрешения прерывания от таймера (выше Вам это подсказывали).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.