Страница 1 из 2

Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 09:48:04
Дем
Добрый день.

Начинаю осваивать МК.

Но что то не пошло с прерываниями. С таймером разобрался, начал разбираться с внешними прерываниями, но идет затыкаю Вот код.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
unsigned int k,hour, set_hout, delta, i;
ISR(TIMER0_OVF_vect)
{
k=k+1;
if (k>=900)
{
hour=hour+delta;
k=0;
}
}
ISR(INT0_vect)
{
cli();
_delay_ms(100);
set_hour=set_hour+delta;
i=i+1;
if (i==5)
{
i=0;
set_hour=delta;
}
switch (i)
{
case 0 : PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));
case 1 : PORTB |= (1 << 0); break;
case 2 : PORTB |= (1 << 2); break;
case 3 : PORTB |= (1 << 3); break;
case 4 : PORTB |= (1 << 4); break;
default : PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));
}
sei();
}

int main(void)

{
k=0;
hour=0;
delta=30;
set_hour=delta;
i=0;
DDRB=0; // все ножки на вход
DDRB |= (1 << 0)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5); //1,2,3,4,5 на выход
PORTB |= (1 << 5); //5 =1
PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));//1,2,3,4 = 0
PORTB |= (1 << 1); //0 вывод вход по умолчани

GIMSK|=(1<<INT0);//Включаем внешние прерывание

MCUCR|=(0<<ISC00)|(1<<ISC01); //Настраиваем прерывание на срабатывание по спадающему фронт

TCCR0A=0; //счетчик счетает в режиме нормаль
TCCR0B|= (0<<CS02)|(0<<CS01)|(1<<CS00); //001 без деления 101 -1024, 100-256
TCNT0 = 0; //обнулние счетчика
TIMSK0 |= (1<<TOIE0); //разрешение прерывания по переполнению
sei(); // разрешаем глобальное прерывание

while (1)
{

if (set_hour==hour)
PORTB &= ~((1 << 5));

}
}



Работать должен так: нажимаем кнопку 5-вывод отключается через delta-время, еще раз нажимаем, delt+delta и т.д. до 4 раз. Так же при нажатии загораются светодиоды. Но при отладке вылетает из цикла и начинает работать с int main(void). Думаю какой то конфликт прерываний, хотя в отладке пока ничего не нажимаю.

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 10:55:45
metan
Ничего не понятно.
Дем писал(а):Но при отладке вылетает из цикла и начинает работать с int main(void)
Из какого цикла вылетает? У вас в программе я кроме бесконечного цикла в майн других циклов не нашел.
По коду.
1. cll sei в подпрограмме обработки прерывания не нужны, это сделает сам чип.
2. Задержки в обработчиках прерываний - зло, их следует избегать.
3. Все проверки и действия, критически не завязанные на быстродействие, желательно выносить из обработчика в главный цикл. А в самом обработчике оставлять только максимально необходимый код, такой как например, установка флагов, которые можно проверить и в главном цикле.
4. Что касается обработки нажатий кнопок, то на этом сайте есть специальная тема, там есть примеры качественно разработанных программ для этой истории.

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 11:00:07
Дем
Спасибо за ответ.
Последую Вашим рекомендациям.
Но у меня при отладке программа курсор отладки самопроизвольно выходит из бесконечного цикла и начинает работать с начала программы

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 15:34:07
Z_h_e
Для кода есть специальные тэги и желательно тот же код заключить в тэги спойлера. А то нечитабельно и длинно. Исправте, если правка еще возможна.

Ватчдог выключен во фьюзах? Если включен, то это бы все объясняло.

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 19:23:55
Дем
Вачдок не включен. Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 19:55:22
Alkul
Дем писал(а):Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.
Мне кажется, я знаю, что у Вас не так.
Вы не инициализировали указатель стека SPL.
В ассемблере это делается в самом начале программы командами

Код: Выделить всё

ldi R16,RAMEND
out SPL,R16
Да, я знаю, что регистр SPL у ATtiny2313 инициализируется значением RAMEND по умолчанию. Но AVR Studio об этом, похоже, не знает. Во-всяком случае в моих проектах на асм, если вышеуказаные строки не включить в код, программа при отладке рестартует при первом же возврате из подпрограммы, когда адрес возврата снимается из стека с неинициализированным указателем вершины (а обработчик прерывания это тоже подпрограмма).

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 20:37:58
ARV
Alkul писал(а):Вы не инициализировали указатель стека SPL.
это же Си! компилятор всегда делает необходимый пролог, где все и инициализирует!

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 20:48:13
Mishany
Как настроена опоимизация?

Re: Конфликт прерываний на тиньке 13

Добавлено: Чт июн 30, 2016 21:48:19
COKPOWEHEU
Дем писал(а): TCNT0 = 0; //обнулние счетчика
TIMSK0 |= (1<<TOIE0); //разрешение прерывания по переполнению
Дем писал(а):Вачдок не включен. Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.
Поскольку у ATtiny2313 нет регистра TIMSK0, очевидно, вы собираете прошивку для другого камня. Но если так, при чем здесь ATtiny2313? Перепроверьте настройки компилятора и симулятора. Само поведение похоже на вызов неизвестного прерывания.

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 05:00:29
Дем
Поскольку заподозрил что дело не совсем в проге, то перевел ееи настройки с тиньки13 на тиньку 2313. Так то я думал что у них регистры одинаково называются.

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 06:08:04
Z_h_e
У Вас не определена тактовая частота процессора. Установите нечто такое вначале программы.

