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

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср апр 06, 2016 09:00:21

Сообщение Дем »

Добрый день.

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

Но что то не пошло с прерываниями. С таймером разобрался, начал разбираться с внешними прерываниями, но идет затыкаю Вот код.
#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). Думаю какой то конфликт прерываний, хотя в отладке пока ничего не нажимаю.
Последний раз редактировалось Дем Чт июн 30, 2016 19:19:55, всего редактировалось 1 раз.
Реклама
Вымогатель припоя
Сообщения: 597
Зарегистрирован: Ср янв 06, 2010 10:01:46

Сообщение metan »

Ничего не понятно.
Дем писал(а):Но при отладке вылетает из цикла и начинает работать с int main(void)
Из какого цикла вылетает? У вас в программе я кроме бесконечного цикла в майн других циклов не нашел.
По коду.
1. cll sei в подпрограмме обработки прерывания не нужны, это сделает сам чип.
2. Задержки в обработчиках прерываний - зло, их следует избегать.
3. Все проверки и действия, критически не завязанные на быстродействие, желательно выносить из обработчика в главный цикл. А в самом обработчике оставлять только максимально необходимый код, такой как например, установка флагов, которые можно проверить и в главном цикле.
4. Что касается обработки нажатий кнопок, то на этом сайте есть специальная тема, там есть примеры качественно разработанных программ для этой истории.
Реклама
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср апр 06, 2016 09:00:21

Сообщение Дем »

Спасибо за ответ.
Последую Вашим рекомендациям.
Но у меня при отладке программа курсор отладки самопроизвольно выходит из бесконечного цикла и начинает работать с начала программы
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

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

Ватчдог выключен во фьюзах? Если включен, то это бы все объясняло.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср апр 06, 2016 09:00:21

Сообщение Дем »

Вачдок не включен. Мне кажется что то не то с avr studio так ка прога работает на тиньке 2313 . Бред какой то.
Реклама
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

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

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

ldi R16,RAMEND
out SPL,R16
Да, я знаю, что регистр SPL у ATtiny2313 инициализируется значением RAMEND по умолчанию. Но AVR Studio об этом, похоже, не знает. Во-всяком случае в моих проектах на асм, если вышеуказаные строки не включить в код, программа при отладке рестартует при первом же возврате из подпрограммы, когда адрес возврата снимается из стека с неинициализированным указателем вершины (а обработчик прерывания это тоже подпрограмма).
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Alkul писал(а):Вы не инициализировали указатель стека SPL.
это же Си! компилятор всегда делает необходимый пролог, где все и инициализирует!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Электрический кот
Аватара пользователя
Сообщения: 1031
Зарегистрирован: Чт июн 20, 2013 00:00:58
Откуда: москва, м.Сходненская

Сообщение Mishany »

Как настроена опоимизация?
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

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

Сообщение Дем »

Поскольку заподозрил что дело не совсем в проге, то перевел ееи настройки с тиньки13 на тиньку 2313. Так то я думал что у них регистры одинаково называются.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

У Вас не определена тактовая частота процессора. Установите нечто такое вначале программы.

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

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

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

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

ISR(TIM0_OVF_vect)

Смотреть надо не только на ошибки при компиляции, но и на предупреждения.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Z_h_e писал(а):У Вас не определена тактовая частота процессора. Установите нечто такое вначале программы.

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

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

Сообщение Дем »

Ну что же в AVR заработало. Поставил TIME0. Но ни в железе ни в протеусе не работает. Други работают на тиньке 231тиньке. Но на тиньке 13 нехочет. Незнаю что делать
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Попробуйте добавить все-таки определение F_CPU и обязательно перед #include <util/delay.h>.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср апр 06, 2016 09:00:21

Сообщение Дем »

Z_h_e писал(а):Попробуйте добавить все-таки определение F_CPU и обязательно перед #include <util/delay.h>.
Добавил. Ничего. Везде проверил. Кстати почему то не работает делитель таймера, работает только cs00=1
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Выложите оба проекта полностью - для ATtiny2313 и ATtiny13.
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср апр 06, 2016 09:00:21

Сообщение Дем »

переделал код под Аттини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 работает а в протеусе нет.
Может какие настойки нужны
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Ср апр 06, 2016 09:00:21

Сообщение Дем »

последний код для 2313 (что-то пердыдущее сообщение не корректируется)
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Протеус много сообщений выдает при симуляции. Поглядите там. Например могут быть сообщений типа "рестарт из-за.."
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Кстати. А как код для 2313 должен работать? Вы же значения порта D нигде не меняете. А если имелось ввиду внешнии кнопки, то проверяйте регистр PIND, а не PORTD.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Ответить

Вернуться в «AVR»