Код: Выделить всё

#define F_CPU 8000000UL
Переменная объявлена с ошибкой, как вообще проект запускался? Если быть точнее, объявлена одна, в коде другая.
set_hout

И самое главное, поставте правильный вектор прерывания

Код: Выделить всё

ISR(TIM0_OVF_vect)

Смотреть надо не только на ошибки при компиляции, но и на предупреждения.

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 07:38:53
COKPOWEHEU
Z_h_e писал(а):У Вас не определена тактовая частота процессора. Установите нечто такое вначале программы.

Код: Выделить всё

#define F_CPU 8000000UL
Частоту лучше указывать в настройках проекта, а не в исходном коде. Если будете собирать прошивку из нескольких файлов, придется внимательно следить чтобы частоты во совпадали во всех. Неужели в последних версиях студии нельзя задать командную строку компилятора? Добавить надо всего лишь -DF_CPU=8000000
Z_h_e писал(а): Смотреть надо не только на ошибки при компиляции, но и на предупреждения.
Вот предупреждения надо исправлять всегда, разве что 100% уверены что делаете правильно, а для удовлетворения компилятора пришлось бы уж слишком извращаться.

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 20:02:33
Дем
Ну что же в AVR заработало. Поставил TIME0. Но ни в железе ни в протеусе не работает. Други работают на тиньке 231тиньке. Но на тиньке 13 нехочет. Незнаю что делать

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 20:40:01
Z_h_e
Попробуйте добавить все-таки определение F_CPU и обязательно перед #include <util/delay.h>.

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 22:16:15
Дем
Z_h_e писал(а):Попробуйте добавить все-таки определение F_CPU и обязательно перед #include <util/delay.h>.
Добавил. Ничего. Везде проверил. Кстати почему то не работает делитель таймера, работает только cs00=1

Re: Конфликт прерываний на тиньке 13

Добавлено: Пт июл 01, 2016 22:55:58
COKPOWEHEU
Выложите оба проекта полностью - для ATtiny2313 и ATtiny13.

Re: Конфликт прерываний на тиньке 13

Добавлено: Вс июл 03, 2016 08:49:20
Дем
переделал код под Аттини13

Код: Выделить всё

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> 

unsigned int k,hour, set_hour, delta, i;

ISR(TIM0_OVF_vect)
{
	k=k+1;
	if (k>=900) 
		{
			hour=hour+delta;
			k=0;
		}
}




int main(void)
{
	k=0;
	hour=0;
	delta=30;
	set_hour=delta;
	i=0;

	DDRB=0;                                      // все ножки на вход
	DDRB |= (1 << 0)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5);	//1,2,3,4,5 на выход			
	PORTB |= (1 << 5);			//5 =1
	PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));//1,2,3,4 = 0
	PORTB |= (1 << 1);			//0 вывод вход по умолчанию 1


	TCCR0A=0;				//счетчик счетает в режиме нормаль
	TCCR0B|= (0<<CS02)|(0<<CS01)|(1<<CS00);	//001 без деления 101 -1024, 100-256
	TCNT0 = 0;				//обнулние счетчика
	TIMSK0 |= (1<<TOIE0);  			//разрешение прерывания по переполнению

	sei();   				// разрешаем глобальное прерывание

	while (1)
	{
		if (!(PORTB & (1<<PB1)))	
			{
				_delay_ms(50);
				if (!(PORTB & (1<<PB1)))
				{
					i++;
					set_hour=set_hour+delta;
				}
			}
		if (i==5)
			{
				i=0;
				set_hour=delta;	
				
			}

		if (i==0)
			PORTB &= ~((1 << 0)|(1 << 2)|(1 << 3)|(1 << 4));
		if (i==1)			
			PORTB |= (1 << 0);
		if (i==2)      			
			PORTB |= (1 << 2);
		if (i==3)
			PORTB |= (1 << 3);
		if (i==4)
			PORTB |= (1 << 4);
		if (set_hour==hour)
			PORTB &= ~((1 << 5));
	}
}
но дело в том что просто даже это не работает:

Код: Выделить всё

#define F_CPU 4800000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
	DDRB=0x00;     	// порт B на выход
	PORTB=0xFF;     // все входы на порте B=0
	DDRD =0xFF;
	PORTD=0xFF;  
		
    while(1)
    {
					
			if (PORTD & (1 << PD1))
				{
					PORTB |= (1 << PB1);
				//	_delay_ms(5000);
				}
				else 
				{
						PORTB &=~ (1 << PB1);
				}						
			if (!(PORTD & (1 << PD1)))
				{
					PORTB &=~ (1 << PB1);
				//	_delay_ms(5000);
				}
	
    }
}
Вернее в AVR6 работает а в протеусе нет.
Может какие настойки нужны

Re: Конфликт прерываний на тиньке 13

Добавлено: Вс июл 03, 2016 08:52:50
Дем
последний код для 2313 (что-то пердыдущее сообщение не корректируется)

Re: Конфликт прерываний на тиньке 13

Добавлено: Вс июл 03, 2016 09:30:03
Z_h_e
Протеус много сообщений выдает при симуляции. Поглядите там. Например могут быть сообщений типа "рестарт из-за.."

Re: Конфликт прерываний на тиньке 13

Добавлено: Вс июл 03, 2016 09:35:35
Z_h_e
Кстати. А как код для 2313 должен работать? Вы же значения порта D нигде не меняете. А если имелось ввиду внешнии кнопки, то проверяйте регистр PIND, а не PORTD